golang sync.Map和map+mutex性能比较

目录

 

测试环境

测试代码

运行指令

测试结果

结论


测试环境

goos: linux
goarch: amd64

go version go1.14 linux/amd64

Run on (8 X 2394.37 MHz CPU s)
CPU Caches:
  L1 Data 32 KiB (x8)
  L1 Instruction 32 KiB (x8)
  L2 Unified 4096 KiB (x8)
  L3 Unified 16384 KiB (x1)

测试代码

文件:src/benchmark/syncmap_test.go

参数说明:

iteTimes:每个go协和进行map操作次数

writePer:写占用的比例

mod:取模余数。没什么用。取-1时可以控制全都是读。取0时,writePer=1时可以控制都是写。

正如代码所示:有1/writePer的操作为写。

可以看出随着读比例升高,sync.map性能越来越好。

package main

import (
	"sync"
	"testing"
)

var iteTimes = 10000
var writePer = 10000
var mod = 1

func BenchmarkSyncMapGo(b *testing.B) {
	var mp sync.Map
	var wg sync.WaitGroup
	for i := 0; i < b.N; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			for j := 0; j < iteTimes; j++ {
				if i%writePer == mod {
					mp.Store(0, 0)
				} else {
					_, _ = mp.Load(0)
				}
			}

		}(i)
	}
	wg.Wait()
}
func BenchmarkMapGo(b *testing.B) {
	var mp = make(map[int]int)
	var wg sync.WaitGroup
	var lock sync.Mutex
	for i := 0; i < b.N; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()

			for j := 0; j < iteTimes; j++ {
				lock.Lock()
				if i%writePer == mod {
					mp[0] = 0
				} else {
					i = mp[0]
				}
				lock.Unlock()
			}
		}(i)
	}
	wg.Wait()
}

运行指令

go test -v  -bench=MapGo -count=1 -benchtime=2s   benchmark

测试结果

sync.Map和map+Mutex性能对比
测试序号说明writePermodsync.Map    ns/opmap  ns/opmap/sync.Map
1全写10437893122576520.515571495
21/2写2174278519570772.634782609
31/10写10120172017930328.888717034
41/20写201122396175805214.36363933
51/40写40191850174099518.9547632
61/50写50186850176810020.35808866
71/100写100172843176202224.18931126
81/500写500158097170902129.41668244
91/1000写1000157137174615130.56077498
101/5000写5000155446173628831.31493706
11只读的情况下xx-137198164808444.30571536
       

 

                                               

结论

sync.Map的性能高体现在读操作远多于写操作的时候。 极端情况下,只有读操作时,是普通map的性能的44.3倍。

反过来,如果是全写,没有读,那么sync.Map还不如加普通map+mutex锁呢。只有普通map性能的一半。

建议使用sync.Map时一定要考虑读定比例。当写操作只占总操作的<=1/10的时候,使用sync.Map性能会明显高很多。

 

 

更新了一版程序

加上main函数,可以更细的测量。

package main

import (
	"fmt"
	"testing"
)

func BenchmarkParam(b *testing.B) {
}

func TestMain(m *testing.M) {
	println("id  Map    SyncMap Map/SyncMap")
	testing.Benchmark(BenchmarkParam)
	for writePer = 1; writePer <= 1000; writePer++ {
		a := testing.Benchmark(BenchmarkMapGo)

		b := testing.Benchmark(BenchmarkSyncMapGo)
		fmt.Printf("%v  %v  %v  %.4f\n", writePer, a.NsPerOp(), b.NsPerOp(), float64(a.NsPerOp())/float64(b.NsPerOp()))
		if writePer > 100 {
			writePer += 9
		}
	}
}

曲线有振荡,不知道为什么。。。

 

 

 

 

