最近一直搞字串的雜湊尋找,有人推薦使用gperf的Perfect Hash,於是去調查了一下GPerf的使用方法。
gperf 下載 http://www.gnu.org/software/gperf/,ubuntu上可以直接sudo apt-get install gperf ,可能辦法不是最新的。
gperf 文檔 http://www.gnu.org/software/gperf/manual/gperf.html#Functions
我主要參考了《使用 gperf 實現高效的 C/C++ 命令列處理》。
gperf使用:
主要是declarations和keyword部分,如果只是單純的尋找字串是否存在,則不需要declarations部分,.gperf檔案中直接儲存雜湊表中的所有字串即可。但是雜湊表中一般都是key和value對,這樣的要在declaration部分聲明一個struct,然後兩個%%後是keyword。格式如下:
struct KeyValue{ const char * key;//第一個欄位必須是const char * int value; //可以有更多的value值 };%%key1,1key2,2key3,3
keyword部分如果首字元為%,該字串須用雙引號括起來,如%key,必須是“%key”。
然後使用gperf命令產生hpp檔案:
gperf -CGD -K key -L C++ -t xxx.gperf > perfecthash.hpp
產生的標頭檔中有Perfect_Hash的類,類名可以通過-Z選項修改。
類中有Hash函數,預設為hash(),可以通-H選項修改。
尋找函數是in_word_set(),用-N來修改。
-L指定程式設計語言。
如果有declaration部分,必須使用-t選項。
-K指定struct中關鍵字的名稱。
具體的原理不做詳細說明,Perfect Hash應該很快,沒有實際測試過。
問題:
gperf只是把.gperf檔案中的關鍵字使用結構體數組的形式存放在代碼檔案中,省去了檔案載入的時間,然而感覺這種做法只適合小規模的hash尋找,如參考中的C++命令列處理。對於我要處理的幾十萬或者上百萬的字串索引對,並不適合使用gperf來處理。
不知道是否有人處理過大規模的字串Hash尋找,是否有更好的解決方案,望請賜教,謝謝。