Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are interface method invocations slower than concrete invocations?

Tags:

java

This is question comes in mind when I finding difference between abstract class and interface. In this post I came to know that interfaces are slow as they required extra indirection. But I am not getting what type of indirection required by the interface and not by the abstract class or concrete class.Please clarify on it. Thanks in advance

like image 383
Sanjay Jain Avatar asked Jul 27 '11 05:07

Sanjay Jain


People also ask

CAN interface can have concrete methods?

All the methods in an interface must be abstract, you cannot have a concrete method (the one which has body) if you try to do so, it gives you a compile time error saying “interface abstract methods cannot have body”.

What is concrete method in interface?

Concrete methods in interfaces The simplest form of this feature is the ability to declare a concrete method in an interface, which is a method with a body. A class that implements this interface need not implement its concrete method.

How do you invoke an interface method?

In order to call an interface method from a java program, the program must instantiate the interface implementation program. A method can then be called using the implementation object.


2 Answers

There are many performance myths, and some were probably true several years ago, and some might still be true on VMs that don't have a JIT.

The Android documentation (remember that Android don't have a JVM, they have Dalvik VM) used to say that invoking a method on an interfaces was slower than invoking it on a class, so they were contributing to spreading the myth (it's also possible that it was slower on the Dalvik VM before they turned on the JIT). The documentation does now say:

Performance Myths

Previous versions of this document made various misleading claims. We address some of them here.

On devices without a JIT, it is true that invoking methods via a variable with an exact type rather than an interface is slightly more efficient. (So, for example, it was cheaper to invoke methods on a HashMap map than a Map map, even though in both cases the map was a HashMap.) It was not the case that this was 2x slower; the actual difference was more like 6% slower. Furthermore, the JIT makes the two effectively indistinguishable.

Source: Designing for performance on Android

The same thing is probably true for the JIT in the JVM, it would be very odd otherwise.

like image 143
Kaj Avatar answered Sep 24 '22 07:09

Kaj


If in doubt, measure it. My results showed no significant difference. When run, the following program produced:

7421714 (abstract) 5840702 (interface)  7621523 (abstract) 5929049 (interface) 

But when I switched the places of the two loops:

7887080 (interface) 5573605 (abstract)  7986213 (interface) 5609046 (abstract) 

It appears that abstract classes are slightly (~6%) faster, but that should not be noticeable; These are nanoseconds. 7887080 nanoseconds are ~7 milliseconds. That makes it a difference of 0.1 millis per 40k invocations (Java version: 1.6.20)

Here's the code:

public class ClassTest {      public static void main(String[] args) {         Random random = new Random();         List<Foo> foos = new ArrayList<Foo>(40000);         List<Bar> bars = new ArrayList<Bar>(40000);         for (int i = 0; i < 40000; i++) {             foos.add(random.nextBoolean() ? new Foo1Impl() : new Foo2Impl());             bars.add(random.nextBoolean() ? new Bar1Impl() : new Bar2Impl());         }          long start = System.nanoTime();              for (Foo foo : foos) {             foo.foo();         }          System.out.println(System.nanoTime() - start);           start = System.nanoTime();          for (Bar bar : bars) {             bar.bar();         }          System.out.println(System.nanoTime() - start);         }      abstract static class Foo {         public abstract int foo();     }      static interface Bar {         int bar();     }      static class Foo1Impl extends Foo {         @Override         public int foo() {             int i = 10;             i++;             return i;         }     }     static class Foo2Impl extends Foo {         @Override         public int foo() {             int i = 10;             i++;             return i;         }     }      static class Bar1Impl implements Bar {         @Override         public int bar() {             int i = 10;             i++;             return i;         }     }     static class Bar2Impl implements Bar {         @Override         public int bar() {             int i = 10;             i++;             return i;         }     } } 
like image 29
Bozho Avatar answered Sep 23 '22 07:09

Bozho