Go Concurrent Map Access Benchmark

A benchmark to compare the performance of different concurrent map access implementations in Go.

Description:

The classic map access is done by using the map[key] syntax. This implementation works fine in the most cases, but it is not thread-safe. A solution is to use the sync.Map type or to add a mutex to the map. This benchmark shows which implementation is the fastest.

Implementations

Green marks the fastest implementation, red marks the slowest

Comparison

This section compares the performance of Concurrent Map Access implementations with the functions: run

Different Run Count

Different CPU Core Count

Mutex

This benchmark uses a sync.Mutex to lock the map, before accessing it. This makes sure, that only one goroutine can access the map at the same time. For this implementation, you need to write own wrappers, to lock and unlock the map on each access.

Function ns/op ops/sec B/op allocs/op MB/s
run 1227.34 864259 171.6 2 0.0

Comparison

  • Mutex run is 30.58% faster than Sync run.
func BenchmarkMutex_run(b *testing.B) {
	var m = make(map[int]int)
	var mutex sync.Mutex
	var wg sync.WaitGroup

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		wg.Add(2)

		go func() {
			mutex.Lock()
			m[i] = i
			mutex.Unlock()
			wg.Done()
		}()

		go func() {
			mutex.Lock()
			_ = m[i]
			mutex.Unlock()
			wg.Done()
		}()

		wg.Wait()
	}
}

Mutex run

ns/op ops/sec B/op allocs/op MB/s
1227.34 864259 171.6 2 0.0
By Run Count
By CPU Core Count

Sync

This benchmark uses the sync.Map type. This type is thread-safe, so you don't need to write own wrappers to lock and unlock the map on each access.

Function ns/op ops/sec B/op allocs/op MB/s
run 1768.08 590110 225.8 6 0.0

Comparison

  • Sync run is 44.06% slower than Mutex run.
func BenchmarkSync_run(b *testing.B) {
	var m sync.Map
	var wg sync.WaitGroup

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		wg.Add(2)

		go func() {
			m.Store(i, i)
			wg.Done()
		}()

		go func() {
			m.Load(i)
			wg.Done()
		}()

		wg.Wait()
	}
}

Sync run

ns/op ops/sec B/op allocs/op MB/s
1768.08 590110 225.8 6 0.0
By Run Count
By CPU Core Count

Full Benchmark Code

func BenchmarkMutex_run(b *testing.B) {
	var m = make(map[int]int)
	var mutex sync.Mutex
	var wg sync.WaitGroup

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		wg.Add(2)

		go func() {
			mutex.Lock()
			m[i] = i
			mutex.Unlock()
			wg.Done()
		}()

		go func() {
			mutex.Lock()
			_ = m[i]
			mutex.Unlock()
			wg.Done()
		}()

		wg.Wait()
	}
}

func BenchmarkSync_run(b *testing.B) {
	var m sync.Map
	var wg sync.WaitGroup

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		wg.Add(2)

		go func() {
			m.Store(i, i)
			wg.Done()
		}()

		go func() {
			m.Load(i)
			wg.Done()
		}()

		wg.Wait()
	}
}

Full Benchmark Output

