@ghimi
2018-10-20T12:41:06.000000Z
字数 2449
阅读 1414
Java
反射
Java 反射效率到底如何,花了点时间,做了一个简单的测试.供大家参考.
场景 | 本机测试结果(xp,双核,2G) | 服务器测试结果(Linux,XEN虚拟机,8核) |
---|---|---|
方法直接调用 | 235ms | 190ms |
jdk Method调用 | 29188ms | 4633ms |
jdk Method调用(稍作优化) | 5672ms | 4262ms |
Cglib FastMethod调用 | 5390ms | 2787ms |
package top.ghimi;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.esotericsoftware.reflectasm.MethodAccess;
public class ReflectionTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
long now;
long sum = 0;
TestClass t = new TestClass();
now = System.currentTimeMillis();
for (int i = 0; i < 500000; ++i) {
t.setNum(i);
sum += t.getNum();
}
System.out.println("get-set 耗时" + (System.currentTimeMillis() - now) + "ms秒,和是" + sum);
sum = 0;
now = System.currentTimeMillis();
for (int i = 0; i < 50000; ++i) {
Class<?> c = Class.forName("top.ghimi.TestClass");
Class<?>[] argsType = new Class[1];
argsType[0] = int.class;
Method m = c.getMethod("setNum", argsType);
m.invoke(t, i);
sum += t.getNum();
}
System.out.println("标准反射 耗时" + (System.currentTimeMillis() - now) + "ms秒,和是" + sum);
sum = 0;
now = System.currentTimeMillis();
Class<?> c = Class.forName("top.ghimi.TestClass");
Class<?>[] argsType = new Class[1];
argsType[0] = int.class;
Method m = c.getMethod("setNum", argsType);
for (int i = 0; i < 500000; ++i) {
m.invoke(t, i);
sum += t.getNum();
}
System.out.println("缓存反射 耗时" + (System.currentTimeMillis() - now) + "ms秒,和是" + sum);
sum = 0;
now = System.currentTimeMillis();
MethodAccess ma = MethodAccess.get(TestClass.class);
int index = ma.getIndex("setNum");
for (int i = 0; i < 500000; ++i) {
ma.invoke(t, index, i);
sum += t.getNum();
}
System.out.println("reflectasm反射 耗时" + (System.currentTimeMillis() - now) + "ms秒,和是" + sum);
}
}
运行结果如下:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running top.ghimi.AppTest
get-set 耗时20ms秒,和是124999750000
标准反射 耗时107ms秒,和是1249975000
缓存反射 耗时15ms秒,和是124999750000
reflectasm反射 耗时30ms秒,和是124999750000
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.184 sec
Results :
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
从结果可以看出,标准反射的运行时间是最长的,比较以外的是缓存反射的运行时间要比正常使用 get-set 方法耗时要短,可见反射并非在任何时候都是消耗性能的.
可以看出,查找函数依然是耗时最长的部分,JDK7的优化确实很不错,由JDK6的40倍降到10倍左右,reflectasm invoke的效率比java原生invoke好,大致是直接访问的4倍时间。效率确实可以一用。