zoukankan      html  css  js  c++  java
  • golang 并发程序写入map两种实现方式sync.Mutex和chan的效率对比

    golang原生的数据结构map,由于是通过hash方式实现的,不支持并发写入,但是在golang很多并发场景中,不可避免的需要写入map,下面介绍两种解决map并发写入的实现方式:

    1. sync.Mutex互斥锁(通过加锁解锁解决map不能并发写入的问题)
    2. chan (通过管道来解决map并发的问题),chan的存在完美解决goroutine之间的通信以及数据race问题,但是它的性能如何呢,下面让我们来测一下

    首先先上代码:

    package main

    import (
    "testing"
    "sync"
    )

    func BenchmarkTest(b *testing.B) {
    var m = make(map[int]int, 10000)
    var mu = &sync.Mutex{}
    var c = make(chan int, 200)
    var w = &sync.WaitGroup{}

    w.Add(b.N)
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    c <- 1
    go func(index int) {
    mu.Lock()
    m[index] = 0
    mu.Unlock()
    w.Done()
    <- c
    }(i)
    }
    w.Wait()
    }

    func BenchmarkTestBlock(b *testing.B) {
    var m = make(map[int]int, 10000)
    var c = make(chan int, 200)
    var dataChan = make(chan int, 200)
    var w = &sync.WaitGroup{}

    w.Add(b.N+1)
    go func() {
    for i := 0; i < b.N; i++ {
    m[<- dataChan] = 0
    }
    w.Done()
    }()

    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    c<-1
    go func(index int) {
    dataChan <- index
    w.Done()
    <-c
    }(i)
    }
    w.Wait()
    }

    代码很简洁,我就不多解释了。

    看一下执行效率    

    可以看到,chan的实现方式其性能并不理想,比sync.Mutex的实现方式的效率低了大约25%左右。 

    chan的效率为什么不理想呢,其实原因很简单,下面看一下它的数据结构就一目了然了

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        s := "hello, world!"
        b := []byte(s)
        c := make(chan int, 1)
        c<-1
        fmt.Println(s, b, <-c)
    }
    

    我们可以看到channel的实现是通过互斥锁和数组的方式实现的,而且还有一些其他字段的同步,因此它的效率是不会比直接用互斥锁更快的。

    很多看上去很高端很简洁的东西,其实是编辑器和runtime在后面为我们码农实现,当然与之相来是额外的内存和时间开销。

  • 相关阅读:
    SQL Server ->> 生成代码把表字段从NULL改为NOT NULL
    Hadoop ->> MapReduce编程模型
    SQL Server ->> 建立linked server到Azure SQL Server
    SQL Server ->> 存储过程sp_rename重命名数据对象
    SQL Server ->> CLR存储过程枚举目录文件并返回结果集
    SQL Server ->> 查看SQL Server备份历史
    SQL Server ->> 生成时间类型的Partition Function和Partition Scheme代码
    SQL Server ->> CLR编程问题汇总
    Hadoop ->> Name node/Data node和Job tracker/Task tracker的区别
    Hadoop ->> Hadoop是什么?
  • 原文地址:https://www.cnblogs.com/shuiyuejiangnan/p/9722791.html
Copyright © 2011-2022 走看看