Implementation Function Runs CPU Core Count ns/op ops/sec B/op allocs/op MB/s
Mutex run 1000 2 876.5 1140901.312036509 179 2 0
Mutex run 2000 2 987.7 1012453.1740407005 180 2 0
Mutex run 3000 2 986 1014198.7829614604 154 2 0
Mutex run 4000 2 1027 973709.8344693282 181 2 0
Mutex run 5000 2 1004 996015.93625498 163 2 0
Mutex run 6000 2 1073 931966.4492078285 152 2 0
Mutex run 7000 2 933.1 1071696.4955524595 191 2 0
Mutex run 8000 2 911.6 1096972.3562966213 179 2 0
Mutex run 9000 2 909.2 1099868.0158380994 170 2 0
Mutex run 10000 2 1032 968992.2480620155 162 2 0
Mutex run 1000 16 1318 758725.3414264036 181 2 0
Mutex run 2000 16 1447 691085.003455425 180 2 0
Mutex run 3000 16 1604 623441.3965087282 154 2 0
Mutex run 4000 16 1460 684931.506849315 181 2 0
Mutex run 5000 16 1324 755287.0090634441 164 2 0
Mutex run 6000 16 1544 647668.3937823834 154 2 0
Mutex run 7000 16 1299 769822.9407236335 191 2 0
Mutex run 8000 16 1262 792393.0269413629 179 2 0
Mutex run 9000 16 1151 868809.7306689835 170 2 0
Mutex run 10000 16 1285 778210.1167315175 162 2 0
Mutex run 1000 32 1908 524109.0146750524 181 2 0
Mutex run 2000 32 1758 568828.2138794084 180 2 0
Mutex run 3000 32 1879 532197.977647685 154 2 0
Mutex run 4000 32 1317 759301.4426727411 180 2 0
Mutex run 5000 32 1729 578368.999421631 164 2 0
Mutex run 6000 32 1702 587544.0658049354 153 2 0
Mutex run 7000 32 1453 688231.2456985547 191 2 0
Mutex run 8000 32 1550 645161.2903225806 180 2 0
Mutex run 9000 32 1520 657894.7368421053 171 2 0
Mutex run 10000 32 1564 639386.189258312 163 2 0
Mutex run 1000 1 889.4 1124353.496739375 179 2 0
Mutex run 2000 1 871.3 1147710.3179157581 180 2 0
Mutex run 3000 1 767.8 1302422.5058609014 153 2 0
Mutex run 4000 1 816.8 1224289.9118511265 180 2 0
Mutex run 5000 1 820.5 1218769.043266301 164 2 0
Mutex run 6000 1 846.7 1181055.8639423645 153 2 0
Mutex run 7000 1 785.5 1273074.4748567792 191 2 0
Mutex run 8000 1 788.2 1268713.5244861708 179 2 0
Mutex run 9000 1 773.6 1292657.7042399172 170 2 0
Mutex run 10000 1 792.6 1261670.4516780216 163 2 0
Mutex run 1000 4 1521 657462.1959237343 182 2 0
Mutex run 2000 4 1436 696378.8300835654 181 2 0
Mutex run 3000 4 1210 826446.2809917355 154 2 0
Mutex run 4000 4 1390 719424.4604316547 181 2 0
Mutex run 5000 4 1161 861326.4427217916 163 2 0
Mutex run 6000 4 1396 716332.3782234957 154 2 0
Mutex run 7000 4 1230 813008.1300813009 192 2 0
Mutex run 8000 4 1192 838926.1744966443 179 2 0
Mutex run 9000 4 1099 909918.1073703367 170 2 0
Mutex run 10000 4 1147 871839.5815170009 163 2 0
Mutex run 1000 8 1257 795544.9482895783 180 2 0
Mutex run 2000 8 1462 683994.5280437757 181 2 0
Mutex run 3000 8 1268 788643.5331230283 155 2 0
Mutex run 4000 8 1391 718907.2609633357 181 2 0
Mutex run 5000 8 1335 749063.670411985 164 2 0
Mutex run 6000 8 1327 753579.5026375282 153 2 0
Mutex run 7000 8 1283 779423.2268121591 192 2 0
Mutex run 8000 8 1182 846023.6886632825 179 2 0
Mutex run 9000 8 1170 854700.8547008547 170 2 0
Mutex run 10000 8 1217 821692.6869350863 163 2 0
Sync run 1000 16 1913 522739.1531625719 236 6 0
Sync run 2000 16 1906 524658.9716684156 237 6 0
Sync run 3000 16 1847 541418.5165132647 200 6 0
Sync run 4000 16 2073 482392.66763145203 238 6 0
Sync run 5000 16 2058 485908.6491739553 214 6 0
Sync run 6000 16 1932 517598.3436853002 200 6 0
Sync run 7000 16 1936 516528.9256198347 254 6 0
Sync run 8000 16 1962 509683.99592252803 238 6 0
Sync run 9000 16 2088 478927.2030651341 225 6 0
Sync run 10000 16 1918 521376.4337851929 214 6 0
Sync run 1000 32 2435 410677.6180698152 234 6 0
Sync run 2000 32 2613 382701.87523918867 238 6 0
Sync run 3000 32 1891 528820.7297726071 200 6 0
Sync run 4000 32 2508 398724.08293460927 237 6 0
Sync run 5000 32 2204 453720.5081669692 214 6 0
Sync run 6000 32 1963 509424.35048395314 200 6 0
Sync run 7000 32 2027 493339.911198816 255 6 0
Sync run 8000 32 1920 520833.3333333333 238 6 0
Sync run 9000 32 2056 486381.3229571984 225 6 0
Sync run 10000 32 1977 505816.8942842691 215 6 0
Sync run 1000 1 1211 825763.8315441784 236 6 0
Sync run 2000 1 1404 712250.7122507122 237 6 0
Sync run 3000 1 1114 897666.0682226212 199 6 0
Sync run 4000 1 1118 894454.3828264759 237 6 0
Sync run 5000 1 1168 856164.3835616439 213 6 0
Sync run 6000 1 1293 773395.2049497293 200 6 0
Sync run 7000 1 1218 821018.0623973728 255 6 0
Sync run 8000 1 1136 880281.690140845 238 6 0
Sync run 9000 1 1248 801282.0512820513 225 6 0
Sync run 10000 1 1110 900900.900900901 214 6 0
Sync run 1000 8 2063 484730.97430925834 236 6 0
Sync run 2000 8 1693 590667.4542232723 237 6 0
Sync run 3000 8 1776 563063.0630630631 201 6 0
Sync run 4000 8 1740 574712.643678161 237 6 0
Sync run 5000 8 1846 541711.8093174432 215 6 0
Sync run 6000 8 1848 541125.5411255411 201 6 0
Sync run 7000 8 1886 530222.6935312832 255 6 0
Sync run 8000 8 1794 557413.6008918617 238 6 0
Sync run 9000 8 1866 535905.6806002144 225 6 0
Sync run 10000 8 1792 558035.7142857143 214 6 0
Sync run 1000 2 1666 600240.0960384153 237 6 0
Sync run 2000 2 2160 462962.962962963 236 6 0
Sync run 3000 2 1632 612745.0980392157 201 6 0
Sync run 4000 2 1684 593824.2280285036 237 6 0
Sync run 5000 2 1763 567214.9744753261 214 6 0
Sync run 6000 2 1577 634115.4090044388 200 6 0
Sync run 7000 2 1452 688705.2341597796 255 6 0
Sync run 8000 2 1370 729927.00729927 238 6 0
Sync run 9000 2 1406 711237.5533428165 226 6 0
Sync run 10000 2 1369 730460.1899196494 215 6 0
Sync run 1000 4 1807 553403.4311012728 237 6 0
Sync run 2000 4 2068 483558.9941972921 237 6 0
Sync run 3000 4 1597 626174.0763932373 201 6 0
Sync run 4000 4 1802 554938.9567147613 238 6 0
Sync run 5000 4 1787 559597.0900951315 214 6 0
Sync run 6000 4 1979 505305.7099545225 201 6 0
Sync run 7000 4 1936 516528.9256198347 255 6 0
Sync run 8000 4 1780 561797.7528089888 238 6 0
Sync run 9000 4 1863 536768.6527106817 225 6 0
Sync run 10000 4 1836 544662.3093681918 215 6 0