Improved barrier performance by making it a pointer.
diff --git a/barrier.go b/barrier.go
index 62f71b4..b292389 100644
--- a/barrier.go
+++ b/barrier.go
@@ -1,17 +1,27 @@
package disruptor
-type Barrier []*Sequence
-
-func NewBarrier(upstream ...*Sequence) Barrier {
- buffer := make([]*Sequence, len(upstream))
- copy(buffer, upstream)
- return Barrier(buffer)
+type Barrier struct {
+ single bool
+ cursors []*Sequence
}
-func (this Barrier) Load() int64 {
+func NewBarrier(upstream ...*Sequence) *Barrier {
+ cursors := make([]*Sequence, len(upstream))
+ copy(cursors, upstream)
+ return &Barrier{
+ single: len(cursors) == 1,
+ cursors: cursors,
+ }
+}
+
+func (this *Barrier) Load() int64 {
+ if this.single {
+ return this.cursors[0].Load()
+ }
+
minimum := MaxSequenceValue
- for _, item := range this {
+ for _, item := range this.cursors {
cursor := item.Load()
if cursor < minimum {
minimum = cursor
diff --git a/barrier_test.go b/barrier_test.go
index 38fc6d2..b1ecf9d 100644
--- a/barrier_test.go
+++ b/barrier_test.go
@@ -2,10 +2,20 @@
import "testing"
-func BenchmarkBarrierLoad(b *testing.B) {
- upstream := NewSequence()
- upstream.Store(42)
- barrier := NewBarrier(upstream)
+func BenchmarkBarrierLoadSingle(b *testing.B) {
+ barrier := NewBarrier(NewSequence())
+
+ iterations := int64(b.N)
+ b.ReportAllocs()
+ b.ResetTimer()
+
+ for i := int64(0); i < iterations; i++ {
+ barrier.Load()
+ }
+}
+
+func BenchmarkBarrierLoadMultiple(b *testing.B) {
+ barrier := NewBarrier(NewSequence(), NewSequence(), NewSequence(), NewSequence())
iterations := int64(b.N)
b.ReportAllocs()
diff --git a/example/consumer.go b/example/consumer.go
index 33de651..3216d84 100644
--- a/example/consumer.go
+++ b/example/consumer.go
@@ -6,7 +6,7 @@
"github.com/smartystreets/go-disruptor"
)
-func consume(barrier disruptor.Barrier, source, sequence *disruptor.Sequence) {
+func consume(barrier *disruptor.Barrier, source, sequence *disruptor.Sequence) {
worker := disruptor.NewWorker(barrier, &ConsumerHandler{time.Now()}, source, sequence)
for {
diff --git a/example/main.go b/example/main.go
index 4844aa9..714f94e 100644
--- a/example/main.go
+++ b/example/main.go
@@ -20,7 +20,7 @@
sequencer := disruptor.NewSingleProducerSequencer(producerSequence, RingSize, consumerBarrier)
publish(sequencer)
}
-func startConsumers(barrier disruptor.Barrier, sequence *disruptor.Sequence) (consumers []*disruptor.Sequence) {
+func startConsumers(barrier *disruptor.Barrier, sequence *disruptor.Sequence) (consumers []*disruptor.Sequence) {
for i := 0; i < MaxConsumers; i++ {
sequence := disruptor.NewSequence()
consumers = append(consumers, sequence)
diff --git a/single_sequencer.go b/single_sequencer.go
index 6d6bbbc..0b2aad7 100644
--- a/single_sequencer.go
+++ b/single_sequencer.go
@@ -5,10 +5,10 @@
gate int64
cursor *Sequence
ringSize int64
- barrier Barrier
+ barrier *Barrier
}
-func NewSingleProducerSequencer(cursor *Sequence, ringSize int32, barrier Barrier) *SingleProducerSequencer {
+func NewSingleProducerSequencer(cursor *Sequence, ringSize int32, barrier *Barrier) *SingleProducerSequencer {
if !isPowerOfTwo(ringSize) {
panic("The ring size must be a power of two, e.g. 2, 4, 8, 16, 32, 64, etc.")
}
diff --git a/single_sequencer_test.go b/single_sequencer_test.go
index c6ac3d4..ea5c714 100644
--- a/single_sequencer_test.go
+++ b/single_sequencer_test.go
@@ -3,7 +3,7 @@
import "testing"
func BenchmarkSingleProducerSequencerPublish(b *testing.B) {
- sequencer := NewSingleProducerSequencer(NewSequence(), 1024, Barrier{})
+ sequencer := NewSingleProducerSequencer(NewSequence(), 1024, &Barrier{})
iterations := int64(b.N)
b.ReportAllocs()
b.ResetTimer()
diff --git a/worker.go b/worker.go
index e6fd990..1c5de44 100644
--- a/worker.go
+++ b/worker.go
@@ -6,13 +6,13 @@
)
type Worker struct {
- barrier Barrier
+ barrier *Barrier
handler Consumer
source *Sequence
sequence *Sequence
}
-func NewWorker(barrier Barrier, handler Consumer, source, sequence *Sequence) *Worker {
+func NewWorker(barrier *Barrier, handler Consumer, source, sequence *Sequence) *Worker {
return &Worker{
barrier: barrier,
handler: handler,