`
76756154
  • 浏览: 34758 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

JDK7之函数句柄MethodHandle

    博客分类:
  • Java
 
阅读更多

JDK7从虚拟机级别添加了invokedynamic 命令,意图最大程度的支持动态语言调用。

函数句柄可以理解成C++的函数指针,执行的时候没有Method反射的虚拟机自检,所以理论效率会比传统反射高,测试代码如下:

 

package common;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;

public class TestMain {

	public static void main(String[] args) throws Throwable {
		MethodHandles.Lookup lookup = MethodHandles.lookup();
		Foo instance = new Foo();
		//搜索函数句柄
		MethodType methodType = MethodType.methodType(void.class);
		MethodHandle methodHandle = lookup.findVirtual(Foo.class, "doSomething", methodType);
		methodHandle.invoke(instance);
		
		//解除反射检测,使用invokedynamic命令直接执行
		Method method = Foo.class.getDeclaredMethod("doSomething");
		methodHandle = lookup.unreflect(method);
		int testTimes = 9999999;
		long t1 = System.currentTimeMillis();
		for(int i=0;i<testTimes;i++){
			methodHandle.invokeExact(instance);
		}
		long t2 = System.currentTimeMillis();
		System.out.println("句柄调用:"+(t2-t1));
		t1 = System.currentTimeMillis();
		for(int i=0;i<testTimes;i++){
			method.invoke(instance);
		}
		t2 = System.currentTimeMillis();
		System.out.println("反射调用:"+(t2-t1));
		
		t1 = System.currentTimeMillis();
		for(int i=0;i<testTimes;i++){
			instance.doSomething();
		}
		t2 = System.currentTimeMillis();
		System.out.println("直接调用:"+(t2-t1));
		
	}

}

 

每种方式执行9999999次,实际运行耗时如下

句柄调用:107ms

反射调用:69ms

直接调用:3ms

实际执行效率句柄调用比反射慢,可能是JDK7刚刚实现函数句柄,还未优化导致,而反射已经过多个版本的优化,期望在JDK1.8+里能够得到优异的表现

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics