#lazy-evaluation #iterator #parallel-iterator #parallel #data #data-transformation

lazy_transducer

懒、并行、可索引、泛型数据迭代器

5个版本

0.2.1 2020年2月26日
0.2.0 2020年2月26日
0.1.2 2019年10月21日
0.1.1 2018年1月1日
0.1.0 2018年1月1日

#2066 in Rust模式

MIT许可证

24KB
312

Lazy Transducer 构建状态

懒转换器是通用的、懒的、并行的、可索引的迭代器,将一个数据源转换为n个输出数据类型。

有关更多信息,请参阅在线文档

使用

将此添加到您的Cargo.toml

[dependencies]
lazy_transducer = "0.1"

示例

extern crate lazy_transducer;
extern crate rayon;

use rayon::prelude::*;
use lazy_transducer::LazyTransducer;

fn main() {
  let data = [0xdeadbeefu32, 0xcafed00d];
  let lt: LazyTransducer<&[u32], u64> = LazyTransducer::new(&data, 2, |input, idx| input[idx] as u64);

  let cafedood = lt.get(1).expect("has 2 elements");
  assert_eq!(cafedood, 0xcafed00d);

  lt.into_par_iter().for_each(|elem| {
    println!("{}", elem);
  });
}

lib.rs:

简介

懒转换器是将一种类型的数据转换为另一种类型的声明性规范。

转换器被称为转换器,它接收原始源输入以及与第i个元素相对应的索引,并返回该源中的相应第i个元素。

重要的是,懒转换器是

  1. 懒的 - 除非您要求它这样做,否则它永远不会解析任何元素
  2. 可迭代的 - 可以遍历每个元素
  3. 可索引的 - 访问元素的时间复杂度为O(1)
  4. 并行的 - 可以并行遍历每个元素

在构建懒转换器时,重要的是要记住转换器必须是一个签名为fn(Input, usize -> Output)的函数;也可以使用不捕获其环境的闭包。

输入源需要是可复制的;即,它通常应该是Vec<_>的引用,或字节数组的切片等。

您还应该记住的一个细节是,索引是第i个元素;因此,如果您的后备数据源是字节,您需要知道您从字节数组中解析出的数据结构的固定长度。这取决于转换器实现来决定。

在某些情况下,数据结构/输出元素的大小无法通过sizeof等静态确定。在这种情况下,建议在构建过程中将此“上下文”作为元组传递到输入源中,例如:(datasource, context),并让您的转换器使用datasource + context + 索引来正确地将数据结构从字节中序列化。

这是基于滚动转换器的做法。还可以参考bincode示例,了解类似的方法。

并行实现使用rayon

示例

extern crate lazy_transducer;
extern crate rayon;

use rayon::prelude::*;
use lazy_transducer::LazyTransducer;

use std::mem::size_of;
use std::mem::transmute;

let bytes: Vec<u8> = vec![1u8, 0, 2, 0, 3, 0, 4, 0];
let lt: LazyTransducer<_, &u16> = LazyTransducer::new(&bytes, 4, |input, index| {
    let start = size_of::<u16>() * index;
    unsafe { transmute::<_, &u16>(&input[start]) }
});

// now iterate in parallel
lt.into_par_iter().for_each(|n| {
  // do stuff
  println!("{}", n);
});

依赖项

~1.5–2.1MB
~45K SLoC