這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
很多時候效能問題總是發生在一些不起眼的地方。最近做一個效能問題分析的時候發現,一個函數裡面使用由於字串拼接產生的臨時字串導致記憶體上漲了40%(120G 記憶體的機器),而這些臨時字串給 GC 也帶來了非常大的負擔,成為主要的效能瓶頸,而這些字串作為 map 的 key,又必須要拼接,所以想到了直接使用 hash 後的值作為 map 的 key,而這個 hash 值使用累加 hash 計算得出。
所謂累加 hash,就是對字串的 hash 可以分為任意多段,對每一段連續 hash,結果累加,對於任意一種分段方式,最後能得到一致的 hash 結果,比如:H.hash("hello world")
, H.hash("hello").hash(" ").hash("world")
, H.hash("hello wo").hash("rld)"
這些結果最後都應該是一致的,利用這個特性,就能做到對多個字串雜湊而不用拼接
BKDR hash 實現
type StringHasherBKDR uint64// NewStringHasherBKDR 建立一個新的 Hasherfunc NewStringHasherBKDR() StringHasherBKDR { return StringHasherBKDR(0)}// AddStr 增加一個字串func (bkdr StringHasherBKDR) AddStr(str string) StringHasherBKDR { val := uint64(bkdr) for i := 0; i < len(str); i++ { val = val*131 + uint64(str[i]) } return StringHasherBKDR(val)}// AddInt 添加一個 int 值func (bkdr StringHasherBKDR) AddInt(i uint64) StringHasherBKDR { val := uint64(bkdr) val = val*131 + i return StringHasherBKDR(val)}// Val 轉成 uint64 的值func (bkdr StringHasherBKDR) Val() uint64 { return uint64(bkdr)}
使用上也很簡單
hasher := NewStringHasherBKDR()So(hasher.AddStr("hello world").Val(), ShouldEqual, hasher.AddStr("hello").AddStr(" ").AddStr("world").Val())
參考連結
- 代碼地址: https://github.com/hatlonely/...
轉載請註明出處
本文連結:http://www.hatlonely.com/2018...