0 Replies Latest reply: May 13, 2010 7:43 AM by 843829 RSS

    Simple interface vs. inline speed comparison with unexpected results

    843829
      Recently, I wrote a simple superficial test to inform myself about the potential penalty for calling methods through interfaces, generic interfaces, final classes vs. inlined code. The example consists of two interfaces
      public interface A{
          public long doA( long a );
      }
      
      public interface B{
          public long doB( long b );
      }
      an interface that extends both
      public interface AB extends A, B {}
      and two final classes, one implementing AB and the other implementing A and B
      final public class ABClass implements AB {
          final long c;     
          public ABClass( final long c ) { this.c = c; }
      
          @Override
          final public long doA( final long a ) {
              return a * a + c;
          }
      
          @Override
          final public long doB( final long b ) {
              return b * b + c;
          }
      }
      
      final public class APlusBClass implements A, B {
          final long c;     
          public APlusBClass( final long c ) { this.c = c; }
      
          @Override
          final public long doA( final long a ) {
              return a * a + c;
          }
      
          @Override
          final public long doB( final long b ) {
              return b * b + c;
          }
      }
      I perform five tests, each looping over long i from 0 to 1000000000, summing up the return values of both methods called with i. The test is performed calling methods using the parameters AB, a generic Type implementing A & B, and the final classes directly in all possible combinations
      final static private long finalAB( final ABClass ab, final long x ) {
          return ab.doA( x ) + ab.doB( x );
      }
      
      final static private long finalAPlusB( final APlusBClass ab, final long x ) {
          return ab.doA( x ) + ab.doB( x );
      }
      
      final static private long nonGeneric( final AB ab, final long x ) {
          return ab.doA( x ) + ab.doB( x );
      }
      
      final static private < T extends A & B >long generic( final T ab, final long x ) {
          return ab.doA( x ) + ab.doB( x );
      }
      Furthermore, as a last test, the calls to doA( x ) + doB( x ) are explicitly inlined
      x * x + c + x * x + c;
      All six tests are performed 10 times.

      The test is here, including the sources:

      [http://www.speedyshare.com/files/22401605/download/test.jar|http://www.speedyshare.com/files/22401605/download/test.jar]

      java -jar test.jar

      When running the test, I get two surprising results:

      1. The first run is the fastest for all tests but the explicitly inlined test. All tests are approx. equally fast but the inlined version is slowest(?).
      2. From the second run, all tests are about 1.5x slower, except the explicitly inlined which has constant speed in all runs and is now the fastest.

      I would be very happy if somebody could highlight to me the rationale behind these effects.

      Thank you very much in advance.

      Edited by: axtimwalde on May 13, 2010 5:22 AM
      Included important code fragments