diff --git a/lib_test.go b/lib_test.go index e636b20..5dd7c46 100644 --- a/lib_test.go +++ b/lib_test.go @@ -2,6 +2,7 @@ package priorityq_test import ( "math/rand" + "runtime" "sync" "testing" @@ -177,3 +178,38 @@ func BenchmarkConcSendRecv(b *testing.B) { close(start) wg.Wait() } + +func BenchmarkHighContention(b *testing.B) { + q := priorityq.Make[int, int](b.N) + var wg sync.WaitGroup + start := make(chan struct{}) + done := make(chan struct{}) + numProducers := runtime.NumCPU() + sendsPerProducer := b.N / numProducers + wg.Add(numProducers) + for i := 0; i < numProducers; i++ { + go func() { + ps := make([]int, sendsPerProducer) + for i := 0; i < sendsPerProducer; i++ { + ps[i] = rand.Int() + } + <-start + for i := 0; i < sendsPerProducer; i++ { + q.Send(ps[i], 1) + } + wg.Done() + }() + } + go func() { + ok := true + for ok { + _, _, ok = q.Recv() + } + close(done) + }() + b.ResetTimer() + close(start) + wg.Wait() + q.Close() + <-done +} diff --git a/mq/lib_test.go b/mq/lib_test.go index a887a73..54d0457 100644 --- a/mq/lib_test.go +++ b/mq/lib_test.go @@ -2,6 +2,7 @@ package mq_test import ( "math/rand" + "runtime" "sync" "testing" @@ -226,3 +227,64 @@ func BenchmarkConcSendRecvChan(b *testing.B) { close(start) wg.Wait() } + +func BenchmarkHighContention(b *testing.B) { + q := mq.Make[int](b.N) + var wg sync.WaitGroup + start := make(chan struct{}) + done := make(chan struct{}) + numProducers := runtime.NumCPU() + sendsPerProducer := b.N / numProducers + wg.Add(numProducers) + for i := 0; i < numProducers; i++ { + go func() { + <-start + for i := 0; i < sendsPerProducer; i++ { + q.Send(1) + } + wg.Done() + }() + } + go func() { + ok := true + for ok { + _, ok = q.Recv() + } + close(done) + }() + b.ResetTimer() + close(start) + wg.Wait() + q.Close() + <-done +} + +func BenchmarkHighContentionChan(b *testing.B) { + c := make(chan int, b.N) + var wg sync.WaitGroup + start := make(chan struct{}) + done := make(chan struct{}) + numProducers := runtime.NumCPU() + sendsPerProducer := b.N / numProducers + wg.Add(numProducers) + for i := 0; i < numProducers; i++ { + go func() { + <-start + for i := 0; i < sendsPerProducer; i++ { + c <- 1 + } + wg.Done() + }() + } + go func() { + for n := range c { + _ = n + } + close(done) + }() + b.ResetTimer() + close(start) + wg.Wait() + close(c) + <-done +}