私有方法内联

时间:2014-04-24 11:52:09

标签: java scala jvm inline

在Scala immutable Vector code中有评论说:

  

原则上,大多数成员应该是私人的。但是,必须谨慎选择访问权限,以防止方法内联

  1. 私人对内联决策的影响是什么?
  2. 这是否也适用于Java?

2 个答案:

答案 0 :(得分:8)

这通常不适用于Java。访问检查仅在Resolution过程中执行一次。当Java方法进行JIT编译时,符号引用已经过解析和验证。实际上,内联不是在原始字节码上执行,而是在编译器特定的中间表示上执行。因此,访问修饰符通常不具有性能副作用。

但是,我可以编写一个人工测试用例,其中private / public修饰符会显着影响性能:

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

此效果由access$000合成方法解释,javac生成该方法以允许访问内部类的私有成员。在上面的测试用例中,这个额外的访问器阻止了内联,因为HotSpot中默认的最大内联级别是9(-XX:MaxInlineLevel=9)。由于getPrivate()不能直接从外部类调用,因此额外的access$000()方法进行了第10级调用,因此没有内联。

答案 1 :(得分:1)

我不是"编译器决策的专家"但从逻辑上讲,我会说:

让我们想象这两个类(例如Java):

class A {

  private B b;

  public void execute(){
    b.execute();
  }

}

class B {

  private int number;

  public void execute {
    println(number);
  }

}

如果B&#39; execute被编译器内联到A execute,则会导致非法访问,因为number在B中是私有的:< / p>

class A {

  private B b;

  public void execute(){
    println(number);  //OUPS! number is unreachable directly from A
  }

}

所以我会说,当你期望某些&#34;内联&#34;时,更愿意避免一些不兼容的变量的范围。

当然,我认为它在极少数情况下很有用(主要用于性能优化,我不会想象其他情况)..也许你说的情况,否则会导致很多&#34;糟糕的封装&#34; ...