diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-02-03 16:54:45 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-02-03 16:59:29 +0100 |
commit | c3bde5f59099a3b21b016bf809b83ee3de126f80 (patch) | |
tree | 35167c928fd71b19d6524beb24c395a4bcefb9c2 | |
parent | fd63a233c9fedad2be4e26edbc540e11d9ea5968 (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.go | 23 |
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 |