2011-11-04 406 views
6

我目前使用一個switch語句來處理有20個左右不同情況的傳入消息的類型。其中一些情況比其他情況更可能發生數量級。在很多情況下優化Java switch語句?

是熱點編譯器能夠優化的案件進行審查,以找到正確的情況下執行的順序,或者我應該構建我的代碼,這樣,最常見的情況先出現:

switch(messageType) 
{ 
    case MOST_COMMON: 
     // handle it 
     break; 

... 
    case LEAST_COMMON: 
     // handle it 
     break; 
} 

所有病例均互斥。

對於消息類型使用策略模式和Map查找會更好嗎?

性能是關鍵問題,因爲我每秒處理數千條消息,並試圖減少對象創建和方法調用開銷。

非常感謝,

克里斯

編輯: 謝謝你的指針。 messageType是一個int值,範圍很窄,因此看起來它會編譯爲「tableswitch」字節碼,因此不需要重新排序。 JVM規範的

相關部分在這裏http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14942

+1

IIRC大多數編譯器使用查找表處理C和C++中的'switch'語句。 Java可能會做同樣的事情。但我可能是錯的。 – NullUserException

+0

[Java:If vs. Switch]的可能重複(http://stackoverflow.com/questions/1061101/java-if-vs-switch) –

+0

JIT *應該*在執行過程中優化路徑。我會分析這兩種機制,以確定地看到。 –

回答

3

除非你確信這個開關語句引起你的性能問題,那麼我建議你過早優化。另外,請查看the accepted answer to this question

+0

嗨邁克,指出:)這段代碼處理每個工作日有數百萬個事件,並佔該計劃CPU週期的30%左右。在深入瞭解JVM規範之前,只是想了解關於JIT的意見。 – ChrisWhoCodes

3

如果案例是enum值或者是密集分佈的int值,那麼一旦JIT編譯器開始將它全部轉換爲查找表,那麼使用order排序不會對您有所幫助。

如果您使用的是Java7字符串開關或稀疏分佈的值,那麼最常見的應該是第一個,因爲它會變成類似if級聯集的測試和分支操作。

+0

與java7字符串開關它會慢一些,因爲它會變成級聯'如果'類似的語句它將使用'等於'字符串 – maks

+0

嗨邁克,開關在一個int值範圍很窄,所以我認爲答案是查找表並且不需要重新排序子句。 – ChrisWhoCodes

+0

@maks,我想我同意。您是否試圖將我的答案的一部分指向錯誤,或者只是在字符串開關上進行評論? –

1

switch語句是執行查找以確定要跳轉到哪個代碼塊。這不是一系列if/else檢查,並且聲明塊的順序對性能沒有影響。即所有情況下的價值都被平等地檢查。

它相同(爲一個小int值範圍)

goto case_label[messageType.ordinal()]; 

對於一個大的int值範圍不同的表結構中使用的僞代碼。 (我假設它是一個散列表)

CPU可以使用分支預測,如果一個案例比其他案例更普遍,那麼它可以動態優化執行。