最近在了解反射优化的东西,做了一个 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<String> names = new ArrayList<>(100);
for (int i = 0; i < 100; i++) {
names.add(name+i);
}
List<Integer> 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 快?!!! 直接调和反射差的也不多,是我的这段测试有问题吗?请教一下关于反射优化的问题,谢谢。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.