我正在进行一些代码微基准测试(请友善对待),并遇到了这个谜题:使用反射读取字段时,调用getter方法比读取Field更快。
简单的测试类:
private static final class Foo {
public Foo(double val) {
this.val = val;
}
public double getVal() { return val; }
public final double val; // only public for demo purposes
}
我们有两个反思:
Method m = Foo.class.getDeclaredMethod("getVal", null);
Field f = Foo.class.getDeclaredField("val");
现在我在循环中调用两个反射方法,对于Method执行
invoke
,对于Field执行get
。第一次运行是为了热身虚拟机,第二次运行进行10M次迭代。方法调用始终快30%,但为什么?请注意,在循环中不会调用getDeclaredMethod和getDeclaredField。它们在循环中只调用一次并在同一对象上执行。我还尝试了一些小变化:使字段非final,可传递,非公共等。所有这些组合都导致统计上相似的性能。
编辑:这是在WinXP,Intel Core2 Duo,Sun JavaSE build 1.6.0_16-b01下运行的,使用jUnit4和Eclipse。