這段代碼有沒有什麼缺點,看起來是java.lang.Math.round
更快(更正確)的版本?更快執行Math.round?
public static long round(double d) {
if (d > 0) {
return (long) (d + 0.5d);
} else {
return (long) (d - 0.5d);
}
}
它需要的事實,即,在Java中,截斷長回合零。
這段代碼有沒有什麼缺點,看起來是java.lang.Math.round
更快(更正確)的版本?更快執行Math.round?
public static long round(double d) {
if (d > 0) {
return (long) (d + 0.5d);
} else {
return (long) (d - 0.5d);
}
}
它需要的事實,即,在Java中,截斷長回合零。
有一些special cases內置方法處理,你的代碼不處理。從文檔:
NaN
,結果爲0Integer.MIN_VALUE
值的任何值,則結果等於值Integer.MIN_VALUE
。Integer.MAX_VALUE
的值的任何值,則結果等於Integer.MAX_VALUE
的值。是;你沒有考慮下溢或溢出。從實際的角度來說,這可能對您的應用程序無關緊要。
我一直在測試這個,有一個關鍵的潛在缺點,這裏還沒有描述:您正在更改rounding tie-breaking方法。
Math.round()
實現了「圓形半邊」規則,而您的round()
方法實現了「圓形零距離」規則。
例如:
Math.round(-0.5d)
=>0L
Your.round(-0.5d)
=>-1L
這可能也可能不適合你有問題,但應瞭解的是,上述方法是不是對Math.round()
的直接替換,即使在已經列出NaN和無限大考慮之後。
另一個相關問題:Rounding negative numbers in Java
至於性能,這是毫無疑問的是,上述方法是顯著快於Math.round()
- 它運行在的時間爲隨機生成的正和負值約35%。在緊密循環中調用此方法時,這可能是一種有價值的優化。當僅給出正值時,它甚至更好(25%的運行時間),可能是因爲CPU使用branch prediction。
Math.round()
最終由本地JNI調用實現,這可能是性能差異的原因。 This Sun/Oracle bug表明在j6u22中可能存在純Java版本,但我無法看到j6u23中的哪個位置,實際上Math.round()
與我在測試中的j6u16相似。我沒有在其他版本上測試過。
@TrueWill:如果它整齊地放在一個正確命名的函數中......它真的很重要嗎?也許它正在用於數學密集型計劃。 – Sivvy 2009-11-17 18:20:16
很少有人會爲從1開始的方法找到更快的方法。0,同時保持原始方法的100%一致性。 – TofuBeer 2009-11-17 18:32:24
絕對是一個微型優化,在當地意義上是值得的。 - 但這些不推薦用於一般用途。 – mrjbq7 2009-11-17 18:53:20