XXHASH是一種非常快速的哈希算法,以RAM速度限制處理。代碼是高度便攜的,並且在所有平台(小 /大端)上產生相同的哈希。該庫包括以下算法:
v0.8.0以來):使用矢量化算術生成64或128位哈希。 128位變體稱為XXH128。所有變體都成功完成了評估哈希功能質量(碰撞,分散和隨機性)的Smhasher測試套件。還提供了其他測試,該測試還提供了更全面的速度和64位哈希的碰撞特性。
| 分支 | 地位 |
|---|---|
| 發布 | ![]() |
| 開發 | ![]() |
基準的參考系統使用Intel I7-9700K CPU,並運行Ubuntu X64 20.04。使用-O3標誌與clang V10.0編譯開源基準程序。
| 哈希名 | 寬度 | 帶寬(GB/S) | 小數據速度 | 品質 | 評論 |
|---|---|---|---|---|---|
| XXH3 (SSE2) | 64 | 31.5 GB/s | 133.1 | 10 | |
| XXH128 (SSE2) | 128 | 29.6 GB/s | 118.1 | 10 | |
| RAM順序讀取 | N/A。 | 28.0 GB/s | N/A。 | N/A。 | 供參考 |
| 城市64 | 64 | 22.0 GB/s | 76.6 | 10 | |
| T1HA2 | 64 | 22.0 GB/s | 99.0 | 9 | 碰撞稍差 |
| 城市128 | 128 | 21.7 GB/s | 57.7 | 10 | |
| xxh64 | 64 | 19.4 GB/s | 71.0 | 10 | |
| Spookyhash | 64 | 19.3 GB/s | 53.2 | 10 | |
| 媽媽 | 64 | 18.0 GB/s | 67.0 | 9 | 碰撞稍差 |
| xxh32 | 32 | 9.7 GB/s | 71.9 | 10 | |
| 城市32 | 32 | 9.1 GB/s | 66.0 | 10 | |
| Murmur3 | 32 | 3.9 GB/s | 56.1 | 10 | |
| siphash | 64 | 3.0 GB/s | 43.2 | 10 | |
| FNV64 | 64 | 1.2 GB/s | 62.7 | 5 | 雪崩的差 |
| Blake2 | 256 | 1.1 GB/s | 5.1 | 10 | 加密 |
| SHA1 | 160 | 0.8 GB/s | 5.6 | 10 | 加密但破裂 |
| MD5 | 128 | 0.6 GB/s | 7.8 | 10 | 加密但破裂 |
注意1:小數據速度是對算法在小數據上的效率的粗略評估。有關更多詳細分析,請參閱下一段。
注2:某些算法的特徵比RAM速度快。在這種情況下,當輸入已經在CPU緩存(L3或更高)中時,它們只能達到全速電位。否則,它們會以RAM速度限制最大化。
大數據的性能只是圖片的一部分。哈希在哈希表和盛開過濾器之類的結構中也非常有用。在這些用例中,經常使用許多小數據(以幾個字節開始)。對於這種情況,算法的性能可能會大不相同,因為算法的某些部分(例如初始化或最終化)成為固定成本。分支錯誤預測的影響也變得更加存在。
XXH3已設計為在長輸入和小型輸入上都具有出色的性能,可以在以下圖中觀察到:

