Skip to content

Instantly share code, notes, and snippets.

@yankooo
Created June 28, 2020 03:56
Show Gist options
  • Save yankooo/753abb8d73716eb40417b488f4108e45 to your computer and use it in GitHub Desktop.
Save yankooo/753abb8d73716eb40417b488f4108e45 to your computer and use it in GitHub Desktop.
cas vs mutex
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
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment