Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benwtrent/b74254bf64aba0c55d4b24a474f9eff1 to your computer and use it in GitHub Desktop.
Save benwtrent/b74254bf64aba0c55d4b24a474f9eff1 to your computer and use it in GitHub Desktop.
package org.elasticsearch.benchmark.ml;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Warmup(iterations = 5)
@Measurement(iterations = 10)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Fork(2)
@State(Scope.Benchmark)
@SuppressWarnings("unused")
public class MultiThreadedStatsAccumulatorBenchmark {
private static ReadWriteLockAccumulator readWriteLockAccumulator;
private static SynchronizedAccumulator synchronizedAccumulator;
@Setup(Level.Iteration)
public void setup() {
readWriteLockAccumulator = new ReadWriteLockAccumulator();
synchronizedAccumulator = new SynchronizedAccumulator();
}
@Benchmark
@Threads(1)
public void rwAccumulator_1(Blackhole bh) {
for (int i = 1; i < 100_001; ++i) {
bh.consume(readWriteLockAccumulator.incMissingFields().incFailure().incInference());
}
}
@Benchmark
@Threads(128)
public void rwAccumulator_128(Blackhole bh) {
for (int i = 1; i < 100_001; ++i) {
bh.consume(readWriteLockAccumulator.incMissingFields().incFailure().incInference());
}
}
@Benchmark
@Threads(1)
public void syncAccumulator_1(Blackhole bh) {
for (int i = 1; i < 100_001; ++i) {
bh.consume(synchronizedAccumulator.incMissingFields().incFailure().incInference());
}
}
@Benchmark
@Threads(128)
public void syncAccumulator_128(Blackhole bh) {
for (int i = 1; i < 100_001; ++i) {
bh.consume(synchronizedAccumulator.incMissingFields().incFailure().incInference());
}
}
public static class InferenceStats {
private final long missingAllFieldsCount;
private final long inferenceCount;
private final long failureCount;
public InferenceStats(long missingAllFieldsCount,
long inferenceCount,
long failureCount) {
this.missingAllFieldsCount = missingAllFieldsCount;
this.inferenceCount = inferenceCount;
this.failureCount = failureCount;
}
}
public static class ReadWriteLockAccumulator {
private final LongAdder missingFieldsAccumulator = new LongAdder();
private final LongAdder inferenceAccumulator = new LongAdder();
private final LongAdder failureCountAccumulator = new LongAdder();
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
public ReadWriteLockAccumulator incMissingFields() {
readWriteLock.readLock().lock();
try {
this.missingFieldsAccumulator.increment();
return this;
} finally {
readWriteLock.readLock().unlock();
}
}
public ReadWriteLockAccumulator incInference() {
readWriteLock.readLock().lock();
try {
this.inferenceAccumulator.increment();
return this;
} finally {
readWriteLock.readLock().unlock();
}
}
public ReadWriteLockAccumulator incFailure() {
readWriteLock.readLock().lock();
try {
this.failureCountAccumulator.increment();
return this;
} finally {
readWriteLock.readLock().unlock();
}
}
/**
* Thread safe.
*
* Returns the current stats and resets the values of all the counters.
* @return The current stats
*/
public InferenceStats currentStatsAndReset() {
readWriteLock.writeLock().lock();
try {
InferenceStats stats = currentStats();
this.missingFieldsAccumulator.reset();
this.inferenceAccumulator.reset();
this.failureCountAccumulator.reset();
return stats;
} finally {
readWriteLock.writeLock().unlock();
}
}
public InferenceStats currentStats() {
return new InferenceStats(missingFieldsAccumulator.longValue(),
inferenceAccumulator.longValue(),
failureCountAccumulator.longValue()
);
}
}
public static class SynchronizedAccumulator {
private long missingFieldsAccumulator = 0L;
private long inferenceAccumulator = 0L;
private long failureCountAccumulator = 0L;
public synchronized SynchronizedAccumulator incMissingFields() {
missingFieldsAccumulator++;
return this;
}
public synchronized SynchronizedAccumulator incInference() {
this.inferenceAccumulator++;
return this;
}
public synchronized SynchronizedAccumulator incFailure() {
this.failureCountAccumulator++;
return this;
}
public synchronized InferenceStats currentStatsAndReset() {
InferenceStats stats = currentStats();
this.missingFieldsAccumulator = 0L;
this.inferenceAccumulator = 0L;
this.failureCountAccumulator = 0L;
return stats;
}
public InferenceStats currentStats() {
return new InferenceStats(missingFieldsAccumulator,
inferenceAccumulator,
failureCountAccumulator
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment