在一個長回圈前,冗余分配相同的值,還是分配前檢查成本更高(處理器 記憶體)?
int count = 0;
for(int i=0; i<100_000; i ){
if (...) {
count
doLogic(count); // logic is strictly related with count
} else {
count = 0; //50.000 redundant assignment
}
}
對比。
int count = 0;
for(int i=0; i<10_000; i ){
if (...) {
count
doLogic(count); // logic is strictly related with count
} else {
if(count > 0) { // 50.000 checks
count = 0;
}
}
}
如果count存在于不同的物件中(在 Spring 背景關系中作為單例注入),并且增量/檢查/重置將類似于:
config.incrementCount();
config.getCount();
config.resetCount();
uj5u.com熱心網友回復:
對你的問題的簡短回答是沒關系。兩種方法都具有大致相同的性能,并且很可能會被doLogic.
您的首選應該始終是撰寫簡單且符合地道的代碼,而不是過早地進行優化。
答案很長,這取決于(它總是如此,不是嗎?)。
首先,您并不真正知道JIT會對您的代碼進行什么樣的優化。對一個平臺和 Java 版本適用的情況可能不適用于另一種平臺和 Java 版本。你不能依賴任何沒有明確保證的東西。
其次,您知道他們對過早優化的看法。對代碼進行基準測驗和分析總是一個好主意,但即使是基準測驗也不是 100% 可靠的。
好的,讓我們進行基準測驗:
# First case, variable counter
Benchmark Mode Cnt Score Error Units
Benchmark1.testCounter avgt 8 0.149 ± 0.026 ms/op
Benchmark1.testCounterIf avgt 8 0.190 ± 0.036 ms/op
# Second case, counter in the wrapper class
Benchmark Mode Cnt Score Error Units
Benchmark1.testCounterClass avgt 8 0.198 ± 0.025 ms/op
Benchmark1.testCounterClassIf avgt 8 0.181 ± 0.016 ms/op
基準代碼
雖然對于簡單計數器變數的情況,“如果優化”似乎失敗了,但在第二種情況下,差異在誤差范圍內。
在我的基準測驗中,我只使用了一個簡單的靜態欄位持有Counter類。查看由 JIT 生成的 ASM,方法呼叫似乎是行內的。您的情況可能有所不同,因為企業 Java 和 Spring 因在幕后(例如通過代理和位元組碼操作)執行晦澀的魔法而臭名昭著。不僅方法可能不會被行內,而且一些隱藏的開銷可能會意外出現。
PS 如果您對 JVM 的性能和微優化感興趣,我建議您閱讀Alexey Shipilev 的 JVM Anatomy Quarks 系列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/342570.html
上一篇:與行內樣式相比,使用HTML屬性/標簽是否存在性能差異?
下一篇:如何用鍵盤和活動觸發按鈕
