// File TryDelegate4.java * Last update 2006-03-23 // The reflective call is 10 to 25 times slower than a virtual call, // with Sun HotSpot Client VM 1.4.0 under Linux on Pentium 3. import java.lang.reflect.*; // Method public class TryDelegate4 { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { int count = Integer.parseInt(args[0]); Class ty = SomeClass.class; // Get SomeClass class SomeClass o = new SomeClass(); Object[] margs = new Object[] { }; // Get m0() method Method m0 = ty.getMethod("m0", new Class[] {}); { Timer t = new Timer(); for (int i=count; i>0; i--) m0.invoke(o, margs); System.out.println("Reflective call to o.m0: " + t.Check()); System.out.println(o.k); } { Timer t = new Timer(); for (int i=count; i>0; i--) o.m0(); System.out.println("Virtual call to o.m0: " + t.Check()); System.out.println(o.k); } { SomeClassInterface oi = o; Timer t = new Timer(); for (int i=count; i>0; i--) oi.m0(); System.out.println("Interface call to oi.m0: " + t.Check()); System.out.println(oi.getK()); } { Void2Void dlg0 = (Void2Void)Delegate.createDelegate(Void2Void.class, m0, o); Timer t = new Timer(); for (int i=count; i>0; i--) dlg0.call(); System.out.println("Delegate call to m0(): " + t.Check()); System.out.println(o.getK()); } // Get m1(int) method Method m1 = ty.getMethod("m1", new Class[] { int.class }); { Timer t = new Timer(); int res = 0; for (int i=count; i>0; i--) { Object obj = m1.invoke(o, new Object[] { new Integer(i) }); res = ((Integer)obj).intValue(); } System.out.println("Reflective call to o.m1: " + t.Check()); System.out.println(res); System.out.println(o.getK()); } { Timer t = new Timer(); int res = 0; for (int i=count; i>0; i--) res = o.m1(i); System.out.println("Virtual call to o.m1: " + t.Check()); System.out.println(res); System.out.println(o.k); } { SomeClassInterface oi = o; Timer t = new Timer(); int res = 0; for (int i=count; i>0; i--) res = oi.m1(i); System.out.println("Interface call to oi.m1: " + t.Check()); System.out.println(res); System.out.println(oi.getK()); } { Int2Int dlg1 = (Int2Int)Delegate.createDelegate(Int2Int.class, m1, o); Timer t = new Timer(); int res = 0; for (int i=count; i>0; i--) res = dlg1.call(i); System.out.println("Delegate call to m1(i): " + t.Check()); System.out.println(res); System.out.println(o.getK()); } } public interface Void2Void { void call(); } public interface Int2Int { int call(int x); } } // Crude timing utility ---------------------------------------- class Timer { private long start; public Timer() { start = System.currentTimeMillis(); } public double Check() { return (System.currentTimeMillis()-start)/1000.0; } }