Added code to benchmark disruptor scenarios.
diff --git a/benchmarks/single_writer_test.go b/benchmarks/single_writer_test.go
index 2e0d266..9eb35e3 100644
--- a/benchmarks/single_writer_test.go
+++ b/benchmarks/single_writer_test.go
@@ -1,6 +1,7 @@
package benchmarks
import (
+ "math"
"runtime"
"testing"
@@ -8,32 +9,55 @@
)
const singleWriterRingBufferSize = 1024 * 16
+const singleWriterRingBufferMask = singleWriterRingBufferSize - 1
-func BenchmarkSingleWriter(b *testing.B) {
+func BenchmarkDisruptorWriterSingleClaim(b *testing.B) {
+ benchmarkSingleWriter(b, 1)
+}
+func BenchmarkDisruptorWriterClaimMultiple(b *testing.B) {
+ benchmarkSingleWriter(b, 32)
+}
+
+func benchmarkSingleWriter(b *testing.B, maxClaim int64) {
written, read := disruptor.NewCursor(), disruptor.NewCursor()
reader := disruptor.NewReader(read, written, written)
writer := disruptor.NewWriter(written, read, singleWriterRingBufferSize)
iterations := int64(b.N)
+ ringBuffer := [singleWriterRingBufferSize]int64{}
+ claim := (int64(math.Log2(float64(iterations))) + 1)
+ if claim >= maxClaim {
+ claim = maxClaim
+ }
+
b.ReportAllocs()
b.ResetTimer()
go func() {
- for i := int64(0); i < iterations; i++ {
- if lower, upper := writer.Reserve(1); upper >= 0 {
+ sequence := int64(0)
+ for sequence < iterations {
+ if lower, upper := writer.Reserve(claim); upper >= 0 {
+ for ; sequence <= upper; sequence++ {
+ ringBuffer[sequence&singleWriterRingBufferMask] = sequence
+ }
+
writer.Commit(lower, upper)
+ sequence = upper
}
}
}()
- for {
- _, upper := reader.Receive()
- if upper >= 0 {
- reader.Commit(upper)
-
- if upper+1 == iterations {
- break
+ sequence := int64(0)
+ for sequence < iterations {
+ if _, upper := reader.Receive(); upper >= 0 {
+ for ; sequence <= upper; sequence++ {
+ if sequence != ringBuffer[sequence&singleWriterRingBufferMask] {
+ panic("Out of sequence")
+ }
}
+
+ reader.Commit(upper)
+ sequence = upper
}
}
}