标签:map start Lock 读写 sync 互斥 time go dd
机器及环境:
代码编辑器:Visual Studio Code
读写锁:sync.RWMutex
互斥锁:sync.Mutex{}
Go版本:go version go1.16 windows/amd64
测试:
一共7个协程,6个协程用于读map中的数据,1个协程用于写入map数据,计算所有协程完成工作后的总时间,列出以下表格,
以下所有时间单位为:秒
循环次数(每个协程) | 读写map全加Lock锁[RWMutex] | 读map加RLock 锁,写map加Lock锁[RWMutex] | 读写map加Lock锁[Mutex] |
---|---|---|---|
1千 | 0.0029211 | 0.0019989 | 0.0030007 |
1万 | 0.0132632 | 0.0110304 | 0.0072183 |
10万 | 0.1046344 | 0.1441308 | 0.0703651 |
100万 | 0.9638649 | 1.0364884 | 0.7389124 |
500万 | 4.7609394 | 4.4947625 | 3.6153809 |
1000万 | 9.4329156 | 9.4223508 | 7.5078914 |
2000万 | 20.023867 | 18.038904 | 15.124100 |
3000万 | 29.065017 | 26.220366 | 21.868782 |
1亿 | 95.763412 | 95.097358 | 69.762031 |
结论:
- 互斥锁的效率比读写锁要好
- 在读写锁中,读map加Rlock,写map加Lock锁,表现会更好一些
以下是测试代码:
package cmd
import (
"fmt"
"sync"
"time"
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(bufferCmd)
}
const Times = 1_0000_0000
var bufferCmd = &cobra.Command{
Use: "buffert",
Run: func(cmd *cobra.Command, args []string) {
dd := NewDianDian()
w := sync.WaitGroup{}
start := time.Now()
w.Add(7)
for i := 0; i < 6; i++ {
go R(dd, &w, i)
}
go W(dd, &w)
w.Wait()
fmt.Printf("total: %v\n", time.Now().Sub(start).Seconds())
},
}
type diandian struct {
M map[string]int
RWLock sync.RWMutex
Lock sync.Mutex
}
func NewDianDian() *diandian {
dd := &diandian{}
dd.M = map[string]int{}
dd.Lock = sync.Mutex{}
dd.RWLock = sync.RWMutex{}
return dd
}
func (dd *diandian) Write(name string, value int) {
// sync.RWMutex{}
dd.RWLock.Lock()
defer dd.RWLock.Unlock()
// sync.Mutex{}
// dd.Lock.Lock()
// defer dd.Lock.Unlock()
dd.M[name] = value
}
func (dd *diandian) Read(name string) int {
// sync.RWMutex{}
// dd.RWLock.RLock()
// defer dd.RWLock.RUnlock()
dd.RWLock.Lock()
defer dd.RWLock.Unlock()
// sync.Mutex{}
// dd.Lock.Lock()
// defer dd.Lock.Unlock()
if value, ok := dd.M[name]; ok {
return value
}
return 0
}
func R(dd *diandian, w *sync.WaitGroup, n int) {
defer w.Done()
start := time.Now()
for i := 0; i <= Times; i++ {
dd.Read("start")
}
fmt.Printf("time[R-%d]: %v\n", n, time.Now().Sub(start).Seconds())
}
func W(dd *diandian, w *sync.WaitGroup) {
defer w.Done()
start := time.Now()
for i := 0; i <= Times; i++ {
dd.Write("start", 1)
}
fmt.Printf("time[W]: %v\n", time.Now().Sub(start).Seconds())
}
标签:map,start,Lock,读写,sync,互斥,time,go,dd 来源: https://blog.csdn.net/weixin_43620243/article/details/115064680
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。