21
21
import rx .Subscription ;
22
22
import rx .exceptions .MissingBackpressureException ;
23
23
import rx .internal .operators .NotificationLite ;
24
- import rx .internal .util .unsafe .SpmcArrayQueue ;
25
- import rx .internal .util .unsafe .SpscArrayQueue ;
26
24
import rx .internal .util .unsafe .UnsafeAccess ;
27
25
28
26
/**
@@ -33,15 +31,28 @@ public class RxRingBuffer implements Subscription {
33
31
34
32
public static RxRingBuffer getSpscInstance () {
35
33
if (UnsafeAccess .isUnsafeAvailable ()) {
36
- return new RxRingBuffer (SPSC_POOL , SIZE );
34
+ // using SynchronizedQueue until issues are solved with SpscArrayQueue offer rejection
35
+ // RxRingBufferSpmcTest.testConcurrency occasionally fails with a
36
+ // BackpressureException when using SpscArrayQueue
37
+ // return new RxRingBuffer(SPSC_POOL, SIZE); // this is the one we were trying to use
38
+ // return new RxRingBuffer(new SpscArrayQueue<Object>(SIZE), SIZE);
39
+ // the performance of this is sufficient (actually faster in some cases)
40
+ return new RxRingBuffer (new SynchronizedQueue <Object >(SIZE ), SIZE );
37
41
} else {
38
42
return new RxRingBuffer ();
39
43
}
40
44
}
41
45
42
46
public static RxRingBuffer getSpmcInstance () {
43
47
if (UnsafeAccess .isUnsafeAvailable ()) {
44
- return new RxRingBuffer (SPMC_POOL , SIZE );
48
+ // using SynchronizedQueue until issues are solved with SpmcArrayQueue offer rejection
49
+ // RxRingBufferSpmcTest.testConcurrency occasionally fails with a
50
+ // BackpressureException when using SpmcArrayQueue/MpmcArrayQueue
51
+ // return new RxRingBuffer(SPMC_POOL, SIZE); // this is the one we were trying to use
52
+ // return new RxRingBuffer(new SpmcArrayQueue<Object>(SIZE), SIZE);
53
+ // return new RxRingBuffer(new MpmcArrayQueue<Object>(SIZE), SIZE);
54
+ // the performance of this is sufficient (actually faster in some cases)
55
+ return new RxRingBuffer (new SynchronizedQueue <Object >(SIZE ), SIZE );
45
56
} else {
46
57
return new RxRingBuffer ();
47
58
}
@@ -75,7 +86,7 @@ public static RxRingBuffer getSpmcInstance() {
75
86
* r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 23951121.098 1982380.330 ops/s
76
87
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 1142.351 33.592 ops/s
77
88
*
78
- * With SynchronizedQueue (synchronized LinkedList)
89
+ * With SynchronizedQueue (synchronized LinkedList ... no object pooling )
79
90
*
80
91
* r.i.RxRingBufferPerf.createUseAndDestroy1 thrpt 5 33231667.136 685757.510 ops/s
81
92
* r.i.RxRingBufferPerf.createUseAndDestroy1000 thrpt 5 74623.614 5493.766 ops/s
@@ -119,11 +130,11 @@ public static RxRingBuffer getSpmcInstance() {
119
130
* With SpmcArrayQueue
120
131
* - requires access to Unsafe
121
132
*
122
- * Benchmark Mode Samples Score Score error Units
123
- * r.i.RxRingBufferPerf.createUseAndDestroy1 thrpt 5 1835494.523 63874.461 ops/s
124
- * r.i.RxRingBufferPerf.createUseAndDestroy1000 thrpt 5 45545.599 1882.146 ops/s
125
- * r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 38126258.816 474874.236 ops/s
126
- * r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 42507.743 240.530 ops/s
133
+ * Benchmark Mode Samples Score Score error Units
134
+ * r.i.RxRingBufferPerf.spmcCreateUseAndDestroy1 thrpt 5 27630345.474 769219.142 ops/s
135
+ * r.i.RxRingBufferPerf.spmcCreateUseAndDestroy1000 thrpt 5 80052.046 4059.541 ops/s
136
+ * r.i.RxRingBufferPerf.spmcRingBufferAddRemove1 thrpt 5 44449524.222 563068.793 ops/s
137
+ * r.i.RxRingBufferPerf.spmcRingBufferAddRemove1000 thrpt 5 65231.253 1805.732 ops/s
127
138
*
128
139
* With SpmcArrayQueue and ObjectPool (object pool improves createUseAndDestroy1 by 10x)
129
140
*
@@ -135,17 +146,7 @@ public static RxRingBuffer getSpmcInstance() {
135
146
*
136
147
* --------------
137
148
*
138
- * When UnsafeAccess.isUnsafeAvailable() == true we can use the Spmc/SpscArrayQueue implementations and get these numbers:
139
- *
140
- * Benchmark Mode Samples Score Score error Units
141
- * r.i.RxRingBufferPerf.spmcCreateUseAndDestroy1 thrpt 5 17813072.116 672207.872 ops/s
142
- * r.i.RxRingBufferPerf.spmcCreateUseAndDestroy1000 thrpt 5 46794.691 1146.195 ops/s
143
- * r.i.RxRingBufferPerf.spmcRingBufferAddRemove1 thrpt 5 32117630.315 749011.552 ops/s
144
- * r.i.RxRingBufferPerf.spmcRingBufferAddRemove1000 thrpt 5 47257.476 1081.623 ops/s
145
- * r.i.RxRingBufferPerf.spscCreateUseAndDestroy1 thrpt 5 24729994.601 353101.940 ops/s
146
- * r.i.RxRingBufferPerf.spscCreateUseAndDestroy1000 thrpt 5 73101.460 2406.377 ops/s
147
- * r.i.RxRingBufferPerf.spscRingBufferAddRemove1 thrpt 5 83548821.062 752738.756 ops/s
148
- * r.i.RxRingBufferPerf.spscRingBufferAddRemove1000 thrpt 5 70549.816 1377.227 ops/s
149
+ * When UnsafeAccess.isUnsafeAvailable() == true we can use the Spmc/SpscArrayQueue implementations.
149
150
*
150
151
* } </pre>
151
152
*/
@@ -169,30 +170,13 @@ public static RxRingBuffer getSpmcInstance() {
169
170
170
171
public static final int SIZE = 1024 ;
171
172
172
- private static ObjectPool <Queue <Object >> SPSC_POOL = new ObjectPool <Queue <Object >>() {
173
-
174
- @ Override
175
- protected SpscArrayQueue <Object > createObject () {
176
- return new SpscArrayQueue <Object >(SIZE );
177
- }
178
-
179
- };
180
-
181
- private static ObjectPool <Queue <Object >> SPMC_POOL = new ObjectPool <Queue <Object >>() {
182
-
183
- @ Override
184
- protected SpmcArrayQueue <Object > createObject () {
185
- return new SpmcArrayQueue <Object >(SIZE );
186
- }
187
-
188
- };
189
-
190
173
private RxRingBuffer (Queue <Object > queue , int size ) {
191
174
this .queue = queue ;
192
175
this .pool = null ;
193
176
this .size = size ;
194
177
}
195
178
179
+ @ SuppressWarnings ("unused" )
196
180
private RxRingBuffer (ObjectPool <Queue <Object >> pool , int size ) {
197
181
this .pool = pool ;
198
182
this .queue = pool .borrowObject ();
@@ -213,7 +197,7 @@ public void unsubscribe() {
213
197
release ();
214
198
}
215
199
216
- /* for unit tests */ RxRingBuffer () {
200
+ /* package accessible for unit tests */ RxRingBuffer () {
217
201
this (new SynchronizedQueue <Object >(SIZE ), SIZE );
218
202
}
219
203
@@ -260,7 +244,7 @@ public int count() {
260
244
}
261
245
return queue .size ();
262
246
}
263
-
247
+
264
248
public boolean isEmpty () {
265
249
if (queue == null ) {
266
250
return true ;
@@ -294,7 +278,7 @@ public Object poll() {
294
278
}
295
279
return o ;
296
280
}
297
-
281
+
298
282
public Object peek () {
299
283
if (queue == null ) {
300
284
// we are unsubscribed and have released the undelrying queue
0 commit comments