Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private method inlining

In the Scala immutable Vector code there is a comment that says:

In principle, most members should be private. However, access privileges must be carefully chosen to not prevent method inlining

  1. What's the effect of private on inlining decisions?
  2. Does this apply to Java as well?
like image 976
Splendour Avatar asked Apr 24 '14 11:04

Splendour


1 Answers

This generally does not apply to Java. The access checks are performed only once during the Resolution process. When Java method is JIT-compiled, the symbolic references are already resolved and verified. In fact, the inlining is performed not on the original bytecode, but on the compiler-specific intermediate representation. So, the access modifiers does not usually have performace side-effects.

However, I can write an artificial test case where a private/public modifier dramatically affects the performance:

public class Test {
    static final Inner inner = new Inner();

    static class Inner {
        int x = 1;

        int getX1() { return x; }
        int getX2() { return getX1(); }
        int getX3() { return getX2(); }
        int getX4() { return getX3(); }
        int getX5() { return getX4(); }
        int getX6() { return getX5(); }
        int getX7() { return getX6(); }
        int getX8() { return getX7(); }
        int getX9() { return getX8(); }

        private int getPrivate() { return getX9(); }
        public int getPublic() { return getX9(); }
    }

    @GenerateMicroBenchmark
    public int inlinePrivate() {
        return inner.getPrivate();
    }

    @GenerateMicroBenchmark
    public int inlinePublic() {
        return inner.getPublic();
    }
}

Benchmark                Mode Thr    Cnt  Sec         Mean   Mean error    Units
b.Test.inlinePrivate    thrpt   1      3    5   289480,928     2247,656 ops/msec
b.Test.inlinePublic     thrpt   1      3    5  1157970,245    18473,139 ops/msec

This effect is explained by a synthetic method access$000 which javac generates to allow access to a private member of the inner class. In the above test case this extra accessor prevents from inlining, because the default maximum level of inlining in HotSpot is 9 (-XX:MaxInlineLevel=9). Since getPrivate() cannot be called directly from the outer class, the extra access$000() method makes 10th level of invocation and therefore is not inlined.

like image 72
apangin Avatar answered Sep 29 '22 02:09

apangin