哈希
HashSet
和 HashMap
是两种广泛使用的类型。默认的哈希算法未指定,但在撰写本文时,默认的是一种称为 SipHash 1-3 的算法。这个算法质量很高——它提供了很高的碰撞保护——但相对较慢,特别是对于像整数这样的短键。
如果性能分析显示哈希操作很热门,并且哈希拒绝服务攻击不是您的应用程序的关注点,那么使用具有更快哈希算法的哈希表可以提供很大的速度优势。
rustc-hash
提供了FxHashSet
和FxHashMap
类型,它们是HashSet
和HashMap
的即插即用替代品。其哈希算法质量低,但非常快,特别是对于整数键,已经被发现在rustc
中优于所有其他哈希算法。(fxhash
是相同算法和类型的一个较旧、维护程度较低的实现。)fnv
提供了FnvHashSet
和FnvHashMap
类型。其哈希算法比rustc-hash
更高质量,但稍微慢一些。ahash
提供了AHashSet
和AHashMap
。其哈希算法可以利用一些处理器上可用的 AES 指令支持。
如果哈希性能在您的程序中很重要,值得尝试多种替代方案。例如,在 rustc
中观察到以下结果。
如果决定普遍使用其中一种替代方案,比如 FxHashSet
/FxHashMap
,很容易在某些地方意外使用 HashSet
/HashMap
。您可以使用 Clippy 来避免这个问题。
有些类型不需要哈希。例如,您可能有一个包装整数的新类型,而整数值是随机的,或者接近随机的。对于这种类型,哈希值的分布与值本身的分布不会有太大的不同。在这种情况下,nohash_hasher
crate 可以很有用。
哈希函数设计是一个复杂的话题,超出了本书的范围。ahash
文档 中有很好的讨论。