优化 Go 中的 map 并发存取

针对Catena时序存储引擎中的metricSource获取函数进行了优化。原函数在高并发下因锁竞争导致性能下降,通过引入RWMutex改进,使得读操作不受锁影响,写操作保持同步,有效提升多协程下的插入速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

地址:88250.b3log.org/optimizing-…

Catena (时序存储引擎)中有一个函数的实现备受争议,它从 map 中根据指定的 name 获取一个 metricSource。每一次插入操作都会至少调用一次这个函数,现实场景中该函数调用更是频繁,并且是跨多个协程的,因此我们必须要考虑同步。

该函数从 map[string]*metricSource 中根据指定的 name 获取一个指向 metricSource 的指针,如果获取不到则创建一个并返回。其中要注意的关键点是我们只会对这个 map 进行插入操作。

  1. var source *memorySource
  2. var present bool
  3. p.lock.Lock() // lock the mutex
  4. defer p.lock.Unlock() // unlock the mutex at the end
  5. if source, present = p.sources[name]; !present {
  6. // The source wasn't found, so we'll create it.
  7. source = &memorySource{
  8. name: name,
  9. metrics: map[string]*memoryMetric{},
  10. }
  11. // Insert the newly created *memorySource.
  12. p.sources[name] = source
  13. }
  14. 复制代码

经测试,该实现大约可以达到 1,400,000 插入/秒(通过协程并发调用,GOMAXPROCS 设置为 4)。看上去很快,但实际上它是慢于单个协程的,因为多个协程间存在锁竞争。

下面给出不存在竟态条件、线程安全,应该算是“正确”的版本了。使用了 RWMutex,读操作不会被锁,写操作保持同步。

  1. var source *memorySource
  2. var present bool
  3. p.lock.RLock()
  4. if source, present = p.sources[name]; !present {
  5. // The source wasn't found, so we'll create it.
  6. p.lock.RUnlock()
  7. p.lock.Lock()
  8. if source, present = p.sources[name]; !present {
  9. source = &memorySource{
  10. name: name,
  11. metrics: map[string]*memoryMetric{},
  12. }
  13. // Insert the newly created *memorySource.
  14. p.sources[name] = source
  15. }
  16. p.lock.Unlock()
  17. } else {
  18. p.lock.RUnlock()
  19. }
  20. 复制代码

转载于:https://juejin.im/post/5c25cac1e51d451be35e5bde

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他
点击体验
DeepSeekR1满血版
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回顶部