golang 多协程操作同一个 map 的方案哪个好 ??

2019-08-30 17:31:25 +08:00
 dafsic

多个协程读写 map,读多写少。(就是定时加载配置) 现在的方式是定义一个指针指向 map,tM = *map[int]*sT。

然后读的时候,原子操作 load 这个指针: rM := (*map[int]*sT)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&tM))))

写的时候,先创建一个 map ( tmp ),填好信息后,然后再原子操作: atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&tM)), unsafe.Pointer(&tmp))。

除此之外,知道还有读写锁,sync.Map ,atomic.Value,不知道哪个性能最好?(即读的时候要快,因为有好多数据要通过这个 map 匹配)

另外,如果是读写差不多的情况下,是不是 sync.Map 最合适?

5897 次点击
所在节点    Go 编程语言
18 条回复
cloverstd
2019-08-30 17:32:54 +08:00
sync.Map 适合你的描述
dafsic
2019-08-30 17:45:50 +08:00
@cloverstd 不知道 sync.Map 是怎么实现的,但肯定有一些同步的判断吧,所以每次读都会比正常的 map 要慢一点,数据一多,就会慢的多了。这样理解对不?
polythene
2019-08-30 17:45:52 +08:00
这种情况的话,是 atomic.Value 最好,官方的示例程序就是你这里的场景。
http://blog.betacat.io/post/golang-atomic-value-exploration/
zzn
2019-08-30 17:53:42 +08:00
大多数时候加个锁并没有想象中那么慢,特别是本来就是读多的场景
dafsic
2019-08-30 18:02:08 +08:00
@polythene 之前看到过,想的是,每次读都要 load 一下,肯定不能比我一个原子操作还快吧。所以没用,当然这只是想的,没经过验证,不会基测。。。
dafsic
2019-08-30 18:07:54 +08:00
@zzn 现在 3 分钟内,150 万次读这个 map,如果每次读都加一个读锁,感觉开销有点大啊。也并没有要求那么高,数据来的比较集中,但有 kafka 做缓冲,所以可以慢点也没事,只是我想找一个性能最好的方式。
lishunan246
2019-08-30 18:22:36 +08:00
每个 goroutine 每秒检查一次配置有没有更新就行了,没有必要跑一次读一次。
hellodudu86
2019-08-30 18:54:59 +08:00
sync.Map 最省心,缺点是没法用 len,也没法获取 size,只能在 Range 里面自己计数。
hellodudu86
2019-08-30 18:56:27 +08:00
用内建 map 读多写少的情况最好还是 sync.RWMutex
boob
2019-08-31 11:01:33 +08:00
@dafsic sync.map 比你快,大牛单手写的代码,用的是 cache,大部分情况不加锁的,c++,Java 新官方都开始学习这个
boob
2019-08-31 11:11:21 +08:00
标准问题尽量用 STL,如果你的平均性能超过 STL,直接入选 golang 技术委员会,
reus
2019-09-01 10:58:21 +08:00
写代码测试一下不就知道了。
dafsic
2019-09-02 09:53:28 +08:00
@boob 标准库未必就是性能最佳吧,就说 json,你用的是标准库中的?另外,sync.map 肯定不是为了多读少写场景设计的,如果说是 atomic.Value 到是,这个也是无锁的,看了他的实现,里面用了原子操作,还有判断逻辑,与内置的 map 比肯定差。
dafsic
2019-09-02 09:59:08 +08:00
@reus 实话,真不会测试。研究研究也应该能会,想着这个问题应该都有遇到过,如果别人梳理过,系统的测试过,更好。
tourist2018
2019-09-02 11:16:31 +08:00
sync.Map
sxfscool
2019-09-05 08:39:57 +08:00
@dafsic testing.B 了解以下
javapythongo
2019-09-05 10:28:22 +08:00
用读写锁应该可以把
dafsic
2019-10-09 13:02:00 +08:00
@javapythongo 可以是都可以的,我想要性能最好的,读写锁应该是性能最差的。现在懒得去基测,等有遇到问题再研究。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/596606

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX