哈希

HashSetHashMap 是两种广泛使用的类型。默认的哈希算法未指定,但在撰写本文时,默认的是一种称为 SipHash 1-3 的算法。这个算法质量很高——它提供了很高的碰撞保护——但相对较慢,特别是对于像整数这样的短键。

如果性能分析显示哈希操作很热门,并且哈希拒绝服务攻击不是您的应用程序的关注点,那么使用具有更快哈希算法的哈希表可以提供很大的速度优势。

  • rustc-hash 提供了 FxHashSetFxHashMap 类型,它们是 HashSetHashMap 的即插即用替代品。其哈希算法质量低,但非常快,特别是对于整数键,已经被发现在 rustc 中优于所有其他哈希算法。(fxhash 是相同算法和类型的一个较旧、维护程度较低的实现。)
  • fnv 提供了 FnvHashSetFnvHashMap 类型。其哈希算法比 rustc-hash 更高质量,但稍微慢一些。
  • ahash 提供了 AHashSetAHashMap。其哈希算法可以利用一些处理器上可用的 AES 指令支持。

如果哈希性能在您的程序中很重要,值得尝试多种替代方案。例如,在 rustc 中观察到以下结果。

如果决定普遍使用其中一种替代方案,比如 FxHashSet/FxHashMap,很容易在某些地方意外使用 HashSet/HashMap。您可以使用 Clippy 来避免这个问题。

有些类型不需要哈希。例如,您可能有一个包装整数的新类型,而整数值是随机的,或者接近随机的。对于这种类型,哈希值的分布与值本身的分布不会有太大的不同。在这种情况下,nohash_hasher crate 可以很有用。

哈希函数设计是一个复杂的话题,超出了本书的范围。ahash 文档 中有很好的讨论。