亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么 Java 不優化 |= 賦值?

為什么 Java 不優化 |= 賦值?

楊__羊羊 2021-10-27 10:06:51
t*()對于此示例,始終返回 true,而f*()始終返回 false。假設我們有以下表達式if ( f1() || t1() || f2() || t2() ){    // do stuff        }如果是這種情況,JVM 會優化執行并僅執行,f1()并且t1()因為它“理解”無論什么f2()和t2()yield,都滿足了輸入 if 語句的要求,因此不需要進一步的計算。我正在編寫這樣的代碼:boolean b = false;b |= f1(); // Ab |= t1(); // Bb |= f2(); // Cb |= t2(); // D我的一位同事看到了這一點,并提到他不確定,但 Java 有可能優化語句 C 和 D,因為b總是true從語句B開始,這可能會導致一些問題。我進行了一些測試,似乎所有測試都被正確執行(這是所需的行為),但我仍然想知道為什么這沒有得到優化?我想他可能是對的,JVM 知道一旦b為真|=,對它的任何操作都不會改變它的值。
查看完整描述

3 回答

?
慕雪6442864

TA貢獻1812條經驗 獲得超5個贊

由于JLS §15.26.2,調用不會被優化掉。復合賦值運算符需要計算右側的表達式。

如果左操作數表達式不是數組訪問表達式,則:

  • 首先,評估左邊的操作數以產生一個變量。如果這個評估突然完成,那么賦值表達式也會因為同樣的原因突然完成;不計算右側操作數,也不進行賦值。

  • 否則,保存左側操作數的值,然后評估右側操作數。

  • ...

從歷史上看,短路條件 ( &&||) 而不是按位 ( &|) 運算符的傳統至少可以追溯到 C(但可能值得注意的是,C 直到 1999 年才具有明確的布爾類型)。


查看完整回答
反對 回復 2021-10-27
?
撒科打諢

TA貢獻1934條經驗 獲得超2個贊

我仍然想知道為什么這沒有得到優化?

因為那將違反 JLS。

該聲明

b |= f1();

相當于

b = (boolean)(b | f1());

另外,在上述中,JLS要求b | f1()如下評價:

  1. 獲取 的值b

  2. 調用f1()并捕獲結果值

  3. |運算符應用于兩個值。

該JLS不會讓編譯器跳過通話f1(),如果btrue1。

如果你想要那個語義(短路),你需要使用b = b || f1();等等。(正如您所指出的:b ||= f1()是語法錯誤。)


1 - 實際上,在無法(在單線程程序中)觀察到f1()調用發生或未發生的情況下,理論上可以允許優化。但是,您只能通過仔細檢查JIT 編譯器發出的本機代碼來檢測優化。只有在調用完全沒有副作用的情況下才會發生這種情況。


查看完整回答
反對 回復 2021-10-27
?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

這更多是關于布爾運算符和按位運算符之間的區別。

|=化合物運算符是一個位操作符,這意味著兩個術語進行了評價。

您可以通過設置一個測試來輕松調試它,其中b分配了 literal true,然后|=分配給返回任一boolean值的方法,并在其中設置斷點。

斷點將始終觸發。

另一方面,“快捷方式”優化僅適用于布爾運算符:||&&。

注意:這里有一些關于復合分配的規范,但我找不到有關|=分配的相關部分。


查看完整回答
反對 回復 2021-10-27
  • 3 回答
  • 0 關注
  • 173 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號