Update ThreadLocalRandom benchmark to show issues with contention (#8292)
Previous benchmark was measuring initialization of thread pools and their shutdown, not really measuring performance of Random.nextInt() shared Random instance vs ThreadLocalRandom.current() Example when run with 8 threads Benchmark Mode Cnt Score Error Units ThreadLocalRandomBenchMarker.randomValuesUsingRandom thrpt 20 9.597 ± 0.475 ops/us ThreadLocalRandomBenchMarker.randomValuesUsingThreadLocalRandom thrpt 20 2195.178 ± 109.579 ops/us
This commit is contained in:
parent
edc39bfffd
commit
0b73db930f
@ -1,22 +1,27 @@
|
|||||||
package com.baeldung.threadlocalrandom;
|
package com.baeldung.threadlocalrandom;
|
||||||
|
|
||||||
import org.openjdk.jmh.runner.Runner;
|
import org.openjdk.jmh.runner.Runner;
|
||||||
import org.openjdk.jmh.runner.options.Options;
|
import org.openjdk.jmh.runner.options.ChainedOptionsBuilder;
|
||||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
public class ThreadLocalRandomBenchMarkRunner {
|
public class ThreadLocalRandomBenchMarkRunner {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
Options options = new OptionsBuilder().include(ThreadLocalRandomBenchMarker.class.getSimpleName())
|
ChainedOptionsBuilder options = new OptionsBuilder().include(ThreadLocalRandomBenchMarker.class.getSimpleName())
|
||||||
.threads(1)
|
|
||||||
.forks(1)
|
.forks(1)
|
||||||
.shouldFailOnError(true)
|
.shouldFailOnError(true)
|
||||||
.shouldDoGC(true)
|
.shouldDoGC(true)
|
||||||
.jvmArgs("-server")
|
.jvmArgs("-server");
|
||||||
.build();
|
|
||||||
|
|
||||||
new Runner(options).run();
|
|
||||||
|
|
||||||
|
for (Integer i : ImmutableList.of(1, 2, 8, 32)) {
|
||||||
|
new Runner(
|
||||||
|
options
|
||||||
|
.threads(i)
|
||||||
|
.build())
|
||||||
|
.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,64 +1,34 @@
|
|||||||
package com.baeldung.threadlocalrandom;
|
package com.baeldung.threadlocalrandom;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.openjdk.jmh.annotations.Benchmark;
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
import org.openjdk.jmh.annotations.Level;
|
|
||||||
import org.openjdk.jmh.annotations.Mode;
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
import org.openjdk.jmh.annotations.Scope;
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
import org.openjdk.jmh.annotations.Setup;
|
|
||||||
import org.openjdk.jmh.annotations.State;
|
import org.openjdk.jmh.annotations.State;
|
||||||
import org.openjdk.jmh.annotations.Warmup;
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
@BenchmarkMode(Mode.Throughput)
|
||||||
@Warmup(iterations = 1)
|
@Warmup(iterations = 1)
|
||||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||||
@State(Scope.Benchmark)
|
@State(Scope.Benchmark)
|
||||||
public class ThreadLocalRandomBenchMarker {
|
public class ThreadLocalRandomBenchMarker {
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
List<Callable<Integer>> randomCallables = new ArrayList<>();
|
@Benchmark
|
||||||
List<Callable<Integer>> threadLocalRandomCallables = new ArrayList<>();
|
public int randomValuesUsingRandom() {
|
||||||
|
|
||||||
@Setup(Level.Iteration)
|
|
||||||
public void init() {
|
|
||||||
Random random = new Random();
|
|
||||||
randomCallables = new ArrayList<>();
|
|
||||||
threadLocalRandomCallables = new ArrayList<>();
|
|
||||||
for (int i = 0; i < 1000; i++) {
|
|
||||||
randomCallables.add(() -> {
|
|
||||||
return random.nextInt();
|
return random.nextInt();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 1000; i++) {
|
@Benchmark
|
||||||
threadLocalRandomCallables.add(() -> {
|
public int randomValuesUsingThreadLocalRandom() {
|
||||||
return ThreadLocalRandom.current()
|
return ThreadLocalRandom
|
||||||
|
.current()
|
||||||
.nextInt();
|
.nextInt();
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Benchmark
|
|
||||||
public void randomValuesUsingRandom() throws InterruptedException {
|
|
||||||
ExecutorService executor = Executors.newWorkStealingPool();
|
|
||||||
executor.invokeAll(randomCallables);
|
|
||||||
executor.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Benchmark
|
|
||||||
public void randomValuesUsingThreadLocalRandom() throws InterruptedException {
|
|
||||||
ExecutorService executor = Executors.newWorkStealingPool();
|
|
||||||
executor.invokeAll(threadLocalRandomCallables);
|
|
||||||
executor.shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user