#vec #slot #memory #location #stable #indices #order

persist-o-vec

一个旨在具有稳定索引和内存位置的 Vec 类型

12 个版本

0.3.1 2020 年 7 月 11 日
0.3.0 2020 年 1 月 31 日
0.2.4 2020 年 1 月 29 日
0.1.7 2020 年 1 月 28 日

#647数据结构

Download history 99/week @ 2024-02-26 3/week @ 2024-03-04

每月 102 次下载
tiny_ecs 中使用

MPL-2.0 许可证

23KB
533

pipeline status docs.rs status

Persist-O-Vec

“persist-o-vec”的目的是

  • 防止重新分配
  • 删除项而不会向左移动
  • 快速重用已释放的槽位,弹出,推送和删除
  • 仅遍历已使用槽位

因此,您必须在使用之前分配所需的内容,最多达到所选索引器功能确定的极限。未来将提供选项,如果需要,可以增加容量。

它在某些情况下(如推送)会稍微类似于 stable-vec,但不会在 vec 中重用已释放的槽位。

正在进行中! 我会在工作时添加一些内容。

注意: 将在将来添加一个启用重新分配的功能。目前,这个包的目的是防止重新分配,从而防止指针失效。这个包目前是一个实验性的项目。

迭代器不一定按顺序排列

默认功能是 FIFO

原因

我处于需要 Vec<Option<T> 的场景 - 这实际上是 Vec 的常见用法。但我也需要 Vec 永远不移动(重新分配),以便指针不会失效,我还想快速遍历 Vec。

迭代问题源于 Vec 通常非常快,但它是一个连续的内存块。一旦你向其中引入 Option<T>,你将需要检查每个槽位,并将遍历整个 Vec,这可能导致有很多空白空间。

Persist-O-Vec试图在一定程度上解决这个问题。迭代器现在运行得很快,并且只遍历实际分配的槽位,并强制预先分配所需的空间,以确保位置不会移动。

未来我将添加一个功能,以便在尝试推送一个项目时,如果给定的空间不足,则允许重新分配。

使用unsafe

在7个函数内部的代码中有10处使用unsafe - 这些用于解引用保证安全、快速的指针。这些使用经过严格的审查和单元测试、基准测试以及在外部代码中的应用(随后,模糊测试)。

空间使用

空间使用至少每条记录额外24个字节。Rust将根据存储的内容执行一些优化。

基准测试

running 10 tests
test pst_init_with_capacity        ... bench:      17,221 ns/iter (+/- 1,012)
test pst_iter                      ... bench:      19,105 ns/iter (+/- 798)
test pst_iter_mut                  ... bench:      19,220 ns/iter (+/- 1,281)
test pst_populate_to_capacity      ... bench:      65,173 ns/iter (+/- 2,484)
test pst_populate_to_capacity_fast ... bench:      42,507 ns/iter (+/- 2,122)
test pst_remove_and_push           ... bench:          51 ns/iter (+/- 7)
test vec_iter                      ... bench:       4,476 ns/iter (+/- 253)
test vec_iter_mut                  ... bench:       6,159 ns/iter (+/- 1,500)
test vec_populate_to_capacity      ... bench:      18,886 ns/iter (+/- 1,143)
test vec_remove_and_push           ... bench:      22,673 ns/iter (+/- 1,244)

pst_populate_to_capacity_fast看起来像这样:Persist::with_capacity_filled_by(LIMIT, || Velocity(1.0));

提醒:像这样对小事进行基准测试相对困难,因为编译器通常能够将事物优化到更少的量,甚至完全移除。上述基准测试应该仅供参考,尽管它们确实有助于一些优化。

在实际使用中,例如在游戏引擎中为ECS提供后端时,Persist-O-Vec表现极其出色。例如,当它用作tiny_ecs的后端时

     Running target/release/deps/pos_vel_legion-2f3c5c5d2ec6ce5d

running 2 tests
test bench_build  ... bench:     526,150 ns/iter (+/- 42,578)
test bench_update ... bench:       1,898 ns/iter (+/- 98)

test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured; 0 filtered out

     Running target/release/deps/pos_vel_specs-bbdfcc04780f88ac

running 2 tests
test bench_build  ... bench:     316,030 ns/iter (+/- 25,096)
test bench_update ... bench:       3,315 ns/iter (+/- 142)

test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured; 0 filtered out

     Running target/release/deps/pos_vel_tiny_ecs-26c6953c8fca73ca

running 2 tests
test bench_build  ... bench:     386,614 ns/iter (+/- 22,060)
test bench_update ... bench:       2,040 ns/iter (+/- 229)

它似乎能够跟上专门针对ECS的ECS引擎。

没有运行时依赖