#排序 #no-std

no-std entwine

用于同时操作多个切片的泛型类似切片接口

1 个不稳定版本

0.1.0 2021年11月25日

#2279 in Rust模式

MIT/Apache

87KB
1.5K SLoC

entwine

此crate提供了Entwine trait,它提供了一个类似切片的泛型接口,允许同时操作多个切片。

请注意,这是一个实验,目前没有证据表明它在性能上优于更直观的方法。除非你必须原地执行操作,否则可能不是使用它的好主意。

示例

一次排序多个切片

use entwine::Entwine;

let mut a = [6, -3, 2, 7, 0, -42];
let mut b = [1, 2, 3, 4, 5];
let mut c = ["a", "b", "c", "d", "e", "f", "g", "h"];

// Sort all three slices at once by comparing the elements in the first.
//
// `Entwine` handles slices of different lengths by exposing only the range
// shared by all input slices.
(&mut a[..], &mut b[..], &mut c[..])
    .sort_unstable_by(|(l, _, _), (r, _, _)| l.cmp(r));

// Elements in `b` and `c` are sorted along with elements in `a`.
assert_eq!([-3, 0, 2, 6, 7, -42], a);
assert_eq!([2, 5, 3, 1, 4], b);
assert_eq!(["b", "e", "c", "a", "d", "f", "g", "h"], c);

在排序过程中跟踪元素的索引

use entwine::Entwine;
use entwine::index::TrackIndex;

let mut xs = [5, 7, -2, 4, 9, 0, 3];

// This creates an imaginary slice tracking the index of "9", that can be
// entwined with real ones.
let mut idx = TrackIndex::new(4, xs.len());

(&mut xs[..], &mut idx).sort_unstable_by(|(l, _), (r, _)| l.cmp(r));

// "9" is now moved to the last place
assert_eq!([-2, 0, 3, 4, 5, 7, 9], xs);
assert_eq!(Some(6), idx.get());

性能

遗憾的是,当处理原始的Copy类型时,性能大约是分配临时向量的直观方法的0.5倍,即使在LTO的情况下。事后看来,这是有道理的,因为当多个指针打包在一起时,指针会变得很大,难以处理。

对于非Copy或甚至非Clone类型,当需要在原地执行操作时,情况可能会有所不同。分配索引向量,排序,然后根据索引交换元素可能不如原始数据优化得那么好,但目前的任何结论都尚未确定。

可以使用cargo bench --features=nightly运行基准测试。

特性标志

  • nightly - 在crate顶部添加feature(generic_associated_types),这将允许crate在nightly编译器上编译。从2021年11月起必需。
  • std - 默认启用。启用需要完整标准库的功能。目前不执行任何操作。

许可

Apache 2.0和MIT条款双重许可。

此crate包含大量来自Rust标准库的代码。有关完整的作者信息,请参阅https://github.com/rust-lang/rusthttps://thanks.rust-lang.org的版本控制历史。

依赖关系