BAEL-1423 Java Concurrency Utility with JCTools Library

Refactored JMH benchmark after digging deeper into its features
This commit is contained in:
Denis Zhdanov 2018-04-02 04:32:05 +03:00
parent f4feab9212
commit b296e9a496
1 changed files with 32 additions and 57 deletions

View File

@ -14,82 +14,57 @@ import java.util.concurrent.TimeUnit;
@Fork(1) @Fork(1)
@Warmup(iterations = 1) @Warmup(iterations = 1)
@Measurement(iterations = 3) @Measurement(iterations = 3)
@State(Scope.Group)
public class MpmcBenchmark { public class MpmcBenchmark {
public static final String GROUP_UNSAFE = "MpmcArrayQueue"; public static final String PARAM_UNSAFE = "MpmcArrayQueue";
public static final String GROUP_AFU = "MpmcAtomicArrayQueue"; public static final String PARAM_AFU = "MpmcAtomicArrayQueue";
public static final String GROUP_JDK = "ArrayBlockingQueue"; public static final String PARAM_JDK = "ArrayBlockingQueue";
public static final int PRODUCER_THREADS_NUMBER = 32; public static final int PRODUCER_THREADS_NUMBER = 32;
public static final int CONSUMER_THREADS_NUMBER = 32; public static final int CONSUMER_THREADS_NUMBER = 32;
public static final String GROUP_NAME = "MyGroup";
public static final int CAPACITY = 128; public static final int CAPACITY = 128;
@State(Scope.Group) @Param({PARAM_UNSAFE, PARAM_AFU, PARAM_JDK})
public static class Mpmc { public volatile String implementation;
public final Queue<Long> queue = new MpmcArrayQueue<>(CAPACITY);
public volatile Queue<Long> queue;
@Setup(Level.Trial)
public void setUp() {
switch (implementation) {
case PARAM_UNSAFE:
queue = new MpmcArrayQueue<>(CAPACITY);
break;
case PARAM_AFU:
queue = new MpmcAtomicArrayQueue<>(CAPACITY);
break;
case PARAM_JDK:
queue = new ArrayBlockingQueue<>(CAPACITY);
break;
default:
throw new UnsupportedOperationException("Unsupported implementation " + implementation);
}
} }
@State(Scope.Group)
public static class MpmcAtomic {
public final Queue<Long> queue = new MpmcAtomicArrayQueue<>(CAPACITY);
}
@State(Scope.Group)
public static class Jdk {
public final Queue<Long> queue = new ArrayBlockingQueue<>(CAPACITY);
}
@Benchmark @Benchmark
@Group(GROUP_UNSAFE) @Group(GROUP_NAME)
@GroupThreads(PRODUCER_THREADS_NUMBER) @GroupThreads(PRODUCER_THREADS_NUMBER)
public void mpmcWrite(Control control, Mpmc state) { public void write(Control control) {
write(control, state.queue);
}
@Benchmark
@Group(GROUP_UNSAFE)
@GroupThreads(CONSUMER_THREADS_NUMBER)
public void mpmcRead(Control control, Mpmc state) {
read(control, state.queue);
}
@Benchmark
@Group(GROUP_AFU)
@GroupThreads(PRODUCER_THREADS_NUMBER)
public void mpmcAtomicWrite(Control control, MpmcAtomic state) {
write(control, state.queue);
}
@Benchmark
@Group(GROUP_AFU)
@GroupThreads(CONSUMER_THREADS_NUMBER)
public void mpmcAtomicRead(Control control, MpmcAtomic state) {
read(control, state.queue);
}
@Benchmark
@Group(GROUP_JDK)
@GroupThreads(PRODUCER_THREADS_NUMBER)
public void jdkWrite(Control control, Jdk state) {
write(control, state.queue);
}
@Benchmark
@Group(GROUP_JDK)
@GroupThreads(CONSUMER_THREADS_NUMBER)
public void jdkRead(Control control, Jdk state) {
read(control, state.queue);
}
private void write(Control control, Queue<Long> queue) {
//noinspection StatementWithEmptyBody //noinspection StatementWithEmptyBody
while (!control.stopMeasurement && !queue.offer(1L)) { while (!control.stopMeasurement && !queue.offer(1L)) {
// Is intentionally left blank // Is intentionally left blank
} }
} }
private void read(Control control, Queue<Long> queue) { @Benchmark
@Group(GROUP_NAME)
@GroupThreads(CONSUMER_THREADS_NUMBER)
public void read(Control control) {
//noinspection StatementWithEmptyBody //noinspection StatementWithEmptyBody
while (!control.stopMeasurement && queue.poll() == null) { while (!control.stopMeasurement && queue.poll() == null) {
// Is intentionally left blank // Is intentionally left blank