rx.internal.util.RxRingBuffer Maven / Gradle / Ivy
The newest version!
/**
* Copyright 2014 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package rx.internal.util;
import java.util.Queue;
import rx.Observer;
import rx.Subscription;
import rx.exceptions.MissingBackpressureException;
import rx.internal.operators.NotificationLite;
import rx.internal.util.atomic.SpscAtomicArrayQueue;
import rx.internal.util.unsafe.SpmcArrayQueue;
import rx.internal.util.unsafe.SpscArrayQueue;
import rx.internal.util.unsafe.UnsafeAccess;
/**
* This assumes Spsc or Spmc usage. This means only a single producer calling the on* methods. This is the Rx
* contract of an Observer (see http://reactivex.io/documentation/contract.html). Concurrent invocations of
* on* methods will not be thread-safe.
*/
public class RxRingBuffer implements Subscription {
/**
* Queue implementation testing that led to current choices of data structures:
*
* With synchronized LinkedList
* {@code
* Benchmark Mode Samples Score Score error Units
* r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 19118392.046 1002814.238 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 17891.641 252.747 ops/s
*
* With MpscPaddedQueue (single consumer, so failing 1 unit test)
*
* Benchmark Mode Samples Score Score error Units
* r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 22164483.238 3035027.348 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 23154.303 602.548 ops/s
*
*
* With ConcurrentLinkedQueue (tracking count separately)
*
* Benchmark Mode Samples Score Score error Units
* r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 17353906.092 378756.411 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 19224.411 1010.610 ops/s
*
* With ConcurrentLinkedQueue (using queue.size() method for count)
*
* Benchmark Mode Samples Score Score error Units
* r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 23951121.098 1982380.330 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 1142.351 33.592 ops/s
*
* With SynchronizedQueue (synchronized LinkedList ... no object pooling)
*
* r.i.RxRingBufferPerf.createUseAndDestroy1 thrpt 5 33231667.136 685757.510 ops/s
* r.i.RxRingBufferPerf.createUseAndDestroy1000 thrpt 5 74623.614 5493.766 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 22907359.257 707026.632 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 22222.410 320.829 ops/s
*
* With ArrayBlockingQueue
*
* Benchmark Mode Samples Score Score error Units
* r.i.RxRingBufferPerf.createUseAndDestroy1 thrpt 5 2389804.664 68990.804 ops/s
* r.i.RxRingBufferPerf.createUseAndDestroy1000 thrpt 5 27384.274 1411.789 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 26497037.559 91176.247 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 17985.144 237.771 ops/s
*
* With ArrayBlockingQueue and Object Pool
*
* Benchmark Mode Samples Score Score error Units
* r.i.RxRingBufferPerf.createUseAndDestroy1 thrpt 5 12465685.522 399070.770 ops/s
* r.i.RxRingBufferPerf.createUseAndDestroy1000 thrpt 5 27701.294 395.217 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 26399625.086 695639.436 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 17985.427 253.190 ops/s
*
* With SpscArrayQueue (single consumer, so failing 1 unit test)
* - requires access to Unsafe
*
* Benchmark Mode Samples Score Score error Units
* r.i.RxRingBufferPerf.createUseAndDestroy1 thrpt 5 1922996.035 49183.766 ops/s
* r.i.RxRingBufferPerf.createUseAndDestroy1000 thrpt 5 70890.186 1382.550 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 80637811.605 3509706.954 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 71822.453 4127.660 ops/s
*
*
* With SpscArrayQueue and Object Pool (object pool improves createUseAndDestroy1 by 10x)
*
* Benchmark Mode Samples Score Score error Units
* r.i.RxRingBufferPerf.createUseAndDestroy1 thrpt 5 25220069.264 1329078.785 ops/s
* r.i.RxRingBufferPerf.createUseAndDestroy1000 thrpt 5 72313.457 3535.447 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1 thrpt 5 81863840.884 2191416.069 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 73140.822 1528.764 ops/s
*
* With SpmcArrayQueue
* - requires access to Unsafe
*
* Benchmark Mode Samples Score Score error Units
* r.i.RxRingBufferPerf.spmcCreateUseAndDestroy1 thrpt 5 27630345.474 769219.142 ops/s
* r.i.RxRingBufferPerf.spmcCreateUseAndDestroy1000 thrpt 5 80052.046 4059.541 ops/s
* r.i.RxRingBufferPerf.spmcRingBufferAddRemove1 thrpt 5 44449524.222 563068.793 ops/s
* r.i.RxRingBufferPerf.spmcRingBufferAddRemove1000 thrpt 5 65231.253 1805.732 ops/s
*
* With SpmcArrayQueue and ObjectPool (object pool improves createUseAndDestroy1 by 10x)
*
* Benchmark Mode Samples Score Score error Units
* r.i.RxRingBufferPerf.createUseAndDestroy1 thrpt 5 18489343.061 1011872.825 ops/s
* r.i.RxRingBufferPerf.createUseAndDestroy1000 thrpt 5 46416.434 1439.144 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove thrpt 5 38280945.847 1071801.279 ops/s
* r.i.RxRingBufferPerf.ringBufferAddRemove1000 thrpt 5 42337.663 1052.231 ops/s
*
* --------------
*
* When UnsafeAccess.isUnsafeAvailable() == true we can use the Spmc/SpscArrayQueue implementations.
*
* }
*/
private Queue