More benchmarks
This commit is contained in:
+68
-40
@@ -3,6 +3,7 @@ package puddle_test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -489,52 +490,79 @@ func TestPoolReturnClosesResourcePoolIsAlreadyClosedErrorIsReported(t *testing.T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPoolGetAndReturnNoContention(b *testing.B) {
|
func BenchmarkPoolGetAndReturn(b *testing.B) {
|
||||||
createFunc, _ := createCreateResourceFunc()
|
benchmarks := []struct {
|
||||||
pool := puddle.NewPool(createFunc, stubCloseRes)
|
poolSize int
|
||||||
|
concurrentClientCount int
|
||||||
|
loanDuration time.Duration
|
||||||
|
}{
|
||||||
|
// Small pool
|
||||||
|
{10, 1, 0},
|
||||||
|
{10, 5, 0},
|
||||||
|
{10, 10, 0},
|
||||||
|
{10, 20, 0},
|
||||||
|
{10, 1, 1 * time.Millisecond},
|
||||||
|
{10, 5, 1 * time.Millisecond},
|
||||||
|
{10, 10, 1 * time.Millisecond},
|
||||||
|
{10, 20, 1 * time.Millisecond},
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
// large pool
|
||||||
res, err := pool.Get(context.Background())
|
{100, 1, 0},
|
||||||
if err != nil {
|
{100, 50, 0},
|
||||||
b.Fatal(err)
|
{100, 100, 0},
|
||||||
}
|
{100, 200, 0},
|
||||||
pool.Return(res)
|
{100, 1, 1 * time.Millisecond},
|
||||||
|
{100, 50, 1 * time.Millisecond},
|
||||||
|
{100, 100, 1 * time.Millisecond},
|
||||||
|
{100, 200, 1 * time.Millisecond},
|
||||||
|
|
||||||
|
// huge pool
|
||||||
|
{1000, 1, 0},
|
||||||
|
{1000, 500, 0},
|
||||||
|
{1000, 1000, 0},
|
||||||
|
{1000, 2000, 0},
|
||||||
|
{1000, 1, 1 * time.Millisecond},
|
||||||
|
{1000, 500, 1 * time.Millisecond},
|
||||||
|
{1000, 1000, 1 * time.Millisecond},
|
||||||
|
{1000, 2000, 1 * time.Millisecond},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkPoolGetAndReturnHeavyContention(b *testing.B) {
|
for _, bm := range benchmarks {
|
||||||
poolSize := 8
|
name := fmt.Sprintf("PoolSize=%d/ConcurrentClientCount=%d/LoanDuration=%v", bm.poolSize, bm.concurrentClientCount, bm.loanDuration)
|
||||||
contentionClients := 15
|
|
||||||
|
|
||||||
createFunc, _ := createCreateResourceFunc()
|
createFunc, _ := createCreateResourceFunc()
|
||||||
pool := puddle.NewPool(createFunc, stubCloseRes)
|
pool := puddle.NewPool(createFunc, stubCloseRes)
|
||||||
pool.SetMaxSize(poolSize)
|
pool.SetMaxSize(bm.poolSize)
|
||||||
|
|
||||||
doneChan := make(chan struct{})
|
borrowAndReturn := func() {
|
||||||
defer close(doneChan)
|
res, err := pool.Get(context.Background())
|
||||||
for i := 0; i < contentionClients; i++ {
|
if err != nil {
|
||||||
go func() {
|
b.Fatal(err)
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-doneChan:
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := pool.Get(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
pool.Return(res)
|
|
||||||
}
|
}
|
||||||
}()
|
time.Sleep(bm.loanDuration)
|
||||||
}
|
pool.Return(res)
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
res, err := pool.Get(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
}
|
||||||
pool.Return(res)
|
|
||||||
|
b.Run(name, func(b *testing.B) {
|
||||||
|
doneChan := make(chan struct{})
|
||||||
|
defer close(doneChan)
|
||||||
|
for i := 0; i < bm.concurrentClientCount-1; i++ {
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-doneChan:
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
borrowAndReturn()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
borrowAndReturn()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user