Que Reflection é lento eu sempre soube, mas para testar quão mais lento é, eu executei esse benchmark tosco:
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.");
}
}
PS: O primeiro teste foi feito sem os System.out.printlns
Eu executei (sem sysouts) esperando que o reflection normal fosse um pouco mais lento que chamadas diretas, e eis que minha surpresa foi:
Foi então que decedi adicionar os sysouts, por achar que a JVM estava fazendo uma otimização maluca que fizesse o codigo com Reflection ser mais rapido, mas executando, novamente uma surpresa:
Observando no topico original de onde tirei o teste (http://www.jguru.com/faq/view.jsp?EID=246569) que mostrava que era duas vezes mais lento, fui decendo nos comentarios, e reparei que com o tempo e novas atualizações na JVM, esse tempo foi diminuindo até que mais recentemente (Java 6_12) acontece o mesmo que eu observei.
Alguém mais pode executar, falar que estou errado, ou responder o que aconteceu que está mais rapido?
E se isso for realmente uma super otimização, por que nos docs do Java (http://download.oracle.com/javase/tutorial/reflect/index.html) ainda exibe: