golang读写锁与互斥锁的性能比较

长时间来一直以为在读多写少的场景下,读写锁性能必然优于互斥锁,然而情况恰恰相反

不废话了,先上一段测试代码

func main() {
   var w = &sync.WaitGroup{}
   var num = 50000000
   var c = make(chan int, 3000)

   var rwmutexTmp = newRwmutex()
   w.Add(num)
   t1 := time.Now()
   for i := 0; i < num; i++ {
      c <- 0
      go func(index int) {
         defer w.Done()
         _ = rwmutexTmp.get(index)
         //fmt.Println(value)
         <-c
      }(i)
   }
   w.Wait()
   t2 := time.Now()

   var mutexTmp = newMutex()
   w.Add(num)
   t3 := time.Now()
   for i := 0; i < num; i++ {
      c <- 0
      go func(index int) {
         defer w.Done()
         t := mutexTmp.get()
         _, _ = t[index]
         //fmt.Println(ok)
         <-c
      }(i)
   }
   w.Wait()
   t4 := time.Now()
   fmt.Println("rwmutex cost:", t2.Sub(t1).String())
   fmt.Println("mutex cost:", t4.Sub(t3).String())
}

type rwmutex struct {
   mu     *sync.RWMutex
   ipmap map[int]int
}

type mutex struct {
   mu  *sync.Mutex
   ipmap map[int]int
}

func (t *rwmutex) get(i int) int {
   t.mu.RLock()
   defer t.mu.RUnlock()

   return t.ipmap[i]
}


func (t *mutex) get() map[int]int {
   t.mu.Lock()
   defer t.mu.Unlock()

   return t.ipmap
}

func newRwmutex() *rwmutex {
   var t = &rwmutex{}
   t.mu = &sync.RWMutex{}
   t.ipmap = make(map[int]int, 100)

   for i := 0; i < 100; i++ {
      t.ipmap[i] = 0
   }
   return t
}

func newMutex() *mutex {
   var t = &mutex{}
   t.mu = &sync.Mutex{}
   t.ipmap = make(map[int]int, 100)

   for i := 0; i < 100; i++ {
      t.ipmap[i] = 0
   }
   return t
}

各加锁5000万次,时间比较如下:

go run test_rwmutex_mutex.go

rwmutex cost: 22.403487195s

mutex cost: 21.636404963s

go run test_rwmutex_mutex.go

rwmutex cost: 22.3359224s

mutex cost: 21.931208658s

在某些场景下,互斥锁要比读写锁更快!!!