2014-04-24 18 views
5

W Scala immutable Vector code nie jest komentarz, który mówi:Metoda prywatna inline

W zasadzie większość członków powinny być prywatne. Jednak przywileje dostępowe muszą być starannie dobrane, aby nie uniemożliwiać metoda inline

  1. Jaki jest efekt prywatne na decyzje inline?
  2. Czy dotyczy to również środowiska Java?

Odpowiedz

1

Nie jestem ekspertem w „decyzji kompilator” ale logicznie powiedziałbym:

Wyobraźmy sobie te dwie klasy (w Javie na przykład):

class A { 

    private B b; 

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

} 

class B { 

    private int number; 

    public void execute { 
    println(number); 
    } 

} 

Jeśli B execute jest inlined przez kompilator do użytkownika execute, prowadziłoby to do nielegalnego dostępu od number jest prywatne w B:

class A { 

    private B b; 

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

} 

Powiedziałbym więc, że kiedy oczekujesz "inliningu", wolisz unikać zakresu nieokreślonej zmiennej.

Oczywiście, wyobrażam sobie, że jest to przydatne w rzadkich przypadkach (głównie w celu optymalizacji wydajności, nie wyobrażam sobie innych przypadków). Może tak jest w przypadku, w którym prowadzisz, w przeciwnym razie doprowadziłoby to do wielu "złych enkapsulacji". ..

8

Zasadniczo nie dotyczy to środowiska Java. Kontrole dostępu są wykonywane tylko raz podczas procesu Resolution. Gdy metoda Java jest kompilowana JIT, referencje symboliczne są już rozwiązane i zweryfikowane. W rzeczywistości, wstawianie odbywa się nie na oryginalnym kodzie bajtowym, ale na specyficznej kompilacji reprezentacji pośredniej. Tak więc modyfikatory dostępu zwykle nie mają skutków ubocznych.

Jednakże, można napisać sztucznego sprawdzian gdzie private/public modyfikator znacząco wpływa na wydajność:

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 

Zjawisko to tłumaczy się metody syntezy access$000 które javac wytwarza się umożliwić dostęp do prywatnego członka klasy wewnętrznej. W powyższym teście ten dodatkowy akcesor zapobiega inlinowaniu, ponieważ domyślny maksymalny poziom wstawiania w HotSpot wynosi 9 (-XX:MaxInlineLevel=9). Ponieważ getPrivate() nie można wywołać bezpośrednio z klasy zewnętrznej, dodatkowa metoda access$000() tworzy 10. poziom wywołania i dlatego nie jest inline.

Powiązane problemy