#contiguous-memory #heterogeneous #vec #any #element #vector

hvec

一种类似 Vec 的结构,可以在内存中连续存储不同类型和不同大小的数据

4 个版本 (破坏性更新)

0.4.0 2024年3月1日
0.3.0 2023年7月22日
0.2.0 2022年7月5日
0.1.0 2021年12月7日

#245 in 数据结构

CC0 许可证

51KB
752

hvec

Crates.io Docs.rs

纪念Anna Harren,她提出了“turbofish”一词——如果您使用此crate,您会经常看到。

此crate的主要目的是HarrenVec类型——一种类似Vec的数据结构,可以存储来自不同类型和大小的事项。

用法

use hvec::hvec;

// Make a list that can contain any type
let list = hvec![
    1_usize,
    2_usize,
    999_usize,
    "Wow, big number!".to_string(),
    3_usize,
];

// Make an iterator (unfortunately can't use `for` loops)
let mut iter = list.into_iter();

// Use `next` with the turbofish to step through elements of different types
let mut total = 0;
while let Some(number) = iter.next::<usize>() {
    if number > 100 {
        let comment = iter.next::<String>().unwrap();
        println!("{}", comment); // Wow, big number!
    }
    total += number;
}
assert_eq!(total, 1005);

迭代基准测试

此仓库中的sum_with_optionals基准测试测量遍历包含大量数据的集合所需的时间,其中较大数据块稀疏地分布在同一集合中。

这可以通过三种方式实现:

  1. 在 Option 中包含较大数据(因此每个结构都很大,但更缓存友好)
  2. 在 Box 中包含较大数据(因此它存储在堆上,而正在迭代的结构保持较小)
  3. 在同一HVec中包含较大和较小的结构(因此没有间接引用和最小的存储开销)

数据类型

// 128 bytes
struct Extra {
    array: [f32; 32],
}

// 136 bytes (including the tag for the Option enum)
struct BigStruct {
    number: f32,
    extra: Option<Extra>,
}

// 12 bytes on the stack (plus 128 on the heap)
struct BoxStruct {
    number: f32,
    extra: Option<Box<Extra>>,
}

// 8 bytes, bool indicates whether an `Extra` will be packed next to it
struct BareStruct {
    number: f32,
    has_extra: bool,
}

BigStructBoxStruct结构在结构内编码了是否包含Extra数据,因此要么增加结构的大小,要么在堆上添加间接引用层。

BareStruct只有一个标志,表示是否将Extra数据带在旁边。

时间

基准测试 大约50%有Extra 大约10%有Extra 大约1%有Extra
BigStruct, 1000x 38.910µs 24.111µs 19.717µs
BoxStruct, 1000x 49.197µs 15.292µs 2.6134µs
HVec, 1000x 27.757µs 11.132µs 5.6643µs
- - - -
BigStruct, 4000x 156.29µs 95.310µs 79.063µs
BoxStruct, 4000x 220.69µs 62.703µs 10.651µs
HVec, 4000x 114.26µs 45.898µs 22.677µs
- - - -
BigStruct, 16000x 676.91µs 399.65µs 339.60µs
BoxStruct, 16000x 928.10µs 266.41µs 41.443µs
HVec, 16000x 460.43µs 181.65µs 90.787µs

如果您根据这些基准进行判断:除非您收集的大型数据非常罕见,否则 HVec 可以是存储和迭代它的一种更节省时间和空间的方法。

无运行时依赖