Skip to content

Instantly share code, notes, and snippets.

@cstockton
Created October 28, 2017 18:52
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 cstockton/e22b990bfc915a3cc4856220287ddbeb to your computer and use it in GitHub Desktop.
Save cstockton/e22b990bfc915a3cc4856220287ddbeb to your computer and use it in GitHub Desktop.
for reddit comment
// For reddit comment:
// https://www.reddit.com/r/golang/comments/799of8/how_to_implement_a_lock_free_array/dp0js4k/
//
// About: https://github.com/cornelk/hashmap
// Map of atomic Values built in 10 seconds without unsafe is the winner for a contentious but consistent key set:
//
// BenchmarkCorrectReadGoAtomicMapUintMutex-24 1000000 1957 ns/op 0 B/op 0 allocs/op
// BenchmarkCorrectReadGoAtomicMapUintValMutex-24 1000000 1926 ns/op 0 B/op 0 allocs/op
func BenchmarkCorrectReadGoAtomicMapUintMutex(b *testing.B) {
m := make(map[uintptr]*atomic.Value)
for i := uintptr(0); i < benchmarkItemCount; i++ {
j := uintptr(i)
v := new(atomic.Value)
v.Store(&j)
m[i] = v
}
b.ReportAllocs()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
for i := uintptr(0); i < benchmarkItemCount; i++ {
v, _ := m[i]
if *(v.Load().(*uintptr)) != i {
b.Fail()
}
}
}
})
}
func BenchmarkCorrectReadGoAtomicMapUintValMutex(b *testing.B) {
m := make(map[uintptr]*atomic.Value)
for i := uintptr(0); i < benchmarkItemCount; i++ {
j := uintptr(i)
v := new(atomic.Value)
v.Store(j)
m[i] = v
}
b.ReportAllocs()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
for i := uintptr(0); i < benchmarkItemCount; i++ {
v, _ := m[i]
if v.Load().(uintptr) != i {
b.Fail()
}
}
}
})
}
// Fixed benchmarks:
//
// BenchmarkCorrectReadGoSyncMapUint-24 300000 4038 ns/op 0 B/op 0 allocs/op
// BenchmarkCorrectReadGoSyncMapValUint-24 300000 3998 ns/op 0 B/op 0 allocs/op
// BenchmarkCorrectReadHashMapUint-24 500000 2528 ns/op 0 B/op 0 allocs/op
func BenchmarkCorrectReadGoSyncMapUint(b *testing.B) {
m := syncmap.Map{}
for i := uintptr(0); i < benchmarkItemCount; i++ {
j := uintptr(i)
m.Store(i, &j)
}
b.ReportAllocs()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
for i := uintptr(0); i < benchmarkItemCount; i++ {
j, _ := m.Load(i)
if *(j.(*uintptr)) != i {
b.Fail()
}
}
}
})
}
func BenchmarkCorrectReadGoSyncMapValUint(b *testing.B) {
m := syncmap.Map{}
for i := uintptr(0); i < benchmarkItemCount; i++ {
j := uintptr(i)
m.Store(i, j)
}
b.ReportAllocs()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
for i := uintptr(0); i < benchmarkItemCount; i++ {
j, _ := m.Load(i)
if j.(uintptr) != i {
b.Fail()
}
}
}
})
}
func BenchmarkCorrectReadGoMapUintMutex(b *testing.B) {
var l sync.RWMutex
m := make(map[uintptr]*uintptr)
for i := uintptr(0); i < benchmarkItemCount; i++ {
j := uintptr(i)
m[i] = &j
}
b.ReportAllocs()
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
for i := uintptr(0); i < benchmarkItemCount; i++ {
l.RLock()
j, _ := m[i]
l.RUnlock()
if *j != i {
b.Fail()
}
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment