火影 发表于 2024-5-18 05:29:56

【先容一个组件】go: Copy-On-Write map,对读极多和写极少的场景做优化

作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!

[*]cnblogs博客
[*]zhihu
[*]Github
[*]公众号:不苟言笑的瞎扯
https://img2022.cnblogs.com/blog/1457949/202202/1457949-20220216153819145-1193738712.png
代码请看:https://github.com/ahfuzhang/cowmap
有这样一种场景:数据量不多的map,在使用中读极多写极少。为了在这种场景下做极致的优化,我实现了 copy-on-write 的map:
实在现原理为:全部的读都可以不加锁的并发读取,一旦需要写,则 copy 一份原来的map,在备份上修改,然后通过原子操纵把指针切换到新的对象上。
我对比了CowMap(Copy-On-Write Map) 和 sync.Map , 以及普通map + 读写锁三种方式的性能:
Read-write rateTypens/op99.99% : 0.01%CowMap4.64999.99% : 0.01%map + sync.RWMutex187.599.99% : 0.01%sync.Map15.0699.90% : 0.10%CowMap32.7099.90% : 0.10%map + sync.RWMutex159.999.90% : 0.10%sync.Map14.0899.00% : 1.00%CowMap303.699.00% : 1.00%map + sync.RWMutex105.799.00% : 1.00%sync.Map14.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.
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【先容一个组件】go: Copy-On-Write map,对读极多和写极少的场景做优化