Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxandersen/d6571c2e637702fb55cd18783e5bff1b to your computer and use it in GitHub Desktop.
Save maxandersen/d6571c2e637702fb55cd18783e5bff1b to your computer and use it in GitHub Desktop.
//JAVA 19
//DEPS org.openjdk.jmh:jmh-generator-annprocess:1.36
//JAVA_OPTIONS --enable-preview --add-opens java.base/java.lang=ALL-UNNAMED
// to run with javagagent add the following:
// `--javaagent=ap-loader@maxandersen=start,event=cpu,file=profile.html`
package red.hat.puzzles.loom;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Measurement(iterations = 5, time = 100, timeUnit = TimeUnit.MILLISECONDS)
@Warmup(iterations = 10, time = 100, timeUnit = TimeUnit.MILLISECONDS)
@Fork(2)
public class VirtualThreadReflectionBenchmark {
private static final class Dummy {
private static Thread currentCarrierThread() {
return Thread.currentThread();
}
}
private static final Method CURRENT_CARRIER_METHOD = currentCarrierThreadMethod();
private static final Method DUMMY_CURRENT_CARRIER_METHOD = dummyCurrentCarrierThreadMethod();
private static final MethodHandle CURRENT_CARRIER_MH = currentCarrierThreadMH();
private static Method dummyCurrentCarrierThreadMethod() {
try {
Method currentCarrierThread = Dummy.class.getDeclaredMethod("currentCarrierThread");
currentCarrierThread.setAccessible(true);
Thread dummy = (Thread) currentCarrierThread.invoke(null);
return currentCarrierThread;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
private static Method currentCarrierThreadMethod() {
try {
Method currentCarrierThread = Thread.class.getDeclaredMethod("currentCarrierThread");
currentCarrierThread.setAccessible(true);
// this is to check if --enable-preview for Java 19 is correctly set
Thread dummy = (Thread) currentCarrierThread.invoke(null);
return currentCarrierThread;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
private static MethodHandle currentCarrierThreadMH() {
try {
MethodHandle mh = MethodHandles.lookup().unreflect(currentCarrierThreadMethod());
Thread t = (Thread) mh.invokeExact();
return mh;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
private static Thread currentCarrierThread() {
try {
return (Thread) CURRENT_CARRIER_METHOD.invoke(null);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
private static Thread dummyCurrentCarrierThread() {
try {
return (Thread) DUMMY_CURRENT_CARRIER_METHOD.invoke(null);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
private static Thread currentCarrierThreadInvokeExact() {
try {
// NOT USING primitive on purpose :"( Netty 4.1 is Java 1.6 sigh!
return (Thread) CURRENT_CARRIER_MH.invokeExact();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
@Benchmark
public Thread reflectiveCurrentCarrierThread() {
return currentCarrierThread();
}
@Benchmark
public Thread mhCurrentCarrierThread() {
return currentCarrierThreadInvokeExact();
}
@Benchmark
public Thread reflectiveDummyCurrentCarrierThread() {
return dummyCurrentCarrierThread();
}
public static void main(String[] args) throws Exception {
org.openjdk.jmh.Main.main(args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment