Skip to content

Instantly share code, notes, and snippets.

@clohfink
Created November 20, 2014 05:00
Show Gist options
  • Save clohfink/50e22ab895a7a700661b to your computer and use it in GitHub Desktop.
Save clohfink/50e22ab895a7a700661b to your computer and use it in GitHub Desktop.
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
public class ThreadLocalBenchmark {
@State(Scope.Benchmark)
public static class ThreadLocalExecutorPool extends JMXEnabledThreadPoolExecutor {
protected final ThreadLocal<Long> startTime = new ThreadLocal<Long>();
public final Counter wallTime;
private ThreadMXBean bean;
public ThreadLocalExecutorPool()
{
super(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("tl", Thread.MIN_PRIORITY), "internal");
wallTime = Metrics.newCounter(new MetricName("g", "t", "n"));
bean = ManagementFactory.getThreadMXBean();
}
@Override
protected void afterExecute(Runnable r, Throwable t)
{
wallTime.inc(bean.getCurrentThreadCpuTime() - startTime.get());
super.afterExecute(r, t);
}
@Override
public void execute(Runnable task) {
super.execute(task);
}
@Override
protected void beforeExecute(Thread t, Runnable r)
{
super.beforeExecute(t, r);
startTime.set(bean.getCurrentThreadCpuTime());
}
}
@State(Scope.Benchmark)
public static class WrapRunnableExecutorPool extends JMXEnabledThreadPoolExecutor {
public final Counter wallTime;
private ThreadMXBean bean;
public WrapRunnableExecutorPool()
{
super(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("wrapped", Thread.MIN_PRIORITY), "internal");
wallTime = Metrics.newCounter(new MetricName("g", "t", "n"));
bean = ManagementFactory.getThreadMXBean();
}
@Override
public void execute(Runnable task) {
long startTime = bean.getCurrentThreadCpuTime();
try
{
super.execute(task);
} finally {
wallTime.inc(bean.getCurrentThreadCpuTime() - startTime);
}
}
}
static class TimedRunnable implements Runnable
{
Counter wallTime;
Runnable task;
private ThreadMXBean bean;
public TimedRunnable(Counter wallTime, Runnable task, ThreadMXBean bean)
{
this.wallTime = wallTime;
this.task = task;
this.bean = bean;
}
public void run()
{
long startTime = bean.getCurrentThreadCpuTime();
try
{
task.run();
} finally
{
wallTime.inc(bean.getCurrentThreadCpuTime() - startTime);
}
}
}
@State(Scope.Benchmark)
public static class StaticWrapExecutorPool extends JMXEnabledThreadPoolExecutor {
public final Counter wallTime;
private ThreadMXBean bean;
public StaticWrapExecutorPool()
{
super(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("staticwrapped", Thread.MIN_PRIORITY), "internal");
wallTime = Metrics.newCounter(new MetricName("g", "t", "n"));
bean = ManagementFactory.getThreadMXBean();
}
@Override
public void execute(Runnable task) {
super.execute(new TimedRunnable(wallTime, task, bean));
}
}
@State(Scope.Benchmark)
public static class BaseLineExecutorPool extends JMXEnabledThreadPoolExecutor
{
public BaseLineExecutorPool()
{
super(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new NamedThreadFactory("baseline",
Thread.MIN_PRIORITY), "internal");
}
}
@Benchmark()
@BenchmarkMode(Mode.All)
public synchronized Object baseline(BaseLineExecutorPool pool) throws InterruptedException, ExecutionException {
return pool.submit(new Runnable() {
public void run() {
Thread.yield();
}
}).get();
}
@Benchmark()
@BenchmarkMode(Mode.All)
public synchronized Object staticWrap(StaticWrapExecutorPool pool) throws InterruptedException, ExecutionException {
return pool.submit(new Runnable() {
public void run() {
Thread.yield();
}
}).get();
}
@Benchmark()
@BenchmarkMode(Mode.All)
public synchronized Object threadlocal(ThreadLocalExecutorPool pool) throws InterruptedException, ExecutionException {
return pool.submit(new Runnable() {
public void run() {
Thread.yield();
}
}).get();
}
@Benchmark()
@BenchmarkMode(Mode.All)
public synchronized Object wrapped(WrapRunnableExecutorPool pool) throws InterruptedException, ExecutionException {
return pool.submit(new Runnable() {
public void run() {
Thread.yield();
}
}).get();
}
@TearDown
public static void teardown(ThreadLocalExecutorPool tlp, WrapRunnableExecutorPool wrap, BaseLineExecutorPool blp) {
try
{
Field f = QueryProcessor.class.getDeclaredField("evictionCheckTimer");
f.setAccessible(true);
((ScheduledExecutorService)f.get(null)).shutdown();
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
} catch (NoSuchFieldException e)
{
e.printStackTrace();
} catch (SecurityException e)
{
e.printStackTrace();
}
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(".*" + ThreadLocalBenchmark.class.getSimpleName() + ".*")
.warmupIterations(3)
.measurementIterations(15)
.forks(1)
.build();
new Runner(opt).run();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment