Why are interface method invocations slower than concrete invocations?

后端 未结 6 978
伪装坚强ぢ
伪装坚强ぢ 2020-11-27 15:24

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 in

6条回答
  •  长情又很酷
    2020-11-27 16:05

    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 foos = new ArrayList(40000);
            List bars = new ArrayList(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;
            }
        }
    }
    

提交回复
热议问题