summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2021-02-03 16:54:45 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2021-02-03 16:59:29 +0100
commitc3bde5f59099a3b21b016bf809b83ee3de126f80 (patch)
tree35167c928fd71b19d6524beb24c395a4bcefb9c2
parentfd63a233c9fedad2be4e26edbc540e11d9ea5968 (diff)
device: benchmark the waitpool to compare it to the prior channels
Here is the old implementation: type WaitPool struct { c chan interface{} } func NewWaitPool(max uint32, new func() interface{}) *WaitPool { p := &WaitPool{c: make(chan interface{}, max)} for i := uint32(0); i < max; i++ { p.c <- new() } return p } func (p *WaitPool) Get() interface{} { return <- p.c } func (p *WaitPool) Put(x interface{}) { p.c <- x } It performs worse than the new one: name old time/op new time/op delta WaitPool-16 16.4µs ± 5% 15.1µs ± 3% -7.86% (p=0.008 n=5+5) Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--device/pools_test.go23
1 files changed, 23 insertions, 0 deletions
diff --git a/device/pools_test.go b/device/pools_test.go
index e6cbac5..6caf7e7 100644
--- a/device/pools_test.go
+++ b/device/pools_test.go
@@ -58,3 +58,26 @@ func TestWaitPool(t *testing.T) {
t.Errorf("Actual maximum count (%d) != ideal maximum count (%d)", max, p.max)
}
}
+
+func BenchmarkWaitPool(b *testing.B) {
+ var wg sync.WaitGroup
+ trials := int32(b.N)
+ workers := runtime.NumCPU() + 2
+ if workers-4 <= 0 {
+ b.Skip("Not enough cores")
+ }
+ p := NewWaitPool(uint32(workers-4), func() interface{} { return make([]byte, 16) })
+ wg.Add(workers)
+ b.ResetTimer()
+ for i := 0; i < workers; i++ {
+ go func() {
+ defer wg.Done()
+ for atomic.AddInt32(&trials, -1) > 0 {
+ x := p.Get()
+ time.Sleep(time.Duration(rand.Intn(100)) * time.Microsecond)
+ p.Put(x)
+ }
+ }()
+ }
+ wg.Wait()
+} \ No newline at end of file