Skip to content

Commit e802bb7

Browse files
committed
Merge pull request #3495 from akarnokd/JustPerf1x
1.x: benchmark just() and its optimizations.
2 parents b293751 + 88ea092 commit e802bb7

File tree

1 file changed

+197
-0
lines changed

1 file changed

+197
-0
lines changed

src/perf/java/rx/ScalarJustPerf.java

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/**
2+
* Copyright 2014 Netflix, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package rx;
18+
19+
import java.util.concurrent.TimeUnit;
20+
21+
import org.openjdk.jmh.annotations.*;
22+
import org.openjdk.jmh.infra.Blackhole;
23+
24+
import rx.functions.Func1;
25+
import rx.jmh.LatchedObserver;
26+
import rx.schedulers.Schedulers;
27+
28+
/**
29+
* Benchmark the cost of just and its various optimizations.
30+
* <p>
31+
* gradlew benchmarks "-Pjmh=-f 1 -tu s -bm thrpt -wi 5 -i 5 -r 1 .*ScalarJustPerf.*"
32+
* <p>
33+
* gradlew benchmarks "-Pjmh=-f 1 -tu ns -bm avgt -wi 5 -i 5 -r 1 .*ScalarJustPerf.*"
34+
*/
35+
@BenchmarkMode(Mode.Throughput)
36+
@OutputTimeUnit(TimeUnit.SECONDS)
37+
@State(Scope.Thread)
38+
public class ScalarJustPerf {
39+
/** A subscriber without a CountDownLatch; use it for synchronous testing only. */
40+
static final class PlainSubscriber extends Subscriber<Integer> {
41+
final Blackhole bh;
42+
public PlainSubscriber(Blackhole bh) {
43+
this.bh = bh;
44+
}
45+
46+
@Override
47+
public void onNext(Integer t) {
48+
bh.consume(t);
49+
}
50+
51+
@Override
52+
public void onError(Throwable e) {
53+
bh.consume(e);
54+
}
55+
56+
@Override
57+
public void onCompleted() {
58+
bh.consume(false);
59+
}
60+
}
61+
62+
/** This is a simple just. */
63+
Observable<Integer> simple;
64+
/**
65+
* This is a simple just observed on the computation scheduler.
66+
* The current computation scheduler supports direct scheduling and should have
67+
* lower overhead than a regular createWorker-use-unsubscribe.
68+
*/
69+
Observable<Integer> observeOn;
70+
/** This is a simple just observed on the IO thread. */
71+
Observable<Integer> observeOnIO;
72+
73+
/**
74+
* This is a simple just subscribed to on the computation scheduler.
75+
* In theory, for non-backpressured just(), this should be the
76+
* same as observeOn.
77+
*/
78+
Observable<Integer> subscribeOn;
79+
/** This is a simple just subscribed to on the IO scheduler. */
80+
Observable<Integer> subscribeOnIO;
81+
82+
/** This is a just mapped to itself which should skip the operator flatMap completely. */
83+
Observable<Integer> justFlatMapJust;
84+
/**
85+
* This is a just mapped to a range of 2 elements; it tests the case where the inner
86+
* Observable isn't a just().
87+
*/
88+
Observable<Integer> justFlatMapRange;
89+
90+
@Setup
91+
public void setup() {
92+
simple = Observable.just(1);
93+
94+
observeOn = simple.observeOn(Schedulers.computation());
95+
observeOnIO = simple.observeOn(Schedulers.io());
96+
97+
subscribeOn = simple.subscribeOn(Schedulers.computation());
98+
subscribeOnIO = simple.subscribeOn(Schedulers.io());
99+
100+
justFlatMapJust = simple.flatMap(new Func1<Integer, Observable<Integer>>() {
101+
@Override
102+
public Observable<Integer> call(Integer v) {
103+
return Observable.just(v);
104+
}
105+
});
106+
107+
justFlatMapRange = simple.flatMap(new Func1<Integer, Observable<Integer>>() {
108+
@Override
109+
public Observable<Integer> call(Integer v) {
110+
return Observable.range(v, 2);
111+
}
112+
});
113+
}
114+
115+
/**
116+
* Common routine to create a latched observer, subscribe it to the
117+
* given source and spin-wait for its completion.
118+
* <p>Don't use this with long sources. The spin-wait is there
119+
* to avoid operating-system level scheduling-wakeup granularity problems with
120+
* short sources.
121+
* @param bh the black hole to sink values and prevent dead code elimination
122+
* @param source the source observable to observe
123+
*/
124+
void runAsync(Blackhole bh, Observable<Integer> source) {
125+
LatchedObserver<Integer> lo = new LatchedObserver<Integer>(bh);
126+
127+
source.subscribe(lo);
128+
129+
while (lo.latch.getCount() != 0L);
130+
}
131+
132+
@Benchmark
133+
public void simple(Blackhole bh) {
134+
PlainSubscriber s = new PlainSubscriber(bh);
135+
simple.subscribe(s);
136+
}
137+
138+
@Benchmark
139+
public void simpleEscape(Blackhole bh) {
140+
PlainSubscriber s = new PlainSubscriber(bh);
141+
bh.consume(s);
142+
simple.subscribe(s);
143+
}
144+
145+
@Benchmark
146+
public Object simpleEscapeAll(Blackhole bh) {
147+
PlainSubscriber s = new PlainSubscriber(bh);
148+
bh.consume(s);
149+
return simple.subscribe(s);
150+
}
151+
152+
@Benchmark
153+
public void observeOn(Blackhole bh) {
154+
runAsync(bh, observeOn);
155+
}
156+
157+
@Benchmark
158+
public void observeOnIO(Blackhole bh) {
159+
runAsync(bh, observeOnIO);
160+
}
161+
162+
@Benchmark
163+
public void subscribeOn(Blackhole bh) {
164+
runAsync(bh, subscribeOn);
165+
}
166+
167+
@Benchmark
168+
public void subscribeOnIO(Blackhole bh) {
169+
runAsync(bh, subscribeOnIO);
170+
}
171+
172+
@Benchmark
173+
public void justFlatMapJust(Blackhole bh) {
174+
PlainSubscriber s = new PlainSubscriber(bh);
175+
justFlatMapJust.subscribe(s);
176+
}
177+
178+
@Benchmark
179+
public void justFlatMapJustEscape(Blackhole bh) {
180+
PlainSubscriber s = new PlainSubscriber(bh);
181+
bh.consume(s);
182+
justFlatMapJust.subscribe(s);
183+
}
184+
185+
@Benchmark
186+
public void justFlatMapRange(Blackhole bh) {
187+
PlainSubscriber s = new PlainSubscriber(bh);
188+
justFlatMapRange.subscribe(s);
189+
}
190+
191+
@Benchmark
192+
public void justFlatMapRangeEscape(Blackhole bh) {
193+
PlainSubscriber s = new PlainSubscriber(bh);
194+
bh.consume(s);
195+
justFlatMapRange.subscribe(s);
196+
}
197+
}

0 commit comments

Comments
 (0)