【发布时间】:2011-08-04 19:50:45
【问题描述】:
我知道有很多关于反射性能的话题。
甚至官方 Java 文档都说反射速度较慢,但我有这段代码:
public class ReflectionTest {
public static void main(String[] args) throws Exception {
Object object = new Object();
Class<Object> c = Object.class;
int loops = 100000;
long start = System.currentTimeMillis();
Object s;
for (int i = 0; i < loops; i++) {
s = object.toString();
System.out.println(s);
}
long regularCalls = System.currentTimeMillis() - start;
java.lang.reflect.Method method = c.getMethod("toString");
start = System.currentTimeMillis();
for (int i = 0; i < loops; i++) {
s = method.invoke(object);
System.out.println(s);
}
long reflectiveCalls = System.currentTimeMillis() - start;
start = System.currentTimeMillis();
for (int i = 0; i < loops; i++) {
method = c.getMethod("toString");
s = method.invoke(object);
System.out.println(s);
}
long reflectiveLookup = System.currentTimeMillis() - start;
System.out.println(loops + " regular method calls:" + regularCalls
+ " milliseconds.");
System.out.println(loops + " reflective method calls without lookup:"
+ reflectiveCalls+ " milliseconds.");
System.out.println(loops + " reflective method calls with lookup:"
+ reflectiveLookup + " milliseconds.");
}
}
我认为这不是一个有效的基准,但至少应该显示出一些差异。 我执行它等待看到反射正常调用比普通调用慢一些。
但这会打印:
100000 regular method calls:1129 milliseconds.
100000 reflective method calls without lookup:910 milliseconds.
100000 reflective method calls with lookup:994 milliseconds.
请注意,首先我在没有那一堆 sysout 的情况下执行它,然后我意识到一些 JVM 优化只是让它变得更快,所以我添加了这些 printls 以查看反射是否仍然更快。
没有系统输出的结果是:
100000 regular method calls:68 milliseconds.
100000 reflective method calls without lookup:48 milliseconds.
100000 reflective method calls with lookup:168 milliseconds.
我在 Internet 上看到,在旧 JVM 上执行的相同测试使得无需查找的反射比常规调用慢两倍,并且该速度低于新的更新。 如果有人可以执行它并说我错了,或者至少告诉我是否有与过去不同的东西使它更快。
按照说明,我运行了每个单独的循环,结果是(没有系统输出)
100000 regular method calls:70 milliseconds.
100000 reflective method calls without lookup:120 milliseconds.
100000 reflective method calls with lookup:129 milliseconds.
【问题讨论】:
-
不管先执行什么测试,你得到相同的结果吗?或者更好,分成 3 次运行?
标签: java performance reflection benchmarking