要進行更詳細的分析,請訪問Wiki:https://github.com/cyan4973/xxhash/wiki/performance-comparison-comparison#benchs-concentration-concentration-oncentration-on-small-data--
速度不是唯一重要的屬性。產生的哈希值必須尊重出色的分散性和隨機性特性,以便可以使用其最大分佈表或索引的任何子部分,並在生日悖論之後將碰撞量減少到最小的理論水平。
xxHash已通過Austin Appleby出色的Smhasher測試套件進行了測試,並通過所有測試,確保了合理的質量水平。它還通過Smhasher的新叉子進行了擴展測試,其中包括其他場景和條件。
最後,XXHASH提供了自己的巨大碰撞測試儀,能夠生成和比較數十億個哈希人來測試64位哈希算法的限制。在這方面,XXHASH也具有與生日悖論一致的良好結果。 Wiki中記錄了更詳細的分析。
可以在彙編時間設置以下宏來修改libxxhash的行為。默認情況下,它們通常被禁用。
XXH_INLINE_ALL :使所有功能inline ,實現直接包含在xxhash.h中。插入功能對速度有益,特別是對小鍵。當Key的長度表示為編譯時間常數時,它非常有效,並且在 +200%範圍內觀察到性能提高。有關詳細信息,請參見本文。XXH_PRIVATE_API :與XXH_INLINE_ALL相同的結果。仍然可用於傳統支持。該名稱強調了XXH_*符號名稱不會導出。XXH_STATIC_LINKING_ONLY :訪問靜態分配所需的內部狀態聲明。由於ABI變化的風險,與動態鏈接不兼容。XXH_NAMESPACE :前綴所有符號都具有XXH_NAMESPACE的值。該宏只能使用可編譯的字符集。如果XXHASH的源代碼多個包含物,則有助於逃避符號命名碰撞。客戶端應用程序仍然使用常規函數名稱,因為符號會自動通過xxhash.h自動翻譯。XXH_FORCE_ALIGN_CHECK :在對齊輸入時,請使用更快的直接讀取路徑。當輸入到Hash恰好在32或64位邊界上對齊時,此選項可能會導致無法從未對齊地址加載內存的體系結構的急劇提高。它(略有)在平台上具有良好的未對齊內存訪問性能(對對齊和未對準訪問的指令相同)。此選項將在x86 , x64和aarch64上自動禁用,並在所有其他平台上啟用。XXH_FORCE_MEMORY_ACCESS :默認方法0使用便攜式memcpy()符號。方法1使用特定於GCC的packed屬性,該屬性可以為某些目標提供更好的性能。方法2力量不一致的讀數,這不是標準的,但有時可能是提取更好讀取性能的唯一方法。方法3使用字節截面操作,最適合不嵌入memcpy()或大型系統的舊編譯器,而沒有字節匯款說明。XXH_CPU_LITTLE_ENDIAN :默認情況下,Endianness由在編譯時解決的運行時測試確定。如果出於某種原因,編譯器無法簡化運行時測試,則可以花費性能。可以跳過自動檢測,並簡單地說明該架構將其設置為1。XXH_ENABLE_AUTOVECTORIZE :XXH32和XXH64可以觸發自動矢量化,具體取決於CPU矢量功能和編譯器版本。注意:最近版本的clang傾向於更容易觸發自動矢量化。對於XXH32,SSE4.1或等效(NEON)就足夠了,而XXH64需要AVX512。不幸的是,自動矢量化通常不利於XXH性能。因此,XXHASH源代碼試圖防止默認情況下自動矢量化。話雖這麼說,系統就不斷發展,並且這一結論並不是即將得出的。例如,據報導,最近的Zen4 CPU更有可能通過矢量化提高性能。因此,如果您喜歡或想測試矢量化代碼,則可以啟用此標誌:它將刪除無矢量化保護代碼,從而使XXH32和XXH64自動矢量化更有可能。XXH32_ENDJMP :單個跳躍的XXH32的多分支最終確定階段。通常,這對於性能是不可取的,尤其是在隨機大小的哈希輸入時。但是根據確切的體系結構和編譯器,跳躍可能會在小型輸入上提供更好的性能。默認情況下禁用。XXH_IMPORT :MSVC特定:僅應為動態鏈接定義,因為它可以防止鏈接錯誤。XXH_NO_STDLIB : <stdlib.h>函數的禁用調用,尤其是malloc()和free() 。 libxxhash的XXH*_createState()將始終失敗並返回NULL 。但是一擊哈希(例如XXH32() )或使用靜態分配狀態流式傳輸仍可以按預期工作。該構建標誌對於沒有動態分配的嵌入式環境很有用。XXH_DEBUGLEVEL :設置為任何值> = 1時,啟用assert()語句。這(稍微)減慢了執行,但可能有助於在調試會議期間找到錯誤。 XXH_NO_XXH3 :從生成的二進製文件中刪除與XXH3 (64和128位)相關的符號。 XXH3是迄今為止libxxhash尺寸的最大貢獻者,因此減少不使用XXH3的應用程序二進制尺寸很有用。XXH_NO_LONG_LONG :刪除依賴64位long long類型的算法的編譯,包括XXH3和XXH64 。僅XXH32將被編譯。對於無64位支持的目標(架構和編譯器)有用。XXH_NO_STREAM :禁用流動API,將庫僅限於單個鏡頭變體。XXH_NO_INLINE_HINTS :默認情況下,XXHASH使用__attribute__((always_inline))和__forceinline以代碼大小為代價來提高性能。將此宏定義為1將所有內部功能都標記為static ,從而允許編譯器決定是否嵌入功能。當對最小的二進制尺寸進行優化時,這非常有用,並且在使用-O0 , -Os , -Oz或-fno-inline上在GCC和Clang上自動定義。這也可能會根據編譯器和體系結構提高性能。XXH_SIZE_OPT : 0 :默認值,優化速度1 : -Os和-Oz的默認值:禁用一些速度hacks以進行大小優化2 :使代碼盡可能小,性能可能會哭泣XXH_VECTOR :手動選擇一個向量指令集(默認:在編譯時自動選擇)。可用的說明集為XXH_SCALAR , XXH_SSE2 , XXH_AVX2 , XXH_AVX512 , XXH_NEON和XXH_VSX 。編譯器可能需要其他標誌來確保適當的支持(例如,X86_64上的gcc需要-mavx2的AVX2或-mavx512f , AVX512 )。XXH_PREFETCH_DIST :選擇預取距離。以近距離適應特定的硬件平台。僅xxh3。XXH_NO_PREFETCH :禁用預取。某些平台或情況可能會表現更好,而無需預取。僅xxh3。 使用make編譯命令行界面xxhsum時,還可以設置以下環境變量:
DISPATCH=1 :使用xxh_x86dispatch.c ,根據本地主機在運行時自動選擇scalar , sse2 , avx2或avx512指令。此選項僅對x86 / x64系統有效。XXH_1ST_SPEED_TARGET :選擇一個以MB/s表示的初始速度目標,以在基準模式下進行首次速度測試。基準將在隨後的迭代中調整目標,但是第一個測試是通過靶向此速度“盲目”進行的。目前,保守的設置為10 MB/s,以支持非常緩慢(模擬)平台。NODE_JS=1 :當使用emscripten編譯node.js xxhsum時,這將鏈接NODERAWFS庫以進行無限制的文件系統訪問和修補程序isatty ,以使命令行實用程序正確檢測終端。這確實使二進制特定於node.js。您可以使用VCPKG依賴項管理器下載並安裝XXHASH:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install xxhash
Microsoft團隊成員和社區貢獻者保持了VCPKG的XXHASH港口的最新狀態。如果該版本已過時,請在VCPKG存儲庫上創建問題或拉出請求。
最簡單的示例將XXHASH 64位變體稱為單次函數,從單個緩衝區生成哈希值,並從C/C ++程序調用:
#include "xxhash.h"
(...)
XXH64_hash_t hash = XXH64 ( buffer , size , seed );
}流式變體更多地參與了,但可以逐步提供數據:
#include "stdlib.h" /* abort() */
#include "xxhash.h"
XXH64_hash_t calcul_hash_streaming ( FileHandler fh )
{
/* create a hash state */
XXH64_state_t * const state = XXH64_createState ();
if ( state == NULL ) abort ();
size_t const bufferSize = SOME_SIZE ;
void * const buffer = malloc ( bufferSize );
if ( buffer == NULL ) abort ();
/* Initialize state with selected seed */
XXH64_hash_t const seed = 0 ; /* or any other value */
if ( XXH64_reset ( state , seed ) == XXH_ERROR ) abort ();
/* Feed the state with input data, any size, any number of times */
(...)
while ( /* some data left */ ) {
size_t const length = get_more_data ( buffer , bufferSize , fh );
if ( XXH64_update ( state , buffer , length ) == XXH_ERROR ) abort ();
(...)
}
(...)
/* Produce the final hash value */
XXH64_hash_t const hash = XXH64_digest ( state );
/* State could be re-used; but in this example, it is simply freed */
free ( buffer );
XXH64_freeState ( state );
return hash ;
}庫文件xxhash.c和xxhash.h已獲得BSD許可。公用事業xxhsum已獲得GPL許可。
除C參考版本外,XXHASH還可以從許多不同的編程語言中獲得,這要歸功於出色的貢獻者。他們在這裡列出。
許多發行版將軟件包管理器捆綁在一起,該軟件包管理器允許輕鬆安裝XXHASH安裝,因為libxxhash庫和xxhsum命令行接口。
xxhsum -c ,並在早期XXH版本中獲得大力支持XXH64的第一個版本XXH3和XXH128的令人難以置信的低級優化