#array #packed #uint #dense #voxel-game #small

packed-uints

从u4到u32的可变数组,以最小化浪费的空间同时保持快速

10个版本

新版本 0.1.9 2024年8月11日
0.1.8 2024年8月4日
0.1.7 2023年12月28日
0.1.3 2023年9月24日
0.1.2 2023年8月2日

#2 in #voxel-game

Download history 16/week @ 2024-07-01 79/week @ 2024-07-29 116/week @ 2024-08-05

每月195次下载

无许可证

16KB
319

packed-uints

从u4到u32的可变数组,以最小化浪费的空间同时保持快速。感谢Martin Janin对实现工作所做的贡献!

这是一个非常专业的结构,具有专门的应用,在我的情况下,它是用于存储块数据在块中的voxel游戏。

使用

use packed_uints::PackedUints;

// initialize an empty array of length 100 (filled with 0)
let arr = PackedUints::new(100);
// or initialize it from an existing one
let values: Vec<usize> = (0..=15).collect();
let arr = PackedUints::from(values.as_slice());
// set a value at index 3
arr.set(3, 42);
// get the value at index 3
assert_eq!(arr.get(3), 42);

在我们的示例中,我们使用从0到15的值初始化了数组,因此PackedUints将选择使用4位来表示每个值(在一个u8上打包2个值),因为4位足以表示高达15的值。然而,当我们将索引3处的值设置为42时,PackedUints将切换到8位表示(在此过程中重新分配数组)以适应这个新值。

注意:PackedUints仅进行升级,出于性能原因。

基准测试

我将PackedUints与常规的Vec<u32>的性能以及Unthbuf进行了比较,这是一个具有类似目的的crate,但它将位大小决策留给用户,而不是像PackedUints那样自动升级。Unthbuf的好处是允许非对齐值,如u5,而PackedUints只支持u4、u8、u16和u32。

这3个结构在以下方面进行了基准测试

  • 随机读取性能(1百万个"u4"值)
  • 随机写入性能(1百万个"u4"值)
  • 从现有的Vec初始化(1百万个u32值)

以下是在Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz CPU上的结果

vec_read                time:   379.39 µs
vec_write               time:   2.0634 ms
vec_from_vec            time:   1.7448 ms
---
packed_uints_read       time:   438.08 µs
packed_uints_write      time:   3.3806 ms
packed_uints_from_vec   time:   1.9934 ms
---
unthbuf_read            time:   533.75 µs
unthbuf_write           time:   3.1632 ms
unthbuf_vec             time:   6.2827 ms

如你所见,这两个crate的性能相似,并不远于Vec<u32>,packed_uints在随机读取上略快,在从Vec初始化时速度明显更快。

无运行时依赖