2012-09-12 24 views
1

最近我遇到了一個靜態代碼分析工具(PMD)抱怨switch聲明的分支太少的情況。它建議將它變成if語句,我不想​​這樣做,因爲我知道很快會有更多的案例會被添加。但我想知道javac是否執行這樣的優化。我使用JAD對代碼進行了反編譯,但它仍顯示出一個開關。這有可能是由JIT優化的運行時?jit優化switch語句時分支太少嗎?

更新:請不要被我的問題的背景誤導。我不是在問PMD,我沒有詢問是否需要微觀優化等等。問題顯然只有這個:當前的(Oracle 1.6.x)JVM實現是否包含一個JIT,它也可以處理交換機很少有分支機構。

+0

我想PMD有無關JIT? – gefei

+0

當然不是。問題不是這樣.. – jabal

回答

1

如果你在調試模式下編譯它,這是正常的,當你編譯它,你仍然可以獲得開關。否則,任何調試嘗試都會錯過一些信息,例如行號和原始指令流程。
因此,您可以嘗試在生產模式下編譯並查看反編譯結果。

但是,switch語句,特別是如果預期會增長,通常被認爲是代碼味道,應該被評估爲重構的一個好候選。

0

javac的性能幾乎沒有優化。所有的優化都是在運行時使用JIT來執行的。除非你知道你有性能問題,否則我會認爲你沒有。

PMD抱怨的是清晰度。例如

if (a == 5) { 
    // something 
} else { 
    // something else 
} 

是清楚不過

switch(a) { 
    case 5: 
     // something 
     break; 
    default: 
     // something else 
     break; 
} 
+1

問題是如果JIT做了這個特定的優化與否。 – jabal

1

至於你的問題是什麼後澄清。

因爲這會在硬件和JVM上取得如此強大的影響力(使用Java商標的JVM可能會由Oracle以外的公司開發,只要他們遵守JVM規範)Id說唯一有效的方法是提高速度試驗。

刪除一段代碼,將其鎖定在一個循環中進行大量重複,檢查循環執行前後的時間。重複這兩個解決方案(開關,如果)

這看似簡單的和愚蠢的,但它的實際工作,和很多比反編譯速度更快,通過字節碼閱讀和內存轉儲等


你有要記住,Java實際上使用虛擬機和字節碼。林相當肯定這是所有處理和優化。我們正在使用高級語言AVOID這樣的微觀管理和優化,你問的關於

在一個更通用的說明,我認爲你正在嘗試優化有點太早。如果你知道在這個轉換中會有更多的案例,爲什麼要這麼麻煩呢?你有沒有跑分析器?如果不是,它沒有用處優化。 「不成熟的優化是萬惡之源」。您可能正在優化一部分實際上不是瓶頸的代碼,增加了代碼的複雜性,並浪費了自己的時間來編寫不以任何方式貢獻的代碼。

我不知道你在做什麼類型的應用程序,但根據經驗法則,清晰度爲王,你通常應該選擇更簡單,更優雅,自我記錄的解決方案。

+0

這個問題與早期/不必要的優化無關。我一定不會那麼做,只是對JIT的工作方式感到好奇。 – jabal

2

的方式來確定JIT編譯器如何優化switch語句可以是:

  • 讀JIT編譯的源代碼(OpenJDK的6和7是開源),或
  • 與運行JVM開關,告訴它轉儲文件感興趣的類的JIT編譯代碼。

請注意,就像所有與性能和優化相關的問題一樣,答案取決於硬件平臺,JVM供應商和版本。

參考:Disassemble Java JIT compiled native bytecode


,如果這個問題是 「純粹無聊的好奇」,就這樣吧。

但是,還應該指出,出於性能原因重寫代碼以使用switchif可能是一個壞主意和/或浪費時間。

  • 這可能是在浪費時間,因爲有機會,在時間(如果有的話)的原件和手工優化版本之間的差異將是微不足道的。

  • 這是一個壞主意,因爲您的優化可能只對特定的硬件和JVM組合有幫助。在其他方面,它可能沒有影響......甚至是反優化。

簡而言之,即使您知道JIT優化程序如何處理此問題,您可能不應該在編程時將其考慮在內。

(當然,例外的情況是,當你有一個真正的衡量性能問題,併爲瓶頸之一剖析點(比如說)3支switch