package adder import ( "sync" "sync/atomic" "testing" ) type Counter interface { Inc() Load() int64 } // Atomic Implementation type AtomicCounter struct { counter int64 } func (c *AtomicCounter) Inc() { atomic.AddInt64(&c.counter, 1) } func (c *AtomicCounter) Load() int64 { return atomic.LoadInt64(&c.counter) } // Mutex Implementation type MutexCounter struct { counter int64 lock sync.Mutex } func (c *MutexCounter) Inc() { c.lock.Lock() defer c.lock.Unlock() c.counter++ } func (c *MutexCounter) Load() int64 { c.lock.Lock() defer c.lock.Unlock() return c.counter } func BenchmarkCAS(b *testing.B) { b.StopTimer() q := AtomicCounter{} b.StartTimer() for i := 0; i < b.N; i++ { q.Inc() q.Load() } } func BenchmarkMutex(b *testing.B) { b.StopTimer() q := MutexCounter{} b.StartTimer() for i := 0; i < b.N; i++ { q.Inc() q.Load() } } func TestCAS(t *testing.T) { q := AtomicCounter{} for i := 0; i < 1000; i++ { go q.Inc() go q.Load() } } func TestMutex(t *testing.T) { q := MutexCounter{} for i := 0; i < 1000; i++ { go q.Inc() go q.Load() } } /* goos: darwin goarch: amd64 pkg: garbage/adder BenchmarkCAS 200000000 7.17 ns/op BenchmarkCAS-4 200000000 7.25 ns/op BenchmarkCAS-8 200000000 7.18 ns/op BenchmarkCAS-16 200000000 7.14 ns/op BenchmarkMutex 20000000 81.3 ns/op BenchmarkMutex-4 20000000 81.3 ns/op BenchmarkMutex-8 20000000 81.6 ns/op BenchmarkMutex-16 20000000 82.0 ns/op */