go锁与chan的性能对比
锁的作用
- 解决并发安全问题,流程控制等
chan 的作用
- 线程通信(数据传输), 并发安全,流程控制
golang的数据并不是并发安全的
- golang的变量并不是并发安全的
- 锁与chan都可以解决并发安全的问题,那么应该如何选择?
// 锁
func LockServe(lock *sync.Mutex) {
lock.Lock()
defer lock.Unlock()
//todo: 业务逻辑
//...
}
// channel 读(单线程)
func ChanRead(ch chan struct{}) {
for {
<-ch
}
}
// channel 读(多线程)
func ChanReadMulti(ch chan struct{}) {
for i := 0; i < 100; i++ {
go ChanRead(ch)
}
}
// channel 写
func ChanWrite(ch chan struct{}) {
ch <- struct{}{}
}
// 读写锁性能(单线程)
func BenchmarkLock(b *testing.B) {
lock := &sync.Mutex{}
//开始计时
b.ResetTimer()
for i := 0; i < b.N; i++ {
LockServe(lock)
}
//BenchmarkLock-8 128537480 9.141 ns/op 0 B/op
}
// 读写锁性能(多线程)
func BenchmarkLockMulti(b *testing.B) {
lock := &sync.Mutex{}
//开始计时
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
LockServe(lock)
}
})
//BenchmarkLockMulti-8 15528596 77.23 ns/op 0 B/op
}
// channel 通信(单线程)
func BenchmarkChanRead(b *testing.B) {
ch := make(chan struct{}, 9)
defer close(ch)
go ChanRead(ch)
//开始计时
b.ResetTimer()
for i := 0; i < b.N; i++ {
ChanWrite(ch)
}
//BenchmarkChanRead-8 21222759 55.43 ns/op 0 B/op
}
// channel 通信(多线程读)
func BenchmarkChanReadMulti(b *testing.B) {
ch := make(chan struct{}, 9)
defer close(ch)
go ChanReadMulti(ch)
//开始计时
b.ResetTimer()
for i := 0; i < b.N; i++ {
ChanWrite(ch)
}
//BenchmarkChanReadMulti-8 4238251 260.1 ns/op 0
}
// channel 通信(多线程写)
func BenchmarkChanWrite(b *testing.B) {
ch := make(chan struct{}, 1000)
defer close(ch)
go ChanRead(ch)
//开始计时
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
ChanWrite(ch)
}
})
// BenchmarkChanWrite-8 5177377 299.1 ns/op 0 B/op
}
// channel 通信(多线程读写)
func BenchmarkChanReadWrite(b *testing.B) {
ch := make(chan struct{}, 1000)
defer close(ch)
go ChanReadMulti(ch)
//开始计时
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
ChanWrite(ch)
}
})
// BenchmarkChanReadWrite-8 558490 3862 ns/op 0 B/op 0 allocs/op
}
在单线程下:锁 :128537480 qps; chan: 21222759 qps
多线程下: 锁 : 15528596 qps; chan : 5177377 qps
单论性能,锁要比chan更加优秀
为什么锁的性能更加优秀?
- 锁是原子的操作,消耗更低,性能更高
- chan的底层有更加复杂的通信逻辑,消耗较大,在多线程情况下相差3倍
如何选择?
- 在之需要解决并发问题或者流程控制的情况下优先考虑锁,因为性能更高
- 如果需要线程通信 以及 数据传输使用chan
原文地址:https://blog.csdn.net/dengjiayue/article/details/144310508
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!