Skip to content

Instantly share code, notes, and snippets.

@Bobochka
Last active April 26, 2018 16:17
Show Gist options
  • Select an option

  • Save Bobochka/ada3c74afae121daf4d1fd04e12e09fc to your computer and use it in GitHub Desktop.

Select an option

Save Bobochka/ada3c74afae121daf4d1fd04e12e09fc to your computer and use it in GitHub Desktop.
mutexed map vs sync map
package main
import (
"math/rand"
"os"
"strconv"
"sync"
"testing"
)
type mutexedMap struct {
m map[string]string
lock *sync.RWMutex
}
func (mm *mutexedMap) Load(key string) string {
mm.lock.RLock()
defer mm.lock.RUnlock()
return mm.m[key]
}
var sm = &sync.Map{}
var mm = &mutexedMap{
lock: &sync.RWMutex{},
m: map[string]string{},
}
var bin string
var lookup = map[int]string{}
var cnt int
func init() {
var err error
cnt, err = strconv.Atoi(os.Getenv("CNT"))
if cnt == 0 {
panic("CNT is not provided")
}
if err != nil {
panic(err)
}
for _, v := range rand.Perm(cnt) {
lookup[v] = strconv.Itoa(v)
val := lookup[v]
sm.Store(val, val)
mm.m[val] = val
}
}
func BenchmarkMapSingle(b *testing.B) {
for i := 0; i < b.N; i++ {
bin = mm.m[lookup[i%cnt]]
}
}
func BenchmarkSyncMapSingle(b *testing.B) {
for i := 0; i < b.N; i++ {
v, _ := sm.Load(lookup[i%cnt])
bin, _ = v.(string)
}
}
func BenchmarkMutexedMapMSingle(b *testing.B) {
for i := 0; i < b.N; i++ {
bin = mm.Load(lookup[i%cnt])
}
}
func BenchmarkSyncMap100(b *testing.B) {
wg := &sync.WaitGroup{}
wg.Add(100)
binChan := make(chan string, 100)
for j := 0; j < 100; j++ {
go func(n int) {
var bin string
for i := 0; i < n; i++ {
v, _ := sm.Load(lookup[i%cnt])
bin, _ = v.(string)
}
binChan <- bin
wg.Done()
}(b.N)
}
wg.Wait()
}
func BenchmarkMutexedMap100(b *testing.B) {
wg := &sync.WaitGroup{}
wg.Add(100)
binChan := make(chan string, 100)
for j := 0; j < 100; j++ {
go func(n int) {
var bin string
for i := 0; i < n; i++ {
bin = mm.Load(lookup[i%cnt])
}
binChan <- bin
wg.Done()
}(b.N)
}
wg.Wait()
}
// ➜ play CNT=1 go test -bench=.
// goos: darwin
// goarch: amd64
// pkg: github.com/Bobochka/play
// BenchmarkMapSingle-8 100000000 17.5 ns/op
// BenchmarkSyncMapSingle-8 30000000 41.3 ns/op
// BenchmarkMutexedMapMSingle-8 20000000 61.1 ns/op
// BenchmarkSyncMap100-8 1000000 1073 ns/op
// BenchmarkMutexedMap100-8 300000 5156 ns/op
// PASS
// ok github.com/Bobochka/play 7.037s
// ➜ play CNT=10 go test -bench=.
// goos: darwin
// goarch: amd64
// pkg: github.com/Bobochka/play
// BenchmarkMapSingle-8 50000000 32.0 ns/op
// BenchmarkSyncMapSingle-8 30000000 49.9 ns/op
// BenchmarkMutexedMapMSingle-8 20000000 76.3 ns/op
// BenchmarkSyncMap100-8 1000000 1235 ns/op
// BenchmarkMutexedMap100-8 300000 5190 ns/op
// PASS
// ok github.com/Bobochka/play 7.667s
// ➜ play CNT=100 go test -bench=.
// goos: darwin
// goarch: amd64
// pkg: github.com/Bobochka/play
// BenchmarkMapSingle-8 50000000 32.7 ns/op
// BenchmarkSyncMapSingle-8 30000000 57.7 ns/op
// BenchmarkMutexedMapMSingle-8 20000000 80.6 ns/op
// BenchmarkSyncMap100-8 1000000 1369 ns/op
// BenchmarkMutexedMap100-8 300000 5556 ns/op
// PASS
// ok github.com/Bobochka/play 8.297s
// ➜ play CNT=1000 go test -bench=.
// goos: darwin
// goarch: amd64
// pkg: github.com/Bobochka/play
// BenchmarkMapSingle-8 20000000 61.8 ns/op
// BenchmarkSyncMapSingle-8 20000000 84.7 ns/op
// BenchmarkMutexedMapMSingle-8 20000000 108 ns/op
// BenchmarkSyncMap100-8 1000000 1740 ns/op
// BenchmarkMutexedMap100-8 300000 5977 ns/op
// PASS
// ok github.com/Bobochka/play 9.033s
// ➜ play CNT=10000 go test -bench=.
// goos: darwin
// goarch: amd64
// pkg: github.com/Bobochka/play
// BenchmarkMapSingle-8 20000000 92.0 ns/op
// BenchmarkSyncMapSingle-8 10000000 119 ns/op
// BenchmarkMutexedMapMSingle-8 10000000 134 ns/op
// BenchmarkSyncMap100-8 1000000 2413 ns/op
// BenchmarkMutexedMap100-8 300000 5644 ns/op
// PASS
// ok github.com/Bobochka/play 9.003s
// ➜ play CNT=100000 go test -bench=.
// goos: darwin
// goarch: amd64
// pkg: github.com/Bobochka/play
// BenchmarkMapSingle-8 10000000 250 ns/op
// BenchmarkSyncMapSingle-8 3000000 418 ns/op
// BenchmarkMutexedMapMSingle-8 5000000 285 ns/op
// BenchmarkSyncMap100-8 300000 5720 ns/op
// BenchmarkMutexedMap100-8 200000 6380 ns/op
// PASS
// ok github.com/Bobochka/play 9.880s
// ➜ play CNT=1000000 go test -bench=.
// goos: darwin
// goarch: amd64
// pkg: github.com/Bobochka/play
// BenchmarkMapSingle-8 5000000 338 ns/op
// BenchmarkSyncMapSingle-8 2000000 552 ns/op
// BenchmarkMutexedMapMSingle-8 3000000 477 ns/op
// BenchmarkSyncMap100-8 200000 10027 ns/op
// BenchmarkMutexedMap100-8 200000 9572 ns/op
// PASS
// ok github.com/Bobochka/play 16.860s
// ➜ play CNT=10000000 go test -bench=.
// goos: darwin
// goarch: amd64
// pkg: github.com/Bobochka/play
// BenchmarkMapSingle-8 3000000 547 ns/op
// BenchmarkSyncMapSingle-8 2000000 872 ns/op
// BenchmarkMutexedMapMSingle-8 2000000 663 ns/op
// BenchmarkSyncMap100-8 30000 49464 ns/op
// BenchmarkMutexedMap100-8 100000 11823 ns/op
// PASS
// ok github.com/Bobochka/play 114.118s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment