#btree-set #btree-map #set #map #order-statistics

indexset

具有快速迭代和索引操作的二级 BTree

13 个版本

新版本 0.4.1 2024年8月19日
0.4.0 2024年5月24日
0.3.8 2024年2月17日
0.3.6 2023年8月12日
0.1.0 2023年7月4日

#401数据结构 中排名

Download history 25/week @ 2024-04-30 47/week @ 2024-05-07 166/week @ 2024-05-14 220/week @ 2024-05-21 53/week @ 2024-05-28 39/week @ 2024-06-04 86/week @ 2024-06-11 67/week @ 2024-06-18 96/week @ 2024-06-25 188/week @ 2024-07-02 100/week @ 2024-07-09 20/week @ 2024-07-16 71/week @ 2024-07-23 110/week @ 2024-07-30 31/week @ 2024-08-06 143/week @ 2024-08-13

每月 下载 355
物化视图 中使用

Apache-2.0 OR MIT

135KB
2.5K SLoC

indexset

crates.io docs

一个纯 Rust 动态有序统计 b-tree。

该软件包实现了一种紧凑的集合数据结构,它保留其元素的排序顺序,并允许通过值或排序顺序位置查找条目。

此外,它(在大多数情况下)是 stdlib BTree 的直接替换品。

背景

该项目受到了 indexmap 和 python 的 sortedcontainers 的强烈启发。

与两者不同的是

  • indexmap 是一个提供数值查找的哈希表,但在删除的情况下不会保持顺序,而 indexset 是一个始终保持顺序的 BTree,无论执行哪种突变操作。
  • sortecontainers 在精神上类似,但使用不同的算法来平衡树,并且依赖于堆进行数值查找。

indexset 提供以下功能

  • 与 vec 一样快速迭代。
  • 零间接。
  • 按位置和范围查找。
  • 分配最少的内存。
  • select(按位置查找)和 rank(按值查找)操作在接近常数时间内完成。

性能

BTreeSetBTreeMap 从其构建方式直接推导出一些性能事实,大致为

一个二级 B-Tree,其中使用 Fenwick 树作为数值查找的低成本索引

  • 迭代非常快,因为它继承了 vec 的迭代结构。
  • 在最佳情况下,插入和删除操作是常数时间,在最坏情况下,在节点大小上是对数时间
  • 查找非常快,并且仅依赖于少量数据的两次二分搜索。

基准测试

运行 cargo bench 并自行查看。

在一台最低配置的 M1 Macbook Pro 上,我得到了以下数据

插入 100k 随机 usize

  • stdlib::collections::BTreeSet.insert(i): 8.25ms
  • indexset::BTreeSet.insert(i): 17.3ms

检查每个100k随机usize整数是否存在

  • stdlib::collections::BTreeSet.contains(i): 7.5ms
  • indexset::BTreeSet.contains(i): 6.8ms

获取所有100k个i-th元素

  • stdlib::collections::BTreeSet.iter.nth(i): 13.28s yes, seconds!
  • indexset::BTreeSet.get_index(i): 3.93ms

遍历所有100k个元素并将它们收集到一个vec中

  • Vec::from_iter(stdlib::collections::BTreeSet.iter()): 227.28us
  • Vec::from_iter(indexset::BTreeSet.iter()): 123.21.us

是的。

获取第i个元素比stdlib的btree快3400倍,contains快10%,迭代快两倍,但插入速度减半。

如果你的使用场景是std::collections::BTreeSetBTreeMap更侧重于读取,或者你确实需要按排序顺序位置索引,那么检查这个indexset可能是有价值的。

局限性

  • BTreeMapBTreeSet更不成熟。这个crate已经针对更精简的BTreeSet进行了优化。
  • 这是**beta**级别的软件,所以请自行承担使用风险。我对每个迭代器的实现(尽管所有内容都有测试)并不完全确定。
  • 还有相当多的实用特性尚未实现。

命名

这个库叫做indexset,因为基本数据结构是BTreeSetBTreeMap是一个具有Pair<K, V>项类型的BTreeSet

变更日志

CHANGELOG.md

依赖项

~0.4–1MB
~22K SLoC