golang sync.Map分析,设计思想:读多写少
sync.Map
结构体
type Map struct { mu Mutex read atomic.Value // readOnly dirty map[interface{}]*entry misses int }
sync.Map设计思想(读多写少)
sync.Map 采用“空间换时间”的机制,sync.Map结构体冗余了两个数据结构,分别是:read
和dirty
;
写值的时候得通过 Store 方法,读的时候使用方法 Load 来读取。
与map+RWMutex的实现并发的方式相比,减少了加锁对性能的影响。
它做了一些优化:可以无锁访问read map,而且会优先操作read map,倘若只操作rede map就可以满足要求,那就不用去操作write map(dirty)。
所以在某些特定场景中它发生锁竞争的频率会远远小于map + RWMutex的实现方式。
优点:适合读多写少的场景;
缺点:如果是写多的场景,会导致read map缓存失效,需要加锁,冲突突变,性能急剧下降。
map并发写就用map+sync.Mutex效率更高,sync.Map性能比较低1580ns/op
珂哥讲技术:
sync.Map有两个数组,read数组和dirty数组(脏数组),写入map他会发现,read里面没有就写到dirty数组里面1:1,2:2 ,想读key=1的值发现read数组里面没有,加锁从dirty数组里面找,找到不到命中计数器++(miss计数器),当miss++>len(dirty),它就会把dirty里面的数据拷贝到read数组里面,然后把dirty里面的数据清理掉,读是不加锁特别快,
改写1:11,首先在read数组把11进行原子操作,数据交换,同时会在dirty数组里面写进去;写一个新的数据3会写到dirty数组里面,同样原理read的时候没有命中就去dirty数组里面数据拷贝到read数组里面,清理到dirty数组的全部数据 。所以为什么sync.Map读快是因为不加锁,写慢是因为加锁,同时在写的时候还会再去读一次read数组,造成时间消耗的比较多。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架