最近在了解反射优化的东西,做了一个 cglib,java 的反射 api 和直接调用的性能比较
public class SampleBean {
public String echo(String name) {
return name;
}
}
测试代码:
FastClass fastClass = FastClass.create(SampleBean.class);
FastMethod fastMethod = fastClass.getMethod(SampleBean.class.getMethod("echo", String.class));
SampleBean myBean = new SampleBean();
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
fastMethod.invoke(myBean, new Object[]{"haha"+i});
//fastMethod.invoke(myBean, new Object[]{"haha"});
}
System.out.println("fastmethod:" + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
Method m = SampleBean.class.getMethod("echo", String.class);
for (int i = 0; i < 1000000; i++) {
m.invoke(myBean, "haha"+i);
//m.invoke(myBean, "haha");
}
System.out.println("reflect:"+(System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
myBean.echo("haha"+i);
//myBean.echo("haha");
}
System.out.println("normal:"+(System.currentTimeMillis() - start));
输出:
fastmethod:196
reflect:139
normal:72
上面一段代码如果跑被注释掉的那一行时间会更短:
fastmethod:38
reflect:33
normal:25
个人猜测,百万次调用参数不变,是不是被优化了?
public class SampleBean {
public String echo(String name, int age) {
//改一下,方法稍微复杂点
List names = new ArrayList<>(100);
for (int i = 0; i < 100; i++) {
names.add(name+i);
}
List ages = new ArrayList<>(100);
for (int i = 0; i < 100; i++) {
ages.add(age+i);
}
return name+"--"+age;
}
}
测试代码:
FastClass fastClass = FastClass.create(SampleBean.class);
FastMethod fastMethod = fastClass.getMethod(SampleBean.class.getMethod("echo", String.class, int.class));
SampleBean myBean = new SampleBean();
myBean.setValue("Hello cglib!");
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
fastMethod.invoke(myBean, new Object[]{"haha"+i, 12});
}
System.out.println("fastmethod:" + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
Method m = SampleBean.class.getMethod("echo", String.class, int.class);
for (int i = 0; i < 1000000; i++) {
m.invoke(myBean, "haha"+i, 12);
}
System.out.println("reflect:" + (System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
myBean.echo("haha"+i, 12);
}
System.out.println("normal:" + (System.currentTimeMillis() - start));
这段代码输出:
fastmethod:5533
reflect:4779
normal:4691
结果是 cglib 不如 java 自己的反射 api 快?!!! 直接调和反射差的也不多,是我的这段测试有问题吗?请教一下关于反射优化的问题,谢谢。