簡體   English   中英

為什么java編譯器沒有重寫這段代碼?

[英]why doesn't the java compiler rewrite this code?

我正在測試這段代碼:

public class TestNull {
   public void leftComparison(String s) {
       if (s == null);
   }
   public void rightComparison(String s) {
       if (null == s);
   }
}

我用javac 1.8.0_05編譯它,然后檢查字節碼:

public class TestNull {
  ....
  public void leftComparison(java.lang.String);
    Code:
       0: aload_1       
       1: ifnonnull     4
       4: return        

  public void rightComparison(java.lang.String);
     Code:
       0: aconst_null   
       1: aload_1       
       2: if_acmpne     5
       5: return        
}

顯然, leftComparison被編譯為在堆棧上推送和彈出1個變量,而rightComparison推送和彈出2.我推測leftComparison因此比rightComparison稍微有效?

我想知道為什么編譯器不會重寫rightComparison的代碼? 在我看來,這兩個比較應該在語義上是等價的,對吧?

Java字節碼編譯器在優化方面做得很少。 嚴重的優化工作幾乎全部由JIT編譯器完成。

我想知道為什么編譯器不會重寫rightComparison的代碼?

因為重寫它沒有意義。 JIT編譯器應該能夠處理它們,並且很可能為這兩個版本生成最佳(本機)代碼。 (如果您感興趣,可以檢查一下。有很多方法可以查看JIT編譯器生成的本機代碼。)

(另請參閱@ codenheim的答案以獲得更多技術解釋。)

在我看來,這兩個比較應該在語義上是等價的,對吧?

這是正確的......但這並不意味着字節碼編譯器有義務為兩個版本生成相同的字節碼序列。


這里真正的教訓是,字節碼編譯器生成的字節碼序列幾乎不會告訴您代碼實際執行的方式。 您可能從讀取字節碼中得出的任何性能結論都是非常可疑的

實際上,字節碼相當於中間代碼。 過早優化或優化兩次的ROI很低。

  1. 它引入了不必要的維護開銷層。
  2. 當我們了解目標平台時,最好進行優化。 無論如何,基於Java堆棧的指令集不適合高級優化。 它太簡單了(按設計)。 我們可以通過改變一些基於堆棧的操作碼來實現這么多“優化”。 雖然在javac中進行大量高級“無腦”優化是可行的,但我認為實用主義在這里已經取得了成功,我們將其歸功於JIT,它可以利用更豐富的本機構造和技術(不同通過平台)在字節碼中不可用。

幾乎是因為“這就是它的編寫方式”。 比較考慮了左手變量並將其與右側進行比較。 當你說null == s ,你會說“將null與這個變量進行比較”,所以代碼定義了一個null的常量來比較。 編譯器只是將其他比較優化為非空檢查。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM