Skip to content

Instantly share code, notes, and snippets.

@emcfarlane
Created October 6, 2025 22:23
Show Gist options
  • Select an option

  • Save emcfarlane/eab8ab5803fc927aa54693e51593f062 to your computer and use it in GitHub Desktop.

Select an option

Save emcfarlane/eab8ab5803fc927aa54693e51593f062 to your computer and use it in GitHub Desktop.
Benchmark leader election
package go
import (
"sync"
"testing"
)
func BenchmarkLeaderSyncMap(b *testing.B) {
// Simulate work that a leader performs.
doWork := func(key string) int {
sum := 0
for i := 0; i < 100; i++ {
sum += len(key) + i
}
return sum
}
b.Run("HighContention", func(b *testing.B) {
// Many goroutines racing for the same key.
var m sync.Map
key := "shared-key"
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
task := &taskSyncMap{cond: make(chan struct{})}
actual, beaten := m.LoadOrStore(key, task)
loaded := actual.(*taskSyncMap)
if !beaten {
// Leader: do work and broadcast.
loaded.result = doWork(key)
close(loaded.cond)
} else {
// Waiter: wait for leader to finish.
<-loaded.cond
}
_ = loaded.result
}
})
})
b.Run("LowContention", func(b *testing.B) {
// Each goroutine works on different keys.
var m sync.Map
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
key := b.Name() + "-" + string(rune(i))
i++
task := &taskSyncMap{cond: make(chan struct{})}
actual, beaten := m.LoadOrStore(key, task)
loaded := actual.(*taskSyncMap)
if !beaten {
// Leader: do work and broadcast.
loaded.result = doWork(key)
close(loaded.cond)
} else {
// Waiter: wait for leader to finish.
<-loaded.cond
}
_ = loaded.result
}
})
})
b.Run("MixedContention", func(b *testing.B) {
// Multiple keys with some contention on each.
var m sync.Map
keys := []string{"key-1", "key-2", "key-3", "key-4"}
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
key := keys[i%len(keys)]
i++
task := &taskSyncMap{cond: make(chan struct{})}
actual, beaten := m.LoadOrStore(key, task)
loaded := actual.(*taskSyncMap)
if !beaten {
// Leader: do work and broadcast.
loaded.result = doWork(key)
close(loaded.cond)
} else {
// Waiter: wait for leader to finish.
<-loaded.cond
}
_ = loaded.result
}
})
})
}
func BenchmarkLeaderLock(b *testing.B) {
// Simulate work that a leader performs.
doWork := func(key string) int {
sum := 0
for i := 0; i < 100; i++ {
sum += len(key) + i
}
return sum
}
b.Run("HighContention", func(b *testing.B) {
// Many goroutines racing for the same key.
var mu sync.Mutex
m := make(map[string]*taskLock)
key := "shared-key"
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
mu.Lock()
task, exists := m[key]
if !exists {
task = &taskLock{}
task.wg.Add(1)
m[key] = task
mu.Unlock()
// Leader: do work and signal completion.
task.result = doWork(key)
task.wg.Done()
} else {
mu.Unlock()
// Waiter: wait for leader to finish.
task.wg.Wait()
}
_ = task.result
}
})
})
b.Run("LowContention", func(b *testing.B) {
// Each goroutine works on different keys.
var mu sync.Mutex
m := make(map[string]*taskLock)
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
key := b.Name() + "-" + string(rune(i))
i++
mu.Lock()
task, exists := m[key]
if !exists {
task = &taskLock{}
task.wg.Add(1)
m[key] = task
mu.Unlock()
// Leader: do work and signal completion.
task.result = doWork(key)
task.wg.Done()
} else {
mu.Unlock()
// Waiter: wait for leader to finish.
task.wg.Wait()
}
_ = task.result
}
})
})
b.Run("MixedContention", func(b *testing.B) {
// Multiple keys with some contention on each.
var mu sync.Mutex
m := make(map[string]*taskLock)
keys := []string{"key-1", "key-2", "key-3", "key-4"}
b.RunParallel(func(pb *testing.PB) {
i := 0
for pb.Next() {
key := keys[i%len(keys)]
i++
mu.Lock()
task, exists := m[key]
if !exists {
task = &taskLock{}
task.wg.Add(1)
m[key] = task
mu.Unlock()
// Leader: do work and signal completion.
task.result = doWork(key)
task.wg.Done()
} else {
mu.Unlock()
// Waiter: wait for leader to finish.
task.wg.Wait()
}
_ = task.result
}
})
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment