[英]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很低。
幾乎是因為“這就是它的編寫方式”。 比較考慮了左手變量並將其與右側進行比較。 當你說null == s
,你會說“將null
與這個變量進行比較”,所以代碼定義了一個null
的常量來比較。 編譯器只是將其他比較優化為非空檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.