Tôi đã viết một điểm chuẩn ít kiểm tra hiệu suất của java.lang.invoke.MethodHandle
, java.lang.reflect.Method
và các cuộc gọi trực tiếp của phương pháp.MethodHandle hiệu suất
Tôi đọc rằng hiệu suất MethodHandle.invoke()
gần như giống như cuộc gọi trực tiếp. Nhưng kết quả thử nghiệm của tôi cho thấy kết quả khác: MethodHandle
gọi chậm hơn ba lần so với phản xạ. Vấn đề của tôi là gì? Có thể đây là kết quả của một số tối ưu hóa JIT?
public class Main {
public static final int COUNT = 100000000;
static TestInstance test = new TestInstance();
static void testInvokeDynamic() throws NoSuchMethodException, IllegalAccessException {
int [] ar = new int[COUNT];
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType mt = MethodType.methodType(int.class);
MethodHandle handle = lookup.findStatic(TestInstance.class, "publicStaticMethod", mt) ;
try {
long start = System.currentTimeMillis();
for (int i=0; i<COUNT; i++) {
ar[i] = (int)handle.invokeExact();
}
long stop = System.currentTimeMillis();
System.out.println(ar);
System.out.println("InvokeDynamic time: " + (stop - start));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
static void testDirect() {
int [] ar = new int[COUNT];
try {
long start = System.currentTimeMillis();
for (int i=0; i<COUNT; i++) {
ar[i] = TestInstance.publicStaticMethod();
}
long stop = System.currentTimeMillis();
System.out.println(ar);
System.out.println("Direct call time: " + (stop - start));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
static void testReflection() throws NoSuchMethodException {
int [] ar = new int[COUNT];
Method method = test.getClass().getMethod("publicStaticMethod");
try {
long start = System.currentTimeMillis();
for (int i=0; i<COUNT; i++) {
ar[i] = (int)method.invoke(test);
}
long stop = System.currentTimeMillis();
System.out.println(ar);
System.out.println("Reflection time: " + (stop - start));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
static void testReflectionAccessible() throws NoSuchMethodException {
int [] ar = new int[COUNT];
Method method = test.getClass().getMethod("publicStaticMethod");
method.setAccessible(true);
try {
long start = System.currentTimeMillis();
for (int i=0; i<COUNT; i++) {
ar[i] = (int)method.invoke(test);
}
long stop = System.currentTimeMillis();
System.out.println(ar);
System.out.println("Reflection accessible time: " + (stop - start));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
public static void main(String ... args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InterruptedException {
Thread.sleep(5000);
Main.testDirect();
Main.testInvokeDynamic();
Main.testReflection();
Main.testReflectionAccessible();
System.out.println("\n___\n");
System.gc();
System.gc();
Main.testDirect();
Main.testInvokeDynamic();
Main.testReflection();
Main.testReflectionAccessible();
}
}
Môi trường: java phiên bản "1.7.0_11" Java (TM) SE Runtime Environment (xây dựng 1.7.0_11-B21) Java HotSpot (TM) 64-Bit Server VM (xây dựng 23,6-b04, hỗn hợp mode) OS - Windows 7 64
trước tiên hãy đảm bảo bạn biết cách viết điểm chuẩn, xem: http://www.ibm.com/developerworks/java/library/j-jtp02225/index.html –
@NathanHughes Có điểm gì sai với điểm chuẩn của mình? – Andremoniy
@Andremoniy: vấn đề rõ ràng nhất là không có sự khởi động của jvm. –