Created
January 18, 2023 21:49
-
-
Save yyforyongyu/1029d1b1508ed5bcb8f26c8114a3bfb6 to your computer and use it in GitHub Desktop.
Benchmark performance among sync map, mutex map and read-write mutex map.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"sync" | |
"sync/atomic" | |
"testing" | |
) | |
func BenchmarkReadMutexMap(b *testing.B) { | |
// Create a map with a mutex. | |
m := make(map[int64]struct{}) | |
// k is the unique key for each goroutine. | |
k := int64(0) | |
// Create a general mutex. | |
var mu sync.Mutex | |
b.RunParallel(func(pb *testing.PB) { | |
for pb.Next() { | |
// Increment k. | |
atomic.AddInt64(&k, 1) | |
// Perform a lock read. | |
mu.Lock() | |
_, _ = m[k] | |
mu.Unlock() | |
} | |
}) | |
} | |
func BenchmarkReadRWMutexMap(b *testing.B) { | |
// Create a map with a mutex. | |
m := make(map[int64]struct{}) | |
// k is the unique key for each goroutine. | |
k := int64(0) | |
// Create a read write mutex. | |
var mu sync.RWMutex | |
b.RunParallel(func(pb *testing.PB) { | |
for pb.Next() { | |
// Increment k. | |
atomic.AddInt64(&k, 1) | |
// Perform a lock read. | |
mu.RLock() | |
_, _ = m[k] | |
mu.RUnlock() | |
} | |
}) | |
} | |
func BenchmarkReadSyncMap(b *testing.B) { | |
// Create a sync.Map. | |
syncMap := &sync.Map{} | |
// k is the unique key for each goroutine. | |
k := int64(0) | |
b.RunParallel(func(pb *testing.PB) { | |
for pb.Next() { | |
// Increment k. | |
atomic.AddInt64(&k, 1) | |
// Read the value. | |
syncMap.Load(k) | |
} | |
}) | |
} | |
func BenchmarkWriteMutexMap(b *testing.B) { | |
// Create a map with a mutex. | |
m := make(map[int64]struct{}) | |
// k is the unique key for each goroutine. | |
k := int64(0) | |
// Create a general mutex. | |
var mu sync.Mutex | |
b.RunParallel(func(pb *testing.PB) { | |
for pb.Next() { | |
// Increment k. | |
atomic.AddInt64(&k, 1) | |
// Perform a lock write. | |
mu.Lock() | |
m[k] = struct{}{} | |
mu.Unlock() | |
} | |
}) | |
} | |
func BenchmarkWriteRWMutexMap(b *testing.B) { | |
// Create a map with a mutex. | |
m := make(map[int64]struct{}) | |
// k is the unique key for each goroutine. | |
k := int64(0) | |
// Create a read write mutex. | |
var mu sync.RWMutex | |
b.RunParallel(func(pb *testing.PB) { | |
for pb.Next() { | |
// Increment k. | |
atomic.AddInt64(&k, 1) | |
// Perform a lock write. | |
mu.Lock() | |
m[k] = struct{}{} | |
mu.Unlock() | |
} | |
}) | |
} | |
func BenchmarkWriteSyncMap(b *testing.B) { | |
// Create a sync.Map. | |
syncMap := &sync.Map{} | |
// k is the unique key for each goroutine. | |
k := int64(0) | |
b.RunParallel(func(pb *testing.PB) { | |
for pb.Next() { | |
// Increment k. | |
atomic.AddInt64(&k, 1) | |
// Write the value. | |
syncMap.Store(k, struct{}{}) | |
} | |
}) | |
} | |
func BenchmarkDeleteMutexMap(b *testing.B) { | |
// Create a map with a mutex. | |
m := make(map[int64]struct{}) | |
// k is the unique key for each goroutine. | |
k := int64(0) | |
// Create a general mutex. | |
var mu sync.Mutex | |
b.RunParallel(func(pb *testing.PB) { | |
for pb.Next() { | |
// Increment k. | |
atomic.AddInt64(&k, 1) | |
// Perform a lock delete. | |
mu.Lock() | |
delete(m, k) | |
mu.Unlock() | |
} | |
}) | |
} | |
func BenchmarkDeleteRWMutexMap(b *testing.B) { | |
// Create a map with a mutex. | |
m := make(map[int64]struct{}) | |
// k is the unique key for each goroutine. | |
k := int64(0) | |
// Create a read write mutex. | |
var mu sync.RWMutex | |
b.RunParallel(func(pb *testing.PB) { | |
for pb.Next() { | |
// Increment k. | |
atomic.AddInt64(&k, 1) | |
// Perform a lock delete. | |
mu.Lock() | |
delete(m, k) | |
mu.Unlock() | |
} | |
}) | |
} | |
func BenchmarkDeleteSyncMap(b *testing.B) { | |
// Create a sync.Map. | |
syncMap := &sync.Map{} | |
// k is the unique key for each goroutine. | |
k := int64(0) | |
b.RunParallel(func(pb *testing.PB) { | |
for pb.Next() { | |
// Increment k. | |
atomic.AddInt64(&k, 1) | |
// Delete the value. | |
syncMap.Delete(k) | |
} | |
}) | |
} | |
// TODO: can further benchmark based on the map's state, such as, | |
// - read a key that exists. | |
// - write a key that exists. | |
// - delete a key that exists. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment