比较散列策略
總覽
編年史有許多用于哈希的實(shí)現(xiàn),包括City和Murmur。 它也有自己的香草哈希,但是如何進(jìn)行測(cè)試?
什么是香草哈希?
Vanilla Hash設(shè)計(jì)得盡可能簡(jiǎn)單,并且針對(duì)Orthogonal Bits測(cè)試進(jìn)行了優(yōu)化(請(qǐng)參見下文),并與City 1.1和Murmur 3哈希策略進(jìn)行了比較。
這是用新數(shù)據(jù)填充64字節(jié)/ 256字節(jié)緩沖區(qū)并生成64位哈希值的99%延遲。 JMH用于執(zhí)行測(cè)量。 請(qǐng)參閱Main64bytes和Main256bytes
| 香草 | 67 ns | 112毫微秒 |
| 城市1.1 | 90納秒 | 182 ns |
| 雜音3 | 104毫微秒 | 211 ns |
- 完整的測(cè)試結(jié)果在這里。
您可以執(zhí)行哪些測(cè)試來檢查哈希策略是否良好?
您可以執(zhí)行許多簡(jiǎn)單的測(cè)試。 測(cè)試無法識(shí)別出良好的哈希,但可以將哈希顯示為不良哈希。 通過一項(xiàng)測(cè)試可能意味著它將無法通過另一項(xiàng)測(cè)試。
在每種情況下,都使用不同的隨機(jī)起點(diǎn)運(yùn)行多個(gè)測(cè)試。 分?jǐn)?shù)為第99%,即最差的1%。 這是因?yàn)槟恍枰谀承r(shí)間或平均情況下有效的哈希。 您需要一種大多數(shù)情況下都可以使用的產(chǎn)品。 (在所有情況下,您都可以發(fā)明任何特定散列都將分解的病理情況)
為了保持一致性,分?jǐn)?shù)越低越好。 測(cè)試的構(gòu)造應(yīng)使得分為0表示測(cè)試已損壞。
在每個(gè)測(cè)試中,使用8,192位或1024 KB的輸入,一次切換一位。 根據(jù)這些輸入,將生成8,192 x 64位哈希。
但是,對(duì)于隨機(jī)測(cè)試,采用了一系列隨機(jī)的64位值。 這些對(duì)于了解所測(cè)試的散列策略有多少是有用的。
哈希表掩碼
在此測(cè)試中,每個(gè)哈希的模數(shù)為16,384(哈希數(shù)的兩倍),并且報(bào)告了沖突數(shù)。 大多數(shù)哈希策略在此測(cè)試中效果很好。
雪崩分?jǐn)?shù)
在此測(cè)試中,將每個(gè)散列與前一個(gè)散列(前一位進(jìn)行切換)進(jìn)行比較,以查看任何給定位被翻轉(zhuǎn)的可能性。 理想值為50%,與50%的差異之和為報(bào)告的最差1%。
延遲速度
在此測(cè)試中,記錄了執(zhí)行哈希所需的時(shí)間,并報(bào)告了最差的1%延遲。
正交鉆頭
該測(cè)試的目的是確保所有哈希具有的位與生成的其他所有哈希均盡可能不同。 除了64位數(shù)字外,請(qǐng)考慮8個(gè)皇后問題。 理想的情況是每個(gè)數(shù)字都具有與其他每個(gè)數(shù)字不同的相同位數(shù),并且位數(shù)應(yīng)盡可能高。
在此測(cè)試中,將每個(gè)哈希與每個(gè)其他哈希進(jìn)行比較。 對(duì)不同的位數(shù)進(jìn)行計(jì)數(shù)。 如果不同位數(shù)小于18,則給出2 ^(17-n)的懲罰分?jǐn)?shù)。 位數(shù)越少,則指數(shù)級(jí)的懲罰越大。 如果映射到其他8K哈希值的任何8K哈希值的差異小于5位,則即使所有其他對(duì)都很好,這也是失敗的。
我稱其為正交位測(cè)試,因?yàn)槟梢詫?4位數(shù)字建模為64位的位向量。 理想情況下,您希望產(chǎn)生的所有散列之間的角度盡可能大。
在所有測(cè)試中,此測(cè)試顯示具有HashMap.hash(int)的String.hashCode()與其他哈希策略之間的最大差異。
測(cè)試String.hashCode()
String.hashCode()是一個(gè)非常差的哈希,尤其是對(duì)于低位 。 它是標(biāo)準(zhǔn)的,不能更改或破壞向后兼容性。 但是,這不一定是問題,因?yàn)镠ashMap使用agitate函數(shù),該函數(shù)會(huì)降低一些較高的位以隨機(jī)化較低的位。
int hash(int h) {// This function ensures that hashCodes that differ only by// constant multiples at each bit position have a bounded// number of collisions (approximately 8 at default load factor).h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4); }結(jié)果
CheckMain類對(duì)每種哈希策略運(yùn)行一套測(cè)試。
VANILLA Orthogonal bits: 99%tile score: 6066 Speed: The 99%tile for latency was 0.223 us Avalanche: The 99%tile of the drift from 50% was 0.55% Mask of Hash: 99%tile collisions: 1815CITY_1_1 Orthogonal bits: 99%tile score: 7395 Speed: The 99%tile for latency was 0.267 us Avalanche: The 99%tile of the drift from 50% was 0.55% Mask of Hash: 99%tile collisions: 1817MURMUR_3 Orthogonal bits: 99%tile score: 7524 Speed: The 99%tile for latency was 0.378 us Avalanche: The 99%tile of the drift from 50% was 0.54% Mask of Hash: 99%tile collisions: 1815STRING32 Orthogonal bits: 99%tile score: 295906433 Speed: The 99%tile for latency was 1.580 us Avalanche: The 99%tile of the drift from 50% was 1.02% Mask of Hash: 99%tile collisions: 1814STRING64 Orthogonal bits: 99%tile score: 1939167 Speed: The 99%tile for latency was 1.520 us Avalanche: The 99%tile of the drift from 50% was 0.61% Mask of Hash: 99%tile collisions: 1816STRING32_WITHOUT_AGITATE Orthogonal bits: 99%tile score: 879390386 Speed: The 99%tile for latency was 1.573 us Avalanche: The 99%tile of the drift from 50% was 3.53% Mask of Hash: 99%tile collisions: 6593RANDOM Orthogonal bits: 99%tile score: 7444 Speed: The 99%tile for latency was 0.058 us Avalanche: The 99%tile of the drift from 50% was 0.53% Mask of Hash: 99%tile collisions: 1817SECURE_RANDOM Orthogonal bits: 99%tile score: 7449 Speed: The 99%tile for latency was 0.861 us Avalanche: The 99%tile of the drift from 50% was 0.54% Mask of Hash: 99%tile collisions: 1816SEEDED_VANILLA Orthogonal bits: 99%tile score: 6000 Speed: The 99%tile for latency was 0.219 us Avalanche: The 99%tile of the drift from 50% was 0.55% Mask of Hash: 99%tile collisions: 1814SEEDED_CITY_1_1 Orthogonal bits: 99%tile score: 7313 Speed: The 99%tile for latency was 0.270 us Avalanche: The 99%tile of the drift from 50% was 0.54% Mask of Hash: 99%tile collisions: 1813SEEDED_MURMUR_3 Orthogonal bits: 99%tile score: 7404 Speed: The 99%tile for latency was 0.359 us Avalanche: The 99%tile of the drift from 50% was 0.53% Mask of Hash: 99%tile collisions: 1810注意:香草雜種種子是Chronicle Enterprise的一部分
結(jié)論
Vanilla,City和Murmur哈希是最快的。
盡管String.hashCode()很簡(jiǎn)單,但每個(gè)字符的乘法運(yùn)算卻很昂貴。 相比之下,所有其他字節(jié)使用long一次處理8個(gè)字節(jié)。 與STRING32相比,請(qǐng)參閱STRINGS32_WITHOUT_AGITATE。 HashMap使用更高版本。
即使在avalanche測(cè)試中,帶有攪動(dòng)的32位String hashCode()也表現(xiàn)不佳。 在SMHasher中,該測(cè)試的得分超過1%被視為失敗。
哈希掩碼測(cè)試雖然簡(jiǎn)單,但在所有情況下都表現(xiàn)良好。 例外是String.hashCode(),如上所述,它沒有非常隨機(jī)的低位。
我發(fā)現(xiàn)有趣的是,正交測(cè)試得分有何不同。 前三個(gè)哈希策略再次持續(xù)較低。 甚至String.hashCode()的64位版本在產(chǎn)生散列方面也有很大的變化,只有不到18位的不同,實(shí)際上很多位是相同的。
免責(zé)聲明
香草哈希已針對(duì)正交鉆頭測(cè)試進(jìn)行了優(yōu)化。 因此,獲得更好的結(jié)果也就不足為奇了。 這并不意味著Vanilla Hash比City或Murmur好。 這可能僅表示對(duì)“正交位”測(cè)試最好。
翻譯自: https://www.javacodegeeks.com/2015/08/comparing-hashing-strategies.html
總結(jié)
- 上一篇: 最便宜2k屏的手机有哪几款(追剧有什么好
- 下一篇: vaadin_Vaadin应用程序中的E