私有方法内联

Spl*_*our 5 java jvm scala inline

在Scala 不可变向量代码中有一条注释说:

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

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

apa*_*gin 9

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

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

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


Mik*_*378 0

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

让我们想象一下这两个类(例如在 Java 中):

class A {

  private B b;

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

}

class B {

  private int number;

  public void execute {
    println(number);
  }

}
Run Code Online (Sandbox Code Playgroud)

如果 B'sexecute由编译器内联到 A's 中execute,则会导致非法访问,因为number在 B 中是私有的:

class A {

  private B b;

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

}
Run Code Online (Sandbox Code Playgroud)

所以我想说,当您期望一些“内联”时,最好避免一些不兼容的变量范围。

当然,我认为它在极少数情况下很有用(主要是为了性能优化,我不想象其他情况)..也许是你展示的情况,否则会导致很多“糟糕的封装”...