As you all know it is possible to fetch a method with Reflection
and invoke it through the returned Method
instance.
My question is however; once it is fetched by Reflection
and I invoke the Method
over and over again will the performance of the method be slower than the normal way of calling a method?
For example:
import java.lang.reflect.Method;
public class ReflectionTest {
private static Method test;
public ReflectionTest() throws Exception {
test = this.getClass().getMethod("testMethod", null);
}
public void testMethod() {
//execute code here
}
public static void main(String[] args) throws Exception {
ReflectionTest rt = new ReflectionTest();
for (int i = 0; i < 1000; i++) {
rt.test.invoke(null, null);
}
for (int i = 0; i < 1000; i++) {
rt.testMethod();
}
}
}
I am asking this because I am making an event system that, upon registering the listener it scans for annotations. The methods are put into a map and then they are executed each time an event occurs of their required parameter type. I don't know if this is performant enough for, for example a game.
Using the method without reflection is about an order of magnitude faster. I tested it like
public static void main(String[] args) throws Exception {
ReflectionTest rt = new ReflectionTest();
// Warm up
for (int i = 0; i < 100; i++) {
test.invoke(rt, null);
}
for (int i = 0; i < 100; i++) {
rt.testMethod();
}
long start = System.nanoTime();
for (int i = 0; i < 10000; i++) {
test.invoke(rt, null);
}
long end = Math.abs((start - System.nanoTime()) / 1000);
start = System.nanoTime();
for (int i = 0; i < 10000; i++) {
rt.testMethod();
}
long end2 = Math.abs((start - System.nanoTime()) / 1000);
System.out.printf("%d %d%n", end, end2);
}
I also moved test
to a static
field so it would compile and run
private static Method test;
static {
try {
test = ReflectionTest.class.getMethod("testMethod");
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
I get a fairly consistent difference (or an output consistent) with
4526 606
Which indicates that across 10000
invocations reflection is ~7 times slower then direct invocation.
@Elliot Frisch's answer provides conclusive1 evidence that using Method.invoke()
is slower.
You would expect this anyway, because the reflective version involves extra work; e.g.
Object
to the respective parameter types.It is possible that the JIT could could optimize this in some cases ...
1 - OK ... inconclusive. The benchmark is questionable because it doesn't take proper care to deal with possible JVM warmup anomalies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With