I've seen other threads saying java reflection performance is 10-100x slower than when using non-reflection calls.
My tests in 1.6 have shown that this is not the case but I found some other interesting things that I need someone to explain to me.
I have objects that implement my interface. I did three things 1) using a reference to an Object I cast that object to the interface and call the method through the interface 2) using a reference to the actual object call the method directly and 3) call the method through reflection. I saw that #1 interface call was fastest followed closely by #3 reflection but I noticed that the direct method call was the slowest by a good margin.
I don't understand that, I would've expected the direct call to be fastest, then the interface, then reflection would be much much more slow.
Blah and ComplexClass are in a different package from the main class and both have a doSomething(int x) method that implements the interface and just prints the integer x.
Here are my results (times in ms, results very similar w/ multiple trials): calling a method directly: 107194 calling a method directly from an object cast to an interface: 89594 calling a method through reflection: 90453
Here is my code:
public class Main
{
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
Blah x = new Blah();
ComplexClass cc = new ComplexClass();
test((Object) x, cc);
}
public static void test(Object x, ComplexClass cc)
{
long start, end;
long time1, time2, time3 = 0;
int numToDo = 1000000;
MyInterface interfaceClass = (MyInterface) x;
//warming up the cache
for (int i = 0; i < numToDo; i++)
{
cc.doSomething(i); //calls a method directly
}
start = System.currentTimeMillis();
for (int i = 0; i < numToDo; i++)
{
cc.doSomething(i); //calls a method directly
}
end = System.currentTimeMillis();
time1 = end - start;
start = System.currentTimeMillis();
for (int i = 0; i < numToDo; i++)
{
interfaceClass.doSomething(i); //casts an object to an interface then calls the method
}
end = System.currentTimeMillis();
time2 = end - start;
try
{
Class xClass = x.getClass();
Class[] argTypes =
{
int.class
};
Method m = xClass.getMethod("doSomething", argTypes);
Object[] paramList = new Object[1];
start = System.currentTimeMillis();
for (int i = 0; i < numToDo; i++)
{
paramList[0] = i;
m.invoke(x, paramList); //calls via reflection
}
end = System.currentTimeMillis();
time3 = end - start;
} catch (Exception ex)
{
}
System.out.println("calling a method directly: " + time1);
System.out.println("calling a method directly from an object cast to an interface: " + time2);
System.out.println("calling a method through reflection: " + time3);
}