2013-07-19 41 views
0

我有關於JIT優化的問題。 我編了一段簡單的代碼:可以JIT優化這種不必要的呼叫嗎?

class btest 
{ 
     static final boolean flag=false; 

     public final void foo(int x) 
     { 
       if(flag) {a=x; b=x*2; c=x*3;} 
     } 

     public void bar(int y) {foo(y);} 

     int a,b,c; 
}; 

flag設置爲false所以foo()完美編譯成空碼 - 剛剛返回。 但bar()仍然調用它。

JIT是否有可能消除此呼叫? flag屬於外部類別嗎?

關於

回答

4

它可以消除它並在代碼中嵌入它。

注意:它也可以爲非易失性非最終變量執行此操作,它認爲線程不會更改該值。一個常見的錯誤是一樣的東西

boolean running = true; 

public void run() { 
    while(running) { 
     // do something 
    } 
} 

public void stop() { 
    running = false; 
} 

一個常見的誤解是,線程可能會保持運行的一段時間,但在一些未知點的時候,居然在JIT可能內聯running永不止步停止。

+0

爲什麼只是非最終?最終的變量是不是更加開放的說優化? – hexafraction

+0

@hexafraction它將爲原始最終變量和一些非最終變量執行此操作。 –

+0

所以,你認爲使用條件編譯if -s包裝在方法中(比如我的例子)而不是if -s在頂層,不太方便,可能不太優雅? – ardabro

1

JIT編譯器很可能會消除這種情況。

但實際上,我認爲if聲明可能會在之前被優化掉。原因是在JLS 14.21在哪裏是點開始這樣說:

「不過,爲了使,如果方便的使用聲明‘條件編譯’的目的,實際的規則不同。」

如果接着說,編譯器(也就是字節碼編譯!)可根據條件在編譯時已知值在你的榜樣產生不同的代碼。

請注意,此特殊處理僅適用於if報表,並且只有在條件爲的常數表達式時才適用。 (該術語具有非常具體的含義 - 請參閱JLS 15.28)例如,如果您嘗試使用與while循環相同的「技巧」,則會出現抱怨無法訪問的代碼的編譯錯誤。

(以下簡稱「條件編譯」特殊待遇追溯到到Java的早期,是高斯林的決策是不包含在Java語言中的預處理器的理由的一部分。)