idMapSyncMapMap/SyncMap
1158982842125630.3774
2182072310675171.7056
317342187664652.2626
419842787520762.6384
520146035867883.4333
620088304144564.8469
716922124486483.7718
820849875188374.0186
921112963808215.5441
1015903803831354.151
1119946453718545.3641
1219841633439635.7685
1321328233257896.5466
1419207033064716.2672
1516137493192775.0544
1619060713239295.8842
1717470822919705.9838
1819719532440488.0802
1919394152741367.0746
2020099973264696.1568
2120353162364768.6069
22229628721926110.4728
23235005120552511.4344
2421241742175239.7653
25213374119333111.0367
26214085014210915.0648
27213003713885715.3398
28214965010343220.7832
29216758510521120.6023
30215580911211819.228
31215615910948319.694
32216463310613420.3953
33215753411245219.1863
34212420812097617.5589
35237848619484712.2069
36236350319108812.3687
3723847559887824.1182
38230197618354012.5421
39232761716928313.7499
40236033915178915.5501
41236818917484913.5442
42232010614981715.4863
43234268811587020.2182
44236038010950421.5552
45233609016696113.9918
46235600716749914.0658
4723662408884926.6322
4821493848610724.9618
4921053808943123.5419
5021476928878624.1895
51216495414606614.8218
52231893415154915.3015
53230227614243816.1634
5421076968309825.364
5521617648501525.428
5621494208102626.5275
57229604014227116.1385
5821227658138626.0827
59233941912695918.4266
60236363313959316.9323
61233144713616117.1227
62233186913762316.9439
63240851513261818.1613
6423993929844724.3724
6521570378065026.7457
66220875913188516.7476
67227066013328417.0363
68230183310586721.7427
69223402812821217.4245
70225131112517217.9857
71217118012511917.3529
7221214597789727.2342
7321032987916926.5672
7423079547410531.1444
75215101110531320.4249
7621500437737727.7866
7721687147411729.2607
7821661597671328.2372
7921799687780328.0191
8022053327663028.779
8122194617496329.6074
8221609097339729.4414
8321615547917527.301
8421662637646028.332
85225153411081820.3174
86229066111292020.2857
87225096711199120.0995
88232813811078621.0147
89231159610668921.6667
9021990897761628.3329
91221342311130519.8861
92233310810984021.241
93231198910770321.4663
94234127410769021.7409
95228359311068220.632
96231743710633921.7929
97231531910597721.8474
98227396310441321.7785
99229575110846321.1662
100224396210558221.2533
101230945010520921.9511
11122187417024131.5875
12121658967067130.6476
13122979279563024.0294
14123092579394324.5815
15123291588851826.3128
16123099168978925.726
17123497168414327.9253
18123472508242528.4774
19123112348403627.5029
20122958246373036.0242
21121547276298034.2129
22121357936449433.1162
23121564016641232.4701
24121649476155735.1698
25121192976447932.868
26121383916224334.3555
27122825307541430.2667
28123167877467231.0262
29123520697217932.5866
30123029207247031.7776
31123212907263931.9565
32123350647068533.0348
33122630906112837.0222
34121450306150234.8774
35121721755985036.2937
36121279006094034.918
37121698826232934.8134
38122728566815533.3483
39123235026827434.032
40121793235960236.5646
41121613705915036.5405
42121344225884336.2732
43121539085790537.1973
44121408105914436.1966
45121543845993335.9465
46122500516184836.3803
47121146526166234.2942
48121286765768136.9043
49120996925890635.6448
50121631365930036.4778
51121965835912437.1521
52121284386008935.4214
53122211646093436.452
54121289075774236.8693
55121798295925236.7891
56121885145991536.527
57121055245688637.013
58121619306137335.2261
59121722555770437.6448
60121749095912336.7862
61121796065966536.5307
62121659625839737.0903
63121097006074634.7299
64121681046216834.8749
65122082965736038.4989
66121330435980635.666
67121533355869536.6869
68121725945705938.0763
69121814335740937.9981
70121300876166834.5412
71121235256210134.1947
72121264585971435.6107
73121955366200035.4119
74121082445640937.3742
75121611975829337.0747
76121636196061335.6956
77121291115781336.8275
78121752576344634.2852
79121602215859736.8657
80121462086005635.7368
81121492325652838.0207
82121625796143735.1999
83121553735751037.4782
84120977516091834.4357
85121430695641337.9889
86121145365940635.5947
87122805736103637.3644
88122841046207236.7977
89121599756217734.7391
90121540225909236.452
91121716115905936.7702
92121317826092934.988
93123028285995338.4106
94122804896234436.5791
95123267186270637.1052
96121813526106135.7241
97121719015802537.4304
98120641725587836.9407
99121500015800737.0645
  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值