V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
dafsic
V2EX  ›  Go 编程语言

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

  •  
  •   dafsic · 2019-08-30 17:31:25 +08:00 · 5882 次点击
    这是一个创建于 1903 天前的主题,其中的信息可能已经有所发展或是发生改变。

    多个协程读写 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 最合适?

    18 条回复    2019-10-09 13:02:00 +08:00
    cloverstd
        1
    cloverstd  
       2019-08-30 17:32:54 +08:00   ❤️ 1
    sync.Map 适合你的描述
    dafsic
        2
    dafsic  
    OP
       2019-08-30 17:45:50 +08:00
    @cloverstd 不知道 sync.Map 是怎么实现的,但肯定有一些同步的判断吧,所以每次读都会比正常的 map 要慢一点,数据一多,就会慢的多了。这样理解对不?
    polythene
        3
    polythene  
       2019-08-30 17:45:52 +08:00
    这种情况的话,是 atomic.Value 最好,官方的示例程序就是你这里的场景。
    http://blog.betacat.io/post/golang-atomic-value-exploration/
    zzn
        4
    zzn  
       2019-08-30 17:53:42 +08:00
    大多数时候加个锁并没有想象中那么慢,特别是本来就是读多的场景
    dafsic
        5
    dafsic  
    OP
       2019-08-30 18:02:08 +08:00
    @polythene 之前看到过,想的是,每次读都要 load 一下,肯定不能比我一个原子操作还快吧。所以没用,当然这只是想的,没经过验证,不会基测。。。
    dafsic
        6
    dafsic  
    OP
       2019-08-30 18:07:54 +08:00
    @zzn 现在 3 分钟内,150 万次读这个 map,如果每次读都加一个读锁,感觉开销有点大啊。也并没有要求那么高,数据来的比较集中,但有 kafka 做缓冲,所以可以慢点也没事,只是我想找一个性能最好的方式。
    lishunan246
        7
    lishunan246  
       2019-08-30 18:22:36 +08:00 via Android
    每个 goroutine 每秒检查一次配置有没有更新就行了,没有必要跑一次读一次。
    hellodudu86
        8
    hellodudu86  
       2019-08-30 18:54:59 +08:00
    sync.Map 最省心,缺点是没法用 len,也没法获取 size,只能在 Range 里面自己计数。
    hellodudu86
        9
    hellodudu86  
       2019-08-30 18:56:27 +08:00
    用内建 map 读多写少的情况最好还是 sync.RWMutex
    boob
        10
    boob  
       2019-08-31 11:01:33 +08:00 via Android
    @dafsic sync.map 比你快,大牛单手写的代码,用的是 cache,大部分情况不加锁的,c++,Java 新官方都开始学习这个
    boob
        11
    boob  
       2019-08-31 11:11:21 +08:00 via Android
    标准问题尽量用 STL,如果你的平均性能超过 STL,直接入选 golang 技术委员会,
    reus
        12
    reus  
       2019-09-01 10:58:21 +08:00
    写代码测试一下不就知道了。
    dafsic
        13
    dafsic  
    OP
       2019-09-02 09:53:28 +08:00
    @boob 标准库未必就是性能最佳吧,就说 json,你用的是标准库中的?另外,sync.map 肯定不是为了多读少写场景设计的,如果说是 atomic.Value 到是,这个也是无锁的,看了他的实现,里面用了原子操作,还有判断逻辑,与内置的 map 比肯定差。
    dafsic
        14
    dafsic  
    OP
       2019-09-02 09:59:08 +08:00
    @reus 实话,真不会测试。研究研究也应该能会,想着这个问题应该都有遇到过,如果别人梳理过,系统的测试过,更好。
    tourist2018
        15
    tourist2018  
       2019-09-02 11:16:31 +08:00
    sync.Map
    sxfscool
        16
    sxfscool  
       2019-09-05 08:39:57 +08:00
    @dafsic testing.B 了解以下
    javapythongo
        17
    javapythongo  
       2019-09-05 10:28:22 +08:00
    用读写锁应该可以把
    dafsic
        18
    dafsic  
    OP
       2019-10-09 13:02:00 +08:00
    @javapythongo 可以是都可以的,我想要性能最好的,读写锁应该是性能最差的。现在懒得去基测,等有遇到问题再研究。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5286 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 03:46 · PVG 11:46 · LAX 19:46 · JFK 22:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.