// Experiment: invokeinterface may be slower than invokevirtual. The // opposite may also be the case. // 2001-04-15 running (on a 850 MHz P3 with Sun Hotspot 1.3 and Linux): // java Invokevirtual 100000000 // takes 9.3 seconds with invokevirtual: B1 o = geto(i); // and 10.0 seconds with invokeinterface: A o = geto(i); // If the class of the object o is constant from call to call (and // does not alternate between B1 and B2), then invokeinterface is just // as fast as invokevirtual. This indicates that the method found by // invokeinterface is cached together with the class of o, and reused // at next call if the class is the same as before. // 2002-04-21: Curiously, this observation is not confirmed by // experiments with a 850 MHz P3 with Sun Hotspot 1.4 and Linux, where // we get these results for the -client version, regardless whether // geto always returns o1 or alternates between o1 and o2: // invokevirtual: 4.475 sec // invokeinterface: 8.827 sec // Using the -server version, the results are downright unbelievable: // [sestoft@jones oo]$ java -server Invokevirtual 100000000 // invokevirtual: 0.082 sec // invokeinterface: 0.067 sec // 199999999 class Invokevirtual { final static B1 o1 = new B1(); final static B1 o2 = new B2(); public static void main(String[] args) { int count = Integer.parseInt(args[0]); int res = 13; { Timer t = new Timer(); for (int i=0; i=0 ? o1 : o1; } } interface A { int m(); } class B1 implements A { int k; public int m() { return k++; } } class B2 extends B1 { public int m() { return ++k; } } // Crude timing utility ---------------------------------------- class Timer { private long start; public Timer() { start = System.currentTimeMillis(); } public double Check() { return (System.currentTimeMillis()-start)/1000.0; } }