写入具有多个 goroutines 的互斥映射是否比一个更快?以及为什么



我有一个SyncMap定义如下:

type SyncMap struct {
    sync.Mutex
    Map map[int]string
}

而且,现在我使用两种方式写入它,一种是goroutine和多个goroutines,互斥代码如下:

smap := SyncMap{}
smap.Map = make(map[int]string)
t1 := time.Now()
for i := 0; i < 10000; i++ {
    smap.Map[i] = strconv.Itoa(i)
}
elapsed := time.Since(t1)
fmt.Println("t1 elapsed", elapsed)
s2map := SyncMap{}
s2map.Map = make(map[int]string)
t2 := time.Now()
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
    defer wg.Done()
    for i := 0; i < 5000; i++ {
        s2map.Lock()
        s2map.Map[i] = strconv.Itoa(i)
        s2map.Unlock()
    }
}()
go func() {
    defer wg.Done()
    for i := 5000; i < 10000; i++ {
        s2map.Lock()
        s2map.Map[i] = strconv.Itoa(i)
        s2map.Unlock()
    }
}()
wg.Wait()
elapsed2 := time.Since(t2)
fmt.Println("t2 elapsed", elapsed2)

输出如下:

t1 elapsed 5.0363ms
t2 elapsed 5.9353ms

尝试服务时间,t1 总是比 t2 快。所以,我的问题就像标题所说。

我能理解这是由于互斥锁的消耗吗?在这种情况下是同步映射或同步。go包中的map只是为了安全地编写goroutine而设计的,而不是为了效率?在使用多个goroutine编写地图时,有没有办法提高效率?

谢谢~

这相当简单。 在第二种情况下,对于 2 个 goroutine,由于互斥锁,一次只能有一个 goroutines 写入映射。 因此,这实际上与仅按顺序使用一个goroutine执行没有太大区别。在任何给定时间,只有一个goroutine会做任何事情。 计数器和循环根本不消耗太多时间,因此基本上可以忽略它们,大部分时间都是映射写入。

但是,您还需要支付锁争用的额外成本,以及 10,000 次锁定和解锁操作,这些操作的成本相当高。 所以这意味着总体上它会更慢。

总之,如果在任何给定时间只有一个 goroutine,使用更多的 goroutines 不会加快速度。

为了提高效率,请使用更好的地图,例如此或此。 您创建的映射根本不允许并发。

相关内容

  • 没有找到相关文章

最新更新