// // ReflectionPerformance.java // // Adapted from: http://www.jguru.com/faq/view.jsp?EID=246569 import java.lang.reflect.Method; import loci.common.ReflectedUniverse; /** * A benchmark for Java reflection performance. * * <dl><dt><b>Source code:</b></dt> * <dd><a href="http://trac.openmicroscopy.org.uk/ome/browser/bioformats.git/components/common/utils/ReflectionPerformance.java">Trac</a>, * <a href="http://git.openmicroscopy.org/?p=bioformats.git;a=blob;f=components/common/utils/ReflectionPerformance.java;hb=HEAD">Gitweb</a></dd></dl> */ public class ReflectionPerformance { private static int val = 0; public static void fastMethod() { val++; } public static void fastMethod(int arg) { val += arg; } public static void slowMethod() { for (int i=0; i<1000000; i++) val++; } public static void slowMethod(int arg) { for (int i=0; i<1000000; i++) val += arg; } public static void benchmarkFast() throws Exception { System.out.println(); System.out.println("--== Fast method benchmark, no args ==--"); Class<ReflectionPerformance> c = ReflectionPerformance.class; Method method = c.getMethod("fastMethod"); ReflectedUniverse r = new ReflectedUniverse(); r.exec("import ReflectionPerformance"); int loops = 100000; for (int outer=0; outer<3; outer++) { long start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) ReflectionPerformance.fastMethod(); System.out.println(loops + " regular method calls: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) method.invoke(null); System.out.println(loops + " reflective method calls without lookup: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) { method = c.getMethod("fastMethod"); method.invoke(null); } System.out.println(loops + " reflective method calls with lookup: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) { r.exec("ReflectionPerformance.fastMethod()"); } System.out.println(loops + " reflected universe method calls: " + (System.currentTimeMillis() - start) + " ms"); loops *= 10; } } public static void benchmarkFastWithArg() throws Exception { System.out.println(); System.out.println("--== Fast method benchmark, w/ arg ==--"); Class<ReflectionPerformance> c = ReflectionPerformance.class; Method method = c.getMethod("fastMethod", int.class); ReflectedUniverse r = new ReflectedUniverse(); r.exec("import ReflectionPerformance"); int arg = 1; r.setVar("arg", arg); int loops = 100000; for (int outer=0; outer<3; outer++) { long start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) ReflectionPerformance.fastMethod(arg); System.out.println(loops + " regular method calls: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) method.invoke(null, arg); System.out.println(loops + " reflective method calls without lookup: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) { method = c.getMethod("fastMethod", int.class); method.invoke(null, arg); } System.out.println(loops + " reflective method calls with lookup: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) { r.exec("ReflectionPerformance.fastMethod(arg)"); } System.out.println(loops + " reflected universe method calls: " + (System.currentTimeMillis() - start) + " ms"); loops *= 10; } } public static void benchmarkSlow() throws Exception { System.out.println(); System.out.println("--== Slow method benchmark, no args ==--"); Class<ReflectionPerformance> c = ReflectionPerformance.class; Method method = c.getMethod("slowMethod"); ReflectedUniverse r = new ReflectedUniverse(); r.exec("import ReflectionPerformance"); int loops = 100; for (int outer=0; outer<3; outer++) { long start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) ReflectionPerformance.slowMethod(); System.out.println(loops + " regular method calls: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) method.invoke(null); System.out.println(loops + " reflective method calls without lookup: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) { method = c.getMethod("slowMethod"); method.invoke(null); } System.out.println(loops + " reflective method calls with lookup: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) { r.exec("ReflectionPerformance.slowMethod()"); } System.out.println(loops + " reflected universe method calls: " + (System.currentTimeMillis() - start) + " ms"); loops *= 10; } } public static void benchmarkSlowWithArg() throws Exception { System.out.println(); System.out.println("--== Slow method benchmark, w/ arg ==--"); Class<ReflectionPerformance> c = ReflectionPerformance.class; Method method = c.getMethod("slowMethod", int.class); ReflectedUniverse r = new ReflectedUniverse(); r.exec("import ReflectionPerformance"); int arg = 1; r.setVar("arg", arg); int loops = 100; for (int outer=0; outer<3; outer++) { long start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) ReflectionPerformance.slowMethod(arg); System.out.println(loops + " regular method calls: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) method.invoke(null, arg); System.out.println(loops + " reflective method calls without lookup: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) { method = c.getMethod("slowMethod", int.class); method.invoke(null, arg); } System.out.println(loops + " reflective method calls with lookup: " + (System.currentTimeMillis() - start) + " ms"); start = System.currentTimeMillis(); for (int i = 0; i < loops; i++) { r.exec("ReflectionPerformance.slowMethod(arg)"); } System.out.println(loops + " reflected universe method calls: " + (System.currentTimeMillis() - start) + " ms"); loops *= 10; } } public static void main(String[] args) throws Exception { benchmarkFast(); benchmarkFastWithArg(); benchmarkSlow(); benchmarkSlowWithArg(); } }