Skip to content

Instantly share code, notes, and snippets.

@dtjm
Created August 28, 2017 22:42
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 dtjm/164081e978fa6472d137396614f54673 to your computer and use it in GitHub Desktop.
Save dtjm/164081e978fa6472d137396614f54673 to your computer and use it in GitHub Desktop.
package lock_test
import (
"fmt"
"sync"
"testing"
"time"
)
type rlocker interface {
sync.Locker
RLock()
RUnlock()
}
type noopLock struct{}
func (m noopLock) Lock() {}
func (m noopLock) Unlock() {}
func (m noopLock) RLock() {}
func (m noopLock) RUnlock() {}
type lockOnlyMutex struct {
sync.Mutex
}
func (m *lockOnlyMutex) RLock() { m.Lock() }
func (m *lockOnlyMutex) RUnlock() { m.Unlock() }
func BenchmarkLocks(b *testing.B) {
mutexes := []rlocker{
&noopLock{},
&lockOnlyMutex{},
&sync.RWMutex{},
}
for _, readRatio := range []int{1, 10, 100} {
for _, mu := range mutexes {
b.Run(fmt.Sprintf("%T,readRatio=%d", mu, readRatio), func(b *testing.B) {
b.ResetTimer()
benchmarkRLocker(b, mu, readRatio, time.Microsecond, time.Nanosecond)
})
}
}
}
func benchmarkRLocker(b *testing.B, mu rlocker, readRatio int, readTime, writeTime time.Duration) {
writers := 1
readers := writers * readRatio
// mu := sync.Mutex{}
wg := sync.WaitGroup{}
x := 0
for i := 0; i < readers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for {
mu.RLock()
y := x
time.Sleep(readTime)
mu.RUnlock()
if y > b.N {
return
}
}
}()
}
for i := 0; i < writers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for {
// log.Printf("acquiring write lock")
// defer log.Printf("releasing write lock")
mu.Lock()
time.Sleep(writeTime)
x++
done := x > b.N
mu.Unlock()
if done {
return
}
}
}()
}
wg.Wait()
}
@dtjm
Copy link
Author

dtjm commented Nov 22, 2017

Results:

goos: darwin
goarch: amd64
BenchmarkLocks/*lock_test.noopLock,readRatio=1-4         	 2000000	       968 ns/op
BenchmarkLocks/*lock_test.lockOnlyMutex,readRatio=1-4    	   20000	    129093 ns/op
BenchmarkLocks/*sync.RWMutex,readRatio=1-4               	  200000	      8627 ns/op
BenchmarkLocks/*lock_test.noopLock,readRatio=10-4        	  200000	      8337 ns/op
BenchmarkLocks/*lock_test.lockOnlyMutex,readRatio=10-4   	   10000	    533723 ns/op
BenchmarkLocks/*sync.RWMutex,readRatio=10-4              	  100000	     20316 ns/op
BenchmarkLocks/*lock_test.noopLock,readRatio=100-4       	   30000	     52709 ns/op
BenchmarkLocks/*lock_test.lockOnlyMutex,readRatio=100-4  	    2000	   1026620 ns/op
BenchmarkLocks/*sync.RWMutex,readRatio=100-4             	   20000	     75479 ns/op
PASS
ok  	command-line-arguments	23.929s

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