世界上最快的哈希算法XXH3已经达到稳定状态

2020-07-29 03:12:24

注意:小数据速度是算法对于小数据的效率的粗略平均值。有关更准确的信息,请参阅下面第二部分的图表。

以下算法在现代x64 CPU上运行,但它们要么不可移植,要么它们的性能取决于是否存在不受保证的指令集(在x64上只保证SSE2)。

XXH3和XXH128也可以使用AVX512,但该指令集在测试平台上不可用。

注意:有些算法实际上比系统的RAM更快。只有在对缓存中已存在的数据段进行散列时,才能充分利用它们的全速。

有趣的是注意到缓存层在图表中清晰可见。主机CPU的一级缓存为32KB,二级缓存为256KB,三级缓存为12MB。AVX2变种的性能在超过每一个阈值时都会明显下降。

到目前为止,我们已经研究了64位的性能,其中64位散列具有优势,如果仅仅是凭借更快的数据摄取速度的话。这种情况在32位系统上发生了很大的变化,因为在32位指令集上仿真64位算术会对性能造成很大影响。

下图显示了这些散列算法在32位模式下的运行情况。它们中的大多数都遭受了性能的大幅下降。只有32位散列保持其性能,如XXH32。但好消息是,XXH3在32位CPU上也很好用,当有向量单元可用时更是如此。

在许多使用情况下,生成的哈希值可用于填充哈希表或布隆过滤器。在这些场景中,散列算法经常只是较大系统(如数据库)的一部分,并且会为许多相当小的对象调用它。当散列小对象时,散列属性与散列大输入相比可能有很大的不同。例如,一些算法可能有很长的开始或结束阶段,在小输入时占据主导地位。下面的测试试图捕获这些特征。

吞吐量测试尝试生成尽可能多的散列。这是经典的衡量标准,因为这是基准测试最简单的方法。但是,它仅代表批处理模式方案,并且还要求所有输入的长度完全相同。所以它实际上根本不是那个代表。

在这个更高级的场景中,输入长度不再稳定,这种情况通常更常见,因此该场景更有可能代表一些真实的用例。然而,作为一项吞吐量测试,它的目标仍然是批处理模式场景,其中必须重复生成大量散列。在下图中,长度实际上是随机的,从1到N之间生成的一系列值中读取。这种情况在分支预测器上要困难得多,分支预测器可能会错过相当多的猜测,偶尔会触发管道刷新。这样的负面影响会在小输入的情况下迅速影响性能,为了抵抗这种负面影响,一些算法被设计得更好。

延迟测试要求算法先完成一个哈希,然后再开始下一个哈希。这通常更能代表将散列集成到更大算法中的情况。