#hash-map #map #memory-map #memory #maps #key #performance

无std micromap

HashMap的最佳替代品,适用于键数小于20的映射

15个版本

0.0.15 2024年1月1日
0.0.14 2023年5月9日
0.0.12 2023年4月27日

内存管理中排名第69

Download history • Rust 包仓库 100/week @ 2024-04-07 • Rust 包仓库 57/week @ 2024-04-14 • Rust 包仓库 1/week @ 2024-04-21 • Rust 包仓库 24/week @ 2024-04-28 • Rust 包仓库 26/week @ 2024-05-05 • Rust 包仓库 8/week @ 2024-05-12 • Rust 包仓库 24/week @ 2024-05-19 • Rust 包仓库 24/week @ 2024-05-26 • Rust 包仓库 14/week @ 2024-06-02 • Rust 包仓库 16/week @ 2024-06-09 • Rust 包仓库 10/week @ 2024-06-16 • Rust 包仓库 11/week @ 2024-06-23 • Rust 包仓库 28/week @ 2024-06-30 • Rust 包仓库 9/week @ 2024-07-07 • Rust 包仓库 16/week @ 2024-07-14 • Rust 包仓库 19/week @ 2024-07-21 • Rust 包仓库

每月下载量达72次

MIT许可

87KB
1.5K SLoC

cargo crates.io codecov Hits-of-Code License docs.rs

HashMap的一个非常快速的替代品,适用于非常小的映射。它也比FxHashMap、hashbrown、ArrayMap、IndexMap以及其他所有映射都快。映射越小,性能越高。观察发现,当映射包含的键数超过20个时,可能更适合使用标准的HashMap,因为micromap::Map的性能可能会开始下降。请参见下面的基准测试结果

欢迎:并非所有在映射中可能期望拥有的功能都已实现。如果您能通过实现这些缺失的功能来做出贡献,我将不胜感激。

首先,将以下内容添加到Cargo.toml

[dependencies]
micromap = "0.0.14"

然后,像使用标准哈希映射一样使用它...嗯,几乎是这样

use micromap::Map;
let mut m : Map<u64, &str, 10> = Map::new(); // allocation on stack
m.insert(1, "foo");
m.insert(2, "bar");
assert_eq!(2, m.len());

请注意,这里创建的映射带有额外的泛型参数10。这是映射的总大小,当调用::new()时在栈上分配。与HashMap不同,Map完全不使用堆。如果向映射中添加超过十个键,它将引发panic。

阅读 API 文档。结构体 micromap::Map 被设计得尽可能类似于 std::collections::HashMap

基准测试

以下是一个简单基准测试的总结,我们比较了 micromap::Map 与其他几个 Rust 映射,改变了映射的总容量(水平轴)。我们对它们应用了相同的交互(benchmark.rs),并测量了它们的性能。在下表中,大于 1.0 的数字表示性能提升,而小于 1.0 的数字表示性能下降。

2 4 8 16 32 64 128
hashbrown::HashMap 21.49 11.70 6.48 3.64 1.66 0.60 0.31
heapless::LinearMap 1.00 1.59 1.18 1.27 1.34 1.20 0.98
indexmap::IndexMap 12.81 12.48 7.53 4.62 2.41 0.97 0.49
linear_map::LinearMap 2.27 1.62 1.16 1.09 1.04 1.15 1.15
linked_hash_map::LinkedHashMap 28.55 21.61 12.49 7.42 3.83 1.57 0.78
litemap::LiteMap 3.76 2.89 2.04 1.86 1.32 0.59 0.48
micromap::Map 👍 1.00 1.00 1.00 1.00 1.00 1.00 1.00
nohash_hasher::BuildNoHashHasher 21.08 12.04 7.62 3.31 1.65 0.64 0.34
rustc_hash::FxHashMap 20.51 11.79 6.66 3.94 1.44 0.55 0.30
std::collections::BTreeMap 21.16 10.37 8.66 6.60 3.83 1.20 0.73
std::collections::HashMap 22.02 14.87 8.98 5.29 2.84 1.05 0.58
tinymap::array_map::ArrayMap 2.00 4.71 4.56 4.90 5.58 4.57 4.70

该实验于 2023-12-31 进行。重复周期为 1000000。整个基准测试耗时 194 秒。

如您所见,对于小于十个键的映射,性能提升最为显著。对于只有几个键的映射,提升非常巨大。

如何贡献

首先安装 Rust,然后

$ cargo test -vv

如果一切顺利,Fork 存储库,进行更改,通过发送给我们 pull request。我们会审查您的更改,并在不久后将其应用到 master 分支,前提是它们不违反我们的质量标准。为了避免失望,在发送 pull request 之前,请再次运行 cargo test。此外,运行 cargo fmtcargo clippy

此外,在您开始进行更改之前,运行基准测试

$ rustup run nightly cargo bench

然后,在您进行更改后再次运行。比较结果。如果您的更改降低了性能,在提交 pull request 之前请三思。

依赖项

~170KB