Open geektutu opened 3 years ago
你能看下下面的代码,为什么使用读写锁比互斥锁执行的时间要长2倍?
这两个测试用例,代码唯一的区别就是var mutex sync.Mutex
和var mutex sync.RWMutex
// 使用互斥锁
// 耗时大概3秒
func TestSharedVariablesConcurrentlyTest2(t *testing.T) {
var amount int
var mutex sync.Mutex
defer func(t time.Time) {
fmt.Println(float64(time.Now().UnixNano() - t.UnixNano()) / 1e9)
}(time.Now())
waiting := make(chan struct{})
//mutex = &sync.Mutex{}
go func(){
for i:=0; i < 100000000; i++{
//t.Log("a")
mutex.Lock()
amount++
mutex.Unlock()
}
waiting <- struct{}{}
}()
for i:=0; i < 100000000; i++{
//t.Log("b")
mutex.Lock()
amount--
mutex.Unlock()
}
<-waiting
fmt.Println(amount) // 最后查看余额
}
// 使用读写锁
// 耗时大概6秒
func TestSharedVariablesConcurrentlyTest3(t *testing.T) {
var amount int
var mutex sync.RWMutex
defer func(t time.Time) {
fmt.Println(float64(time.Now().UnixNano() - t.UnixNano()) / 1e9)
}(time.Now())
waiting := make(chan struct{})
//mutex = sync.RWMutex{}
go func(){
for i:=0; i < 100000000; i++{
//t.Log("a")
mutex.Lock()
amount++
mutex.Unlock()
}
waiting <- struct{}{}
}()
for i:=0; i < 100000000; i++{
//t.Log("b")
mutex.Lock()
amount--
mutex.Unlock()
}
<-waiting
fmt.Println(amount) // 最后查看余额
}
@GanZhiXiong 你能看下下面的代码,为什么使用读写锁比互斥锁执行的时间要长2倍? 这两个测试用例,代码唯一的区别就是
var mutex sync.Mutex
和var mutex sync.RWMutex
// 使用互斥锁 // 耗时大概3秒 func TestSharedVariablesConcurrentlyTest2(t *testing.T) { var amount int var mutex sync.Mutex defer func(t time.Time) { fmt.Println(float64(time.Now().UnixNano() - t.UnixNano()) / 1e9) }(time.Now()) waiting := make(chan struct{}) //mutex = &sync.Mutex{} go func(){ for i:=0; i < 100000000; i++{ //t.Log("a") mutex.Lock() amount++ mutex.Unlock() } waiting <- struct{}{} }() for i:=0; i < 100000000; i++{ //t.Log("b") mutex.Lock() amount-- mutex.Unlock() } <-waiting fmt.Println(amount) // 最后查看余额 } // 使用读写锁 // 耗时大概6秒 func TestSharedVariablesConcurrentlyTest3(t *testing.T) { var amount int var mutex sync.RWMutex defer func(t time.Time) { fmt.Println(float64(time.Now().UnixNano() - t.UnixNano()) / 1e9) }(time.Now()) waiting := make(chan struct{}) //mutex = sync.RWMutex{} go func(){ for i:=0; i < 100000000; i++{ //t.Log("a") mutex.Lock() amount++ mutex.Unlock() } waiting <- struct{}{} }() for i:=0; i < 100000000; i++{ //t.Log("b") mutex.Lock() amount-- mutex.Unlock() } <-waiting fmt.Println(amount) // 最后查看余额 }
兄弟,你这个问题较多哦。。 1、读写锁读写锁,读写分离,你amount++/amout--都是写,还测试啥哦。 2、读写锁的读加锁解锁用的是 RLock()和RUnlock(),不是Lock()和Unlock() 3、实际的读写操作都是有操作延时的,不可能像测试代码里只做个++或者--,或者是:_ = amout。所以应该用time.sleep()模拟延时,比如1微秒。 4、读写锁的建立实际上也是要消耗cpu时间的,这个开销比互斥锁稍微多一点点。 5、读写锁面对的情况实际上是读要远大于写,比如写100次,读要几千次。
我本地测试下来同样的代码跟你的结果差异很大,这是为啥呀?是不是因为golang的版本不一样导致的呀? 实验结果如下: /usr/local/Cellar/go/1.16.2/libexec/bin/go test -v ./... -bench . -run ^$ goos: darwin goarch: amd64 pkg: example cpu: Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz BenchmarkReadMore BenchmarkReadMore-4 136 8415824 ns/op BenchmarkReadMoreRW BenchmarkReadMoreRW-4 2640 457446 ns/op BenchmarkWriteMore BenchmarkWriteMore-4 140 8112753 ns/op BenchmarkWriteMoreRW BenchmarkWriteMoreRW-4 2245 473042 ns/op BenchmarkEqual BenchmarkEqual-4 147 8295812 ns/op BenchmarkEqualRW BenchmarkEqualRW-4 2433 446097 ns/op PASS ok example 10.558s
Process finished with the exit code 0
同样的代码,为什么在我电脑上运行了将近70秒。。。都快测不出两种锁的差距来了 I7-8700 12核看比貌似比文中的8核快吧,楼上的I5-5257U为啥也比我快 操作系统的差异吗?
@haima96 同样的代码,为什么在我电脑上运行了将近70秒。。。都快测不出两种锁的差距来了 I7-8700 12核看比貌似比文中的8核快吧,楼上的I5-5257U为啥也比我快 操作系统的差异吗?
go version go1.17.6 贴两个我在本地windows下和本地虚拟机centos7下情况,应该是操作系统的差异导致的问题 ''' goos: windows goarch: amd64 pkg: wp20220225 cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz BenchmarkReadMore BenchmarkReadMore-12 1 1738722700 ns/op BenchmarkReadMoreRW BenchmarkReadMoreRW-12 6 178910700 ns/op BenchmarkWriteMore BenchmarkWriteMore-12 1 1724833800 ns/op BenchmarkWriteMoreRW BenchmarkWriteMoreRW-12 1 1566875800 ns/op BenchmarkEqual BenchmarkEqual-12 1 1719672300 ns/op BenchmarkEqualRW BenchmarkEqualRW-12 2 886586600 ns/op PASS ''' ''' goos: linux goarch: amd64 pkg: wp20220225 cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz BenchmarkReadMore-12 45 31306217 ns/op BenchmarkReadMoreRW-12 322 13520457 ns/op BenchmarkWriteMore-12 25 119642091 ns/op BenchmarkWriteMoreRW-12 33 64905106 ns/op BenchmarkEqual-12 42 92607716 ns/op BenchmarkEqualRW-12 80 47145911 ns/op PASS ok wp20220225 21.181s '''
https://geektutu.com/post/hpg-mutex.html
Go 语言/golang 高性能编程,Go 语言进阶教程,Go 语言高性能编程(high performance go)。介绍了读写锁(sync.RWMutex)和互斥锁(sync.Mutex)在不同的读写比情况下的性能开销。