5个不稳定版本
0.3.1 | 2023年9月30日 |
---|---|
0.3.0 | 2023年8月30日 |
0.2.1 | 2023年5月28日 |
0.2.0 | 2023年5月28日 |
0.1.0 | 2022年9月24日 |
在算法中排名第279
每月下载量23次
80KB
2K SLoC
extsort-iter

只要数据能适应您的磁盘,就能对任何类型的迭代器进行排序!
extsort-iter
是一个库,允许您对外部排序任何迭代器,无需进行序列化步骤。
从概念上讲,我们正在使用缓冲区接收您的输入迭代器,对运行进行排序,在将数据流回之前将其移动到磁盘。
为什么使用这个crate?
因为我们提供了一个非常出色的高级API,并且在没有任何(反)序列化开销的情况下执行排序。
用法
let data = [1,42,3,41,5];
// lets pretend this is an iterator that will not fit in memory completely
let source = data.into_iter();
let config = ExtsortConfig::default();
let iterator = data.external_sort(config);
// do whatever you want with the sorted iterator
for item in iterator {
println!("{}", item);
}
// alternatively you can provide a comparison function
// (here one that sorts 42 to the beginning because it is the best number)
let iterator = data.external_sort_by(config, |a,b| if a == 42 {
Ordering::Less
}else {
a.cmp(b)
});
// or you can provide a key extraction function to sort by
// (here we are sorting by the number of trailing ones)
let iterator = data.external_sort_by_key(config, |a| a.trailing_ones());
// if you can spare the memory, you should increase the size of the in-memory sort buffer.
// it defaults to 10MB.
// larger buffer sizes will drastically improve your sort performance, because only the
// in-memory sort part is parallelized and the IO becomes more sequential
let config = ExtsortConfig::with_buffer_size(1_073_741_824);
如果您启用了parallel_sort
功能,所有排序函数的并行版本都将可用,这些并行版本将使用rayon并行排序运行缓冲区
// normal sort by the ord impl
let iterator = data.par_external_sort(config);
// sort using a comparison function
let iterator = data.par_external_sort_by(config, |a,b| if a == 42 {
Ordering::Less
}else {
a.cmp(b)
});
// parallel sort using key extraction function
let iterator = data.par_external_sort_by_key(config, |a| a.trailing_ones());
如果您启用了compress_lz4_flex功能,您可以在I/O目的上启用数据的透明压缩
let config = ExtsortConfig::default().compress_lz4_flex();
// and then just sort as normal
let iterator = data.par_external_sort(config);
何时不使用这个crate
当您的源迭代器很大时,因为每个项目都拥有大量堆内存。这意味着以下情况会导致内存耗尽
let data = "somestring".to_owned();
let iterator = std::iter::from_fn(|| Some(data.clone())).take(1_000_000);
let sorted = iterator.external_sort(ExtsortConfig::default_for::<String>());
原因是我们在结果迭代器产出之前不会丢弃源迭代器的值。
您可以将它视为缓冲整个输入迭代器,其中值本身位于磁盘上,但所有指向值的内存仍位于堆上。
不安全的使用
此crate使用不安全代码将运行缓冲区视为字节数组以将其复制到磁盘,并将数据从磁盘读回到内存中,然后再次将其作为我们的值处理。
所有不安全的代码都限制在 file_run 模块中,文档编写得相当好,并且经过测试,使用 miri 运行测试套件通过,所以我们尽可能地确保代码的正确性和稳定性。
依赖项
~0–310KB