github.com/aclements/go-misc@v0.0.0-20240129233631-2f6ede80790c/split/bench_test.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package split 6 7 import ( 8 "runtime" 9 "sync" 10 "sync/atomic" 11 "testing" 12 ) 13 14 func BenchmarkCounterSplitAtomic(b *testing.B) { 15 // Benchmark a simple split counter updating using atomics. 16 counter := New(func(*uint64) {}) 17 18 b.RunParallel(func(pb *testing.PB) { 19 for pb.Next() { 20 atomic.AddUint64(counter.Get().(*uint64), 1) 21 } 22 }) 23 } 24 25 func BenchmarkCounterSplitLocked(b *testing.B) { 26 // Benchmark a simple split counter using locking instead of atomics. 27 type shard struct { 28 sync.Mutex 29 val uint64 30 } 31 counter := New(func(*shard) {}) 32 33 b.RunParallel(func(pb *testing.PB) { 34 for pb.Next() { 35 s := counter.Get().(*shard) 36 s.Lock() 37 s.val++ 38 s.Unlock() 39 } 40 }) 41 } 42 43 func BenchmarkCounterShared(b *testing.B) { 44 // Non-sharded version of BenchmarkCounter. 45 var counter uint64 46 47 b.RunParallel(func(pb *testing.PB) { 48 for pb.Next() { 49 atomic.AddUint64(&counter, 1) 50 } 51 }) 52 } 53 54 var seqCounter uint64 55 56 func BenchmarkCounterSequential(b *testing.B) { 57 // Sequential version of BenchmarkCounter without atomics. For 58 // fair comparison with the cost of uncontended atomics, this 59 // only runs at -test.cpu=1 and uses the RunParallel mechanics 60 // so the overheads are the same (pb.Next gets inlined and has 61 // no atomic ops in the fast path, so this is pretty small). 62 if runtime.GOMAXPROCS(-1) != 1 { 63 b.Skip("requires -test.cpu=1") 64 } 65 b.RunParallel(func(pb *testing.PB) { 66 for pb.Next() { 67 seqCounter++ 68 } 69 }) 70 } 71 72 func BenchmarkRWMutex(b *testing.B) { 73 var m RWMutex 74 75 b.RunParallel(func(pb *testing.PB) { 76 for pb.Next() { 77 m.RLock().RUnlock() 78 } 79 }) 80 }