#hash-map #hash #cow #swisstable

no-std cow_hashbrown

支持写时复制的 Google SwissTable 哈希表的 Rust 版本

18 个版本

0.14.21 2024年7月28日
0.14.20 2024年7月27日

#139 in 数据结构

Download history 422/week @ 2024-07-05 143/week @ 2024-07-12 275/week @ 2024-07-19 326/week @ 2024-07-26 21/week @ 2024-08-02

854 每月下载量
cow_hashmap 中使用

MIT/Apache

790KB
11K SLoC

hashbrown

Build Status Crates.io Documentation Rust

在添加了 COW 支持的基础上,Fork 自 https://github.com/rust-lang/hashbrown

当修改条目列表或映射本身中的值时,会复制数据的 HashMap 实现。

原始的 crate 是 Google 的高性能 SwissTable 哈希表的 Rust 版本,经过修改,使其成为 Rust 标准库中 HashMapHashSet 类型的直接替代品。

SwissTable 的原始 C++ 版本可以在 这里 找到,而此 CppCon 讲座 提供了算法的概述。

自 Rust 1.36 以来,这现在是 Rust 标准库的 HashMap 实现。然而,您可能仍然希望使用此 crate,因为它可以在没有 std 的环境中工作,例如嵌入式系统和内核。

变更日志

功能

  • 标准库 HashMapHashSet 类型的直接替代品。
  • 使用 AHash 作为默认的哈希函数,它比 SipHash 快得多。然而,AHash 并不提供与 SipHash 相同的 HashDoS 抵御级别,因此如果您认为这一点很重要,您可能需要考虑使用不同的哈希函数。
  • 比之前的标准库 HashMap 快约 2 倍。
  • 较低的内存使用:每个条目只有 1 字节的开销,而不是 8 字节。
  • #[no_std] 兼容(但需要带有 alloc crate 的全局分配器)。
  • 空的哈希表不分配任何内存。
  • 使用 SIMD 进行查找,以并行扫描多个哈希条目。

性能

与之前的 std::collections::HashMap (Rust 1.35) 实现相比。

使用 hashbrown 默认的 AHash 哈希器

名称 oldstdhash ns/iter hashbrown ns/iter diff ns/iter diff % 速度提升
insert_ahash_highbits 18,865 8,020 -10,845 -57.49% x 2.35
insert_ahash_random 19,711 8,019 -11,692 -59.32% x 2.46
insert_ahash_serial 19,365 6,463 -12,902 -66.63% x 3.00
insert_erase_ahash_highbits 51,136 17,916 -33,220 -64.96% x 2.85
insert_erase_ahash_random 51,157 17,688 -33,469 -65.42% x 2.89
insert_erase_ahash_serial 45,479 14,895 -30,584 -67.25% x 3.05
iter_ahash_highbits 1,399 1,092 -307 -21.94% x 1.28
iter_ahash_random 1,586 1,059 -527 -33.23% x 1.50
iter_ahash_serial 3,168 1,079 -2,089 -65.94% x 2.94
lookup_ahash_highbits 32,351 4,792 -27,559 -85.19% x 6.75
lookup_ahash_random 17,419 4,817 -12,602 -72.35% x 3.62
lookup_ahash_serial 15,254 3,606 -11,648 -76.36% x 4.23
lookup_fail_ahash_highbits 21,187 4,369 -16,818 -79.38% x 4.85
lookup_fail_ahash_random 21,550 4,395 -17,155 -79.61% x 4.90
lookup_fail_ahash_serial 19,450 3,176 -16,274 -83.67% x 6.12

使用 libstd 默认的 SipHash 哈希器

名称 oldstdhash ns/iter hashbrown ns/iter diff ns/iter diff % 速度提升
insert_std_highbits 19,216 16,885 -2,331 -12.13% x 1.14
insert_std_random 19,179 17,034 -2,145 -11.18% x 1.13
insert_std_serial 19,462 17,493 -1,969 -10.12% x 1.11
insert_erase_std_highbits 50,825 35,847 -14,978 -29.47% x 1.42
insert_erase_std_random 51,448 35,392 -16,056 -31.21% x 1.45
insert_erase_std_serial 87,711 38,091 -49,620 -56.57% x 2.30
iter_std_highbits 1,378 1,159 -219 -15.89% x 1.19
iter_std_random 1,395 1,132 -263 -18.85% x 1.23
iter_std_serial 1,704 1,105 -599 -35.15% x 1.54
lookup_std_highbits 17,195 13,642 -3,553 -20.66% x 1.26
lookup_std_random 17,181 13,773 -3,408 -19.84% x 1.25
lookup_std_serial 15,483 13,651 -1,832 -11.83% x 1.13
lookup_fail_std_highbits 20,926 13,474 -7,452 -35.61% x 1.55
lookup_fail_std_random 21,766 13,505 -8,261 -37.95% x 1.61
lookup_fail_std_serial 19,336 13,519 -5,817 -30.08% x 1.43

用法

将此添加到您的 Cargo.toml

[dependencies]
hashbrown = "0.14"

然后

use cow_hashbrown::HashMap;

let mut map = HashMap::new();
map.insert(1, "one");

标志

此包有以下 Cargo 功能

  • nightly:启用仅在夜间版本中可用的功能,包括:#[may_dangle]
  • serde:启用 serde 序列化支持。
  • borsh:启用 borsh 序列化支持。
  • rkyv:启用 rkyv 序列化支持。
  • rayon:启用 rayon 并行迭代器支持。
  • equivalent:允许使用 Equivalent 特性自定义比较。
  • raw:启用对实验性和不安全的 RawTable API 的访问。
  • inline-more:向大多数函数添加内联提示,以编译时间代价提高运行时性能。(默认启用)
  • default-hasher:以 ahash 作为默认哈希器进行编译。(默认启用)
  • allocator-api2:启用对支持 allocator-api2 的分配器的支持。(默认启用)

许可

根据您选择,受以下任一项许可协议约束

贡献

除非您明确声明,否则任何有意提交以包含在您的工作中的贡献(根据 Apache-2.0 许可协议定义),均应如上所述双许可,不附加任何其他条款或条件。

依赖关系

~0.5–2.1MB
~40K SLoC