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