Skip to content

Instantly share code, notes, and snippets.

@luqmansen
Created July 21, 2022 03:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luqmansen/67aabb93b094e10a8628373a8692b071 to your computer and use it in GitHub Desktop.
Save luqmansen/67aabb93b094e10a8628373a8692b071 to your computer and use it in GitHub Desktop.
Testing some concurrent map locking mechanism
package caskdb
import (
"github.com/cornelk/hashmap"
"math"
"sync"
"testing"
)
type m struct {
data map[int]int
dataHM *hashmap.HashMap
lock chan struct{}
mu *sync.RWMutex
}
func newM() *m {
mm := &m{
data: make(map[int]int),
dataHM: hashmap.New(1_000_000),
lock: make(chan struct{}, 1),
mu: &sync.RWMutex{},
}
go func() {
mm.lock <- struct{}{}
}()
return mm
}
func (d *m) Add_chan(i int) {
<-d.lock
d.data[i] = i
d.lock <- struct{}{}
}
func (d *m) read_chan(i int) int {
<-d.lock
s := d.data[i]
d.lock <- struct{}{}
return s
}
func (d *m) Add_hm(i int) {
d.dataHM.Set(i, i)
}
func (d *m) read_hm(i int) int {
v, ok := d.dataHM.Get(i)
if ok {
return v.(int)
}
//panic(fmt.Sprintf("%d not found", i))
return -math.MaxInt
}
func (d *m) Add_mu(i int) {
d.mu.Lock()
d.data[i] = i
d.mu.Unlock()
}
func (d *m) read_mu(i int) int {
d.mu.Lock()
s := d.data[i]
d.mu.Unlock()
return s
}
func (d *m) read_rwmu(i int) int {
d.mu.RLock()
s := d.data[i]
d.mu.RUnlock()
return s
}
func Benchmark_lockfree(b *testing.B) {
d := newM()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
for i := 0; i < b.N; i++ {
d.Add_hm(i)
if d.read_hm(i) != i {
b.Fail()
}
}
}
})
}
func Benchmark_channelLock(b *testing.B) {
d := newM()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
for i := 0; i < b.N; i++ {
d.Add_chan(i)
if d.read_chan(i) != i {
b.Fail()
}
}
}
})
}
func Benchmark_mutex(b *testing.B) {
d := newM()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
for i := 0; i < b.N; i++ {
d.Add_mu(i)
if d.read_mu(i) != i {
b.Fail()
}
}
}
})
}
func Benchmark_rwmutex(b *testing.B) {
d := newM()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
for i := 0; i < b.N; i++ {
d.Add_mu(i)
if d.read_rwmu(i) != i {
b.Fail()
}
}
}
})
}
@luqmansen
Copy link
Author

result

goos: darwin
goarch: arm64
pkg: github.com/luqmansen/go-caskdb
Benchmark_lockfree
Benchmark_lockfree-8      	   10000	   5804118 ns/op
Benchmark_channelLock
Benchmark_channelLock-8   	    4396	  12010229 ns/op
Benchmark_mutex
Benchmark_mutex-8         	   10000	  10215965 ns/op
Benchmark_rwmutex
Benchmark_rwmutex-8       	    8539	   8713310 ns/op
PASS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment