ReactiveX/RxJava — pull request #1953 by akarnokd (2014-12-11 15:46:29+00:00)
Title: Fixed timer cast-to-int crash causing incorrect benchmark.

The perf benchmark uses a 1 millisecond timer to interfere with the serializing process. However, the original benchmark used ```cast(Integer.class)``` which just simply throws an error on a long value thus terminating the whole serialization process almost immediately. What gets measured is how fast can the whole process restarted to fail again.

With the fix, I get the following numbers:
```
Benchmark (size) Score Score error
r.o.OSP.noSerializationSingleThreaded 1 15632242,955 576291,356
r.o.OSP.noSerializationSingleThreaded 1000 143971,769 1129,048
r.o.OSP.noSerializationSingleThreaded 1000000 153,444 8,286
r.o.OSP.serializedSingleStream 1 7249531,621 140827,908
r.o.OSP.serializedSingleStream 1000 52595,958 1845,084
r.o.OSP.serializedSingleStream 1000000 53,001 1,155
r.o.OSP.serializedTwoStreamsHighlyContended 1 143335,868 3643,346
r.o.OSP.serializedTwoStreamsHighlyContended 1000 3453,108 22,826
r.o.OSP.serializedTwoStreamsHighlyContended 1000000 3,113 0,127
r.o.OSP.serializedTwoStreamsOneFastOneSlow 1 99417,300 5162,370
r.o.OSP.serializedTwoStreamsOneFastOneSlow 1000 14857,037 7131,489
r.o.OSP.serializedTwoStreamsSlightlyContended 1 82621,317 1977,208
r.o.OSP.serializedTwoStreamsSlightlyContended 1000 1,007 0,026
```

Clearly, the serializedTwoStreamsSlightlyContended() shows that under a second, you can serialize two 1 millisecond sources.

For comparison with my latest endeavors, the custom WriterReaderPhaser + AtomicResizableArray + Fast-path queue drain with front check produces the following values:
(Mode: thrpt, Samples: 5)
```
r.o.OSP.serializedSingleStream 1 4702012,445 65485,925 64.86%
r.o.OSP.serializedSingleStream 1000 43189,631 1508,771 82.12%
r.o.OSP.serializedSingleStream 1000000 42,384 1,531 79.97%
r.o.OSP.serializedTwoStreamsHighlyContended 1 138302,278 3530,496 96.45%
r.o.OSP.serializedTwoStreamsHighlyContended 1000 3085,205 118,029 89.34%
r.o.OSP.serializedTwoStreamsHighlyContended 1000000 3,284 0,555 105.49%
r.o.OSP.serializedTwoStreamsOneFastOneSlow 1 100760,210 6614,699 101.35%
r.o.OSP.serializedTwoStreamsOneFastOneSlow 1000 1464,140 1015,858 9.85%
r.o.OSP.serializedTwoStreamsSlightlyContended 1 82823,995 835,143 102.44%
r.o.OSP.serializedTwoStreamsSlightlyContended 1000 1,002 0,014
```

A specialized two-way only striped custom WriterReaderPhaser produces these:
```
r.o.OSP2.serializedSingleStream 1 4551488,444 776149,420
r.o.OSP2.serializedSingleStream 1000 14567,954 246,157
r.o.OSP2.serializedSingleStream 1000000 14,358 0,574
r.o.OSP2.serializedTwoStreamsHighlyContended 1 165429,534 1245,682
r.o.OSP2.serializedTwoStreamsHighlyContended 1000 3383,878 62,534
r.o.OSP2.serializedTwoStreamsHighlyContended 1000000 3,459 0,759
r.o.OSP2.serializedTwoStreamsOneFastOneSlow 1 105104,317 1247,636
r.o.OSP2.serializedTwoStreamsOneFastOneSlow 1000 265,691 90,654
r.o.OSP2.serializedTwoStreamsSlightlyContended 1 82814,850 1824,645
r.o.OSP2.serializedTwoStreamsSlightlyContended 1000 1,002 0,014
```

I'm not quite sure why ```serializedTwoStreamsOneFastOneSlow``` is so low in my versions. My guess is that since they are lock-free, the timer's thread ends up shoveling the events more frequently than in the synchronized case (because it can sleep).