Skip to content

Instantly share code, notes, and snippets.

@carl-mastrangelo
Created February 20, 2023 21:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carl-mastrangelo/7a5e96f14423e70fdddcb1f4b50a8cc0 to your computer and use it in GitHub Desktop.
Save carl-mastrangelo/7a5e96f14423e70fdddcb1f4b50a8cc0 to your computer and use it in GitHub Desktop.
Sleep Executors
/*
Benchmark (executor) (sleepMillis) (sleeps) Mode Cnt Score Error Units
SleeperBenchmark.Bench.run CACHED 1 1 ss 30 1.180 ± 0.028 ms/op
SleeperBenchmark.Bench.run CACHED 1 8 ss 30 1.227 ± 0.044 ms/op
SleeperBenchmark.Bench.run CACHED 1 64 ss 30 1.365 ± 0.045 ms/op
SleeperBenchmark.Bench.run CACHED 1 512 ss 30 3.764 ± 0.476 ms/op
SleeperBenchmark.Bench.run CACHED 1 4096 ss 30 13.375 ± 0.996 ms/op
SleeperBenchmark.Bench.run FIXED 1 1 ss 30 1.234 ± 0.035 ms/op
SleeperBenchmark.Bench.run FIXED 1 8 ss 30 1.362 ± 0.084 ms/op
SleeperBenchmark.Bench.run FIXED 1 64 ss 30 9.433 ± 0.409 ms/op
SleeperBenchmark.Bench.run FIXED 1 512 ss 30 72.901 ± 0.540 ms/op
SleeperBenchmark.Bench.run FIXED 1 4096 ss 30 588.834 ± 2.089 ms/op
SleeperBenchmark.Bench.run FJP 1 1 ss 30 1.313 ± 0.178 ms/op
SleeperBenchmark.Bench.run FJP 1 8 ss 30 1.526 ± 0.099 ms/op
SleeperBenchmark.Bench.run FJP 1 64 ss 30 1.871 ± 0.258 ms/op
SleeperBenchmark.Bench.run FJP 1 512 ss 30 7.576 ± 2.723 ms/op
SleeperBenchmark.Bench.run FJP 1 4096 ss 30 42.071 ± 32.532 ms/op
SleeperBenchmark.Bench.run VIRTUAL 1 1 ss 30 1.544 ± 0.114 ms/op
SleeperBenchmark.Bench.run VIRTUAL 1 8 ss 30 1.407 ± 0.051 ms/op
SleeperBenchmark.Bench.run VIRTUAL 1 64 ss 30 1.574 ± 0.241 ms/op
SleeperBenchmark.Bench.run VIRTUAL 1 512 ss 30 2.586 ± 0.410 ms/op
SleeperBenchmark.Bench.run VIRTUAL 1 4096 ss 30 7.318 ± 1.268 ms/op
SleeperBenchmark.Bench.run DIRECT 1 1 ss 30 1.151 ± 0.021 ms/op
SleeperBenchmark.Bench.run DIRECT 1 8 ss 30 9.176 ± 0.157 ms/op
SleeperBenchmark.Bench.run DIRECT 1 64 ss 30 73.271 ± 1.302 ms/op
SleeperBenchmark.Bench.run DIRECT 1 512 ss 30 578.302 ± 4.631 ms/op
SleeperBenchmark.Bench.run DIRECT 1 4096 ss 30 4645.557 ± 9.266 ms/op
*/
package bench;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Level;
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.TearDown;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.openjdk.jmh.runner.options.TimeValue;
@RunWith(JUnit4.class)
public class SleeperBenchmark {
@Test
public void markHolderBenchmark() throws Exception {
Options options = new OptionsBuilder()
.include(Bench.class.getCanonicalName())
.measurementIterations(30)
.warmupIterations(10)
.forks(1)
.warmupTime(TimeValue.seconds(20))
.measurementTime(TimeValue.seconds(20))
.shouldFailOnError(true)
// This is necessary to run in the IDE, otherwise it would inherit the VM args.
.jvmArgs("-da", "--enable-preview")
.build();
new Runner(options).run();
}
@State(Scope.Benchmark)
public static class Bench {
private static final class Sleeper implements Callable<Long>, ForkJoinPool.ManagedBlocker {
private final long nanosToSleep;
Sleeper(long nanosToSleep) {
this.nanosToSleep = nanosToSleep;
}
@Override
public Long call() {
long now = System.nanoTime();
try {
ForkJoinPool.managedBlock(this);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
return System.nanoTime() - now;
}
@Override
public boolean block() throws InterruptedException {
TimeUnit.NANOSECONDS.sleep(nanosToSleep);
return true;
}
@Override
public boolean isReleasable() {
return false;
}
}
private ExecutorService exec;
@Param({"1"})
public int sleepMillis;
@Param({"1", "8", "64", "512", "4096"})
public int sleeps;
@Param
public ExecutorSupplier executor;
public enum ExecutorSupplier implements Supplier<ExecutorService> {
CACHED {
@Override
public ExecutorService get() {
return Executors.newCachedThreadPool();
}
},
FIXED {
@Override
public ExecutorService get() {
return Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
}
},
FJP {
@Override
public ExecutorService get() {
return new ForkJoinPool();
}
},
VIRTUAL {
@Override
public ExecutorService get() {
return Executors.newVirtualThreadPerTaskExecutor();
}
},
DIRECT {
@Override
public ExecutorService get() {
return new AbstractExecutorService() {
@Override
public void execute(Runnable command) {
command.run();
}
@Override
public void shutdown() {}
@Override
public List<Runnable> shutdownNow() {
return List.of();
}
@Override
public boolean isShutdown() {
return false;
}
@Override
public boolean isTerminated() {
return false;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit) {
return true;
}
};
}
}
;
}
private final List<Callable<Long>> sleepers = new ArrayList<>();
@Setup(Level.Trial)
public void setUp() {
exec = executor.get();
for (int i = 0; i < sleeps; i++) {
sleepers.add(new Sleeper(Duration.ofMillis(sleepMillis).toNanos()));
}
}
@TearDown
public void tearDown() {
exec.close();
}
@Benchmark
@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public long run() throws InterruptedException {
return exec.invokeAll(sleepers).stream().map(Future::resultNow).reduce(0L, Long::sum);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment