我知道有很多话题讨论反射性能。
即使官方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.
仅作为注意,起初我没有打印那些sysouts,但之后我意识到一些JVM优化使得它变得更快,所以我添加了这些printls来查看反射是否仍然更快。
没有sysouts的结果如下:
100000 regular method calls:68 milliseconds.
100000 reflective method calls without lookup:48 milliseconds.
100000 reflective method calls with lookup:168 milliseconds.
我在网上看到,旧版本JVM上执行的相同测试,反射而无需查找的速度比常规调用慢两倍,并且随着新版本的更新,速度会下降。 如果有人能够执行并告诉我我错了,或者至少告诉我是否存在使其更快的不同之处。 按照说明,我分别运行了每个循环,并得出结果(没有sysouts)。
100000 regular method calls:70 milliseconds.
100000 reflective method calls without lookup:120 milliseconds.
100000 reflective method calls with lookup:129 milliseconds.