單數組哈希表unordered_map和unordered_set(轉)

源博客地址

單數組哈希表unordered_map和unordered_set

以靜態表爲例,原理如下圖,也就是多個單鏈表存儲在同一個數組中。勉強算開地址哈希表吧,但跟一般開地址哈希表原理
不太一樣。存儲在同一個數組的目的是節省一個表頭指針,有表頭指針的哈希表見本主頁”雙數組哈希unordered_xxx”相
對於傳統的拉鍊哈希表,這個哈希表的原理不太好理解(傳統的好理解,但耗費內存多且速度慢~~)
這裏寫圖片描述

這裏寫圖片描述

看上圖。使用默認值覆蓋的原因是我們原本用它計算陸地座標,(0,0,0)這個點在海里,我們根本用不上。如果想存入
默認值的話,需要小改一下代碼,節點snode增加一個計數器跟指針組成union,默認值放在slot最高端做特殊處理。

顯然他比雙數組哈希表節約內存,這不必說了,速度當然也要比雙數組哈希表稍慢一點,但慢不了太多,不過還是比
常見的數組+鏈表的拉鍊哈希錶快,當然僅侷限於處理整數,處理長字符竄的話,可以改爲處理字符竄指針理論上會
好一些。順便說一句,最適合處理字符竄的數據結構顯然不是哈希表,而是trie,如果內存不充裕則應該用有向無環圖。

這個表用於PC機上意義不大,用於內存相對緊張,硬件計算能力十分有限的嵌入式則意義非凡。

PC機上我用64位的g++4.8.2和VC++11.0編譯OK,別的編譯器不知道能否通過。分別在Windows7 X64和
Debian 7.2 X64系統上用g++編譯做了測試,僅僅測試了64位僞隨機數,跟系統的std::unordered_map做個簡
單的比較,結果如下。

這裏寫圖片描述

Sample::unordered_map的erase操作比find和insert顯著慢的原因是減肥了,當空間利用率50%的時候自動
減肥,釋放用不到的空間。實時性要求高且內存碎片敏感的嵌入式裏應該禁止resize,減少碎片且提升速度。

上表僅僅是靜態表的測試結果,在PC上模擬的。在Linux和Windows都用的g++4.8.2編譯器。編譯選項用了
-std=c++11, -O3,鏈接選項-s -static。注意Linux上鍊接需要rt庫,否則測不了時間。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章