作者:張富春(ahfuzhang),轉載時請註明作者和引用鏈接,謝謝! cnblogs博客 zhihu Github 公眾號:一本正經的瞎扯 代碼請看:https://github.com/ahfuzhang/cowmap 有這樣一種場景:數據量不多的map,在使用中讀極多寫極少。為了在這種場景下做 ...
作者:張富春(ahfuzhang),轉載時請註明作者和引用鏈接,謝謝!
代碼請看:https://github.com/ahfuzhang/cowmap
有這樣一種場景:數據量不多的map,在使用中讀極多寫極少。為了在這種場景下做極致的優化,我實現了 copy-on-write 的map:
其實現原理為:所有的讀都可以不加鎖的併發讀取,一旦需要寫,則 copy 一份原來的map,在備份上修改,然後通過原子操作把指針切換到新的對象上。
我對比了CowMap(Copy-On-Write Map) 和 sync.Map , 以及普通map + 讀寫鎖三種方式的性能:
Read-write rate | Type | ns/op |
---|---|---|
99.99% : 0.01% | CowMap | 4.649 |
99.99% : 0.01% | map + sync.RWMutex | 187.5 |
99.99% : 0.01% | sync.Map | 15.06 |
99.90% : 0.10% | CowMap | 32.70 |
99.90% : 0.10% | map + sync.RWMutex | 159.9 |
99.90% : 0.10% | sync.Map | 14.08 |
99.00% : 1.00% | CowMap | 303.6 |
99.00% : 1.00% | map + sync.RWMutex | 105.7 |
99.00% : 1.00% | sync.Map | 14.08 |
因此,當讀的比例超過 99.99%時,CowMap
是 sync.Map
的 3.24 倍。是 map+sync.RWMutex
的 40.33 倍。
不過我認為更好的實現方法,還是應該參考 rust hashbrown 的實現(see: 《Swisstable:C++中比std::unordered_map更快的hash表》),這樣有可能實現這樣一些優化:
- 因為hash的結構是平坦的數組,理論上在不擴容和縮容的前提下,讀寫都能做到無鎖
- 使用simd指令集來搜索位置,能夠提供更好的查找速度。
Have Fun.