Skip to content

Commit 0fbb736

Browse files
committed
Atomic operations JMH benchmarks
1 parent eb8254e commit 0fbb736

File tree

1 file changed

+268
-0
lines changed

1 file changed

+268
-0
lines changed
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
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.internal;
18+
19+
import java.util.concurrent.TimeUnit;
20+
import java.util.concurrent.atomic.AtomicInteger;
21+
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
22+
import java.util.concurrent.atomic.AtomicLong;
23+
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
24+
25+
import org.openjdk.jmh.annotations.Benchmark;
26+
import org.openjdk.jmh.annotations.BenchmarkMode;
27+
import org.openjdk.jmh.annotations.Mode;
28+
import org.openjdk.jmh.annotations.OutputTimeUnit;
29+
import org.openjdk.jmh.annotations.Param;
30+
import org.openjdk.jmh.annotations.Scope;
31+
import org.openjdk.jmh.annotations.State;
32+
import org.openjdk.jmh.infra.Blackhole;
33+
34+
/**
35+
* Benchmark typical atomic operations on volatile fields and AtomicXYZ classes.
36+
* <p>
37+
* gradlew benchmarks "-Pjmh=-f 1 -tu s -bm thrpt -wi 5 -i 5 -r 1 .*AtomicPerf.*"
38+
* <p>
39+
* gradlew benchmarks "-Pjmh=-f 1 -tu ns -bm avgt -wi 5 -i 5 -r 1 .*AtomicPerf.*"
40+
*/
41+
@BenchmarkMode(Mode.Throughput)
42+
@OutputTimeUnit(TimeUnit.SECONDS)
43+
public class AtomicPerf {
44+
@State(Scope.Thread)
45+
public static class Times {
46+
@Param({ "1", "1000", "1000000" })
47+
public int times;
48+
}
49+
@State(Scope.Thread)
50+
public static class VolatileIntState {
51+
public volatile int value;
52+
}
53+
@State(Scope.Thread)
54+
public static class VolatileLongState {
55+
public volatile long value;
56+
}
57+
@State(Scope.Thread)
58+
public static class VolatileIntFieldState {
59+
public volatile int value;
60+
public static final AtomicIntegerFieldUpdater<VolatileIntFieldState> UPDATER
61+
= AtomicIntegerFieldUpdater.newUpdater(VolatileIntFieldState.class, "value");
62+
}
63+
@State(Scope.Thread)
64+
public static class VolatileLongFieldState {
65+
public volatile long value;
66+
public static final AtomicLongFieldUpdater<VolatileLongFieldState> UPDATER
67+
= AtomicLongFieldUpdater.newUpdater(VolatileLongFieldState.class, "value");
68+
}
69+
@State(Scope.Thread)
70+
public static class AtomicIntState {
71+
public final AtomicInteger value = new AtomicInteger();
72+
}
73+
@State(Scope.Thread)
74+
public static class AtomicLongState {
75+
public final AtomicLong value = new AtomicLong();
76+
}
77+
78+
// -----------------------------------------------------------------------------------
79+
80+
@Benchmark
81+
public void volatileIntRead(VolatileIntState state, Times repeat, Blackhole bh) {
82+
for (int i = 0; i < repeat.times; i++) {
83+
bh.consume(state.value);
84+
}
85+
}
86+
@Benchmark
87+
public void volatileLongRead(VolatileLongState state, Times repeat, Blackhole bh) {
88+
for (int i = 0; i < repeat.times; i++) {
89+
bh.consume(state.value);
90+
}
91+
}
92+
@Benchmark
93+
public void volatileIntWrite(VolatileIntState state, Times repeat) {
94+
for (int i = 0; i < repeat.times; i++) {
95+
state.value = 1;
96+
}
97+
}
98+
@Benchmark
99+
public void volatileLongWrite(VolatileLongState state, Times repeat) {
100+
for (int i = 0; i < repeat.times; i++) {
101+
state.value = 1L;
102+
}
103+
}
104+
// -------------------------------------------------------------
105+
@Benchmark
106+
public void atomicIntIncrementAndGet(AtomicIntState state, Times repeat, Blackhole bh) {
107+
for (int i = 0; i < repeat.times; i++) {
108+
bh.consume(state.value.incrementAndGet());
109+
}
110+
}
111+
@Benchmark
112+
public void atomicIntGetAndIncrement(AtomicIntState state, Times repeat, Blackhole bh) {
113+
for (int i = 0; i < repeat.times; i++) {
114+
bh.consume(state.value.getAndIncrement());
115+
}
116+
}
117+
@Benchmark
118+
public void atomicLongIncrementAndGet(AtomicLongState state, Times repeat, Blackhole bh) {
119+
for (int i = 0; i < repeat.times; i++) {
120+
bh.consume(state.value.incrementAndGet());
121+
}
122+
}
123+
@Benchmark
124+
public void atomicLongGetAndIncrement(AtomicLongState state, Times repeat, Blackhole bh) {
125+
for (int i = 0; i < repeat.times; i++) {
126+
bh.consume(state.value.getAndIncrement());
127+
}
128+
}
129+
130+
@Benchmark
131+
public void atomicIntLazySet(AtomicIntState state, Times repeat, Blackhole bh) {
132+
for (int i = 0; i < repeat.times; i++) {
133+
state.value.lazySet(1);
134+
}
135+
}
136+
@Benchmark
137+
public void atomicLongLazySet(AtomicLongState state, Times repeat, Blackhole bh) {
138+
for (int i = 0; i < repeat.times; i++) {
139+
state.value.lazySet(1L);
140+
}
141+
}
142+
143+
@Benchmark
144+
public void atomicIntCASSuccess(AtomicIntState state, Times repeat, Blackhole bh) {
145+
state.value.set(0);
146+
for (int i = 0; i < repeat.times; i++) {
147+
bh.consume(state.value.compareAndSet(i, i + 1));
148+
}
149+
}
150+
@Benchmark
151+
public void atomicLongCASSuccess(AtomicLongState state, Times repeat, Blackhole bh) {
152+
state.value.set(0L);
153+
for (long i = 0; i < repeat.times; i++) {
154+
bh.consume(state.value.compareAndSet(i, i + 1));
155+
}
156+
}
157+
@Benchmark
158+
public void atomicIntCASCheckSuccess(AtomicIntState state, Times repeat, Blackhole bh) {
159+
state.value.set(0);
160+
for (int i = 0; i < repeat.times; i++) {
161+
if (state.value.get() == i) {
162+
bh.consume(state.value.compareAndSet(i, i + 1));
163+
}
164+
}
165+
}
166+
@Benchmark
167+
public void atomicLongCASCheckSuccess(AtomicLongState state, Times repeat, Blackhole bh) {
168+
state.value.set(0L);
169+
for (long i = 0; i < repeat.times; i++) {
170+
if (state.value.get() == i) {
171+
bh.consume(state.value.compareAndSet(i, i + 1));
172+
}
173+
}
174+
}
175+
@Benchmark
176+
public void atomicIntCASFailure(AtomicIntState state, Times repeat, Blackhole bh) {
177+
for (int i = 0; i < repeat.times; i++) {
178+
bh.consume(state.value.compareAndSet(1, 2));
179+
}
180+
}
181+
@Benchmark
182+
public void atomicLongCASFailure(AtomicLongState state, Times repeat, Blackhole bh) {
183+
for (int i = 0; i < repeat.times; i++) {
184+
bh.consume(state.value.compareAndSet(1L, 2L));
185+
}
186+
}
187+
@Benchmark
188+
public void atomicIntCASCheckFailure(AtomicIntState state, Times repeat, Blackhole bh) {
189+
for (int i = 0; i < repeat.times; i++) {
190+
if (state.value.get() == 1) {
191+
bh.consume(state.value.compareAndSet(1, 2));
192+
}
193+
}
194+
}
195+
@Benchmark
196+
public void atomicLongCASCheckFailure(AtomicLongState state, Times repeat, Blackhole bh) {
197+
for (int i = 0; i < repeat.times; i++) {
198+
if (state.value.get() == 1L) {
199+
bh.consume(state.value.compareAndSet(1L, 2L));
200+
}
201+
}
202+
}
203+
// ----------------------------------
204+
@Benchmark
205+
public void atomicIntFieldIncrementAndGet(VolatileIntFieldState state, Times repeat, Blackhole bh) {
206+
for (int i = 0; i < repeat.times; i++) {
207+
bh.consume(VolatileIntFieldState.UPDATER.incrementAndGet(state));
208+
}
209+
}
210+
@Benchmark
211+
public void atomicIntFieldGetAndIncrement(VolatileIntFieldState state, Times repeat, Blackhole bh) {
212+
for (int i = 0; i < repeat.times; i++) {
213+
bh.consume(VolatileIntFieldState.UPDATER.getAndIncrement(state));
214+
}
215+
}
216+
@Benchmark
217+
public void atomicLongFieldIncrementAndGet(VolatileLongFieldState state, Times repeat, Blackhole bh) {
218+
for (int i = 0; i < repeat.times; i++) {
219+
bh.consume(VolatileLongFieldState.UPDATER.incrementAndGet(state));
220+
}
221+
}
222+
@Benchmark
223+
public void atomicLongFieldGetAndIncrement(VolatileLongFieldState state, Times repeat, Blackhole bh) {
224+
for (int i = 0; i < repeat.times; i++) {
225+
bh.consume(VolatileLongFieldState.UPDATER.getAndIncrement(state));
226+
}
227+
}
228+
229+
@Benchmark
230+
public void atomicIntFieldLazySet(VolatileIntFieldState state, Times repeat, Blackhole bh) {
231+
for (int i = 0; i < repeat.times; i++) {
232+
VolatileIntFieldState.UPDATER.lazySet(state, 1);
233+
}
234+
}
235+
@Benchmark
236+
public void atomicLongFieldLazySet(VolatileLongFieldState state, Times repeat, Blackhole bh) {
237+
for (int i = 0; i < repeat.times; i++) {
238+
VolatileLongFieldState.UPDATER.lazySet(state, 1L);
239+
}
240+
}
241+
242+
@Benchmark
243+
public void atomicIntFieldCASSuccess(VolatileIntFieldState state, Times repeat, Blackhole bh) {
244+
state.value = 0;
245+
for (int i = 0; i < repeat.times; i++) {
246+
bh.consume(VolatileIntFieldState.UPDATER.compareAndSet(state, i, i + 1));
247+
}
248+
}
249+
@Benchmark
250+
public void atomicLongFieldCASSuccess(VolatileLongFieldState state, Times repeat, Blackhole bh) {
251+
state.value = 0L;
252+
for (long i = 0; i < repeat.times; i++) {
253+
bh.consume(VolatileLongFieldState.UPDATER.compareAndSet(state, i, i + 1));
254+
}
255+
}
256+
@Benchmark
257+
public void atomicIntFieldCASFailure(VolatileIntFieldState state, Times repeat, Blackhole bh) {
258+
for (int i = 0; i < repeat.times; i++) {
259+
bh.consume(VolatileIntFieldState.UPDATER.compareAndSet(state, 1, 2));
260+
}
261+
}
262+
@Benchmark
263+
public void atomicLongFieldCASFailure(VolatileLongFieldState state, Times repeat, Blackhole bh) {
264+
for (int i = 0; i < repeat.times; i++) {
265+
bh.consume(VolatileLongFieldState.UPDATER.compareAndSet(state, 1L, 2L));
266+
}
267+
}
268+
}

0 commit comments

Comments
 (0)