2017-04-19 71 views
1

我有一個Java程序,我正在嘗試用於平方根的新算法,並將它們與Java中的本機Math.sqrt(a)方法進行比較。我發現奇怪的是,第一次在程序中調用方法時,它至少需要50,000ns,而後面的時間只需要幾千個。這是否與在運行程序的頭幾個時刻計算系統時間有關,還是由於某些原因實際執行速度較慢?平方根法需要很長時間才能執行第一次嘗試

+1

幾乎可以肯定是類加載。嘗試使用'-verbose:class -verbose:jni -verbose:gc -XX:+ PrintCompilation'運行,並查看導致時間的原因。 – sprinter

回答

3

啓動Java應用程序有很大的開銷。

  • 需要加載JVM(java可執行文件)。
  • JVM需要進行引導:
    • 創建和初始化堆
    • 類加載
  • 你的類必須classloaded各種系統類。這通常會觸發系統類,第三方庫等的進一步分類加載。
  • 過了一會...... JIT編譯器開始將方法編譯爲本地代碼。
  • 發生這種情況時,GC可能會運行以清理由JIT編譯和類加載創建的垃圾。

所有這些加起來顯著啓動成本......相比(說)這是用C或C++實現,編譯和鏈接到一個可執行的應用程序。

但是,這個應該是相關的到開發和基準Java算法。您只需要以消除「JVM熱身」開銷的方式進行基準測試。有關詳細信息:


@ user7859067評論:

需要非常真棒性能,入鄉隨俗。

我假設你的意思是......將代碼實現爲Java本地方法。這對JVM引導開銷沒有幫助。而「本土化」並不總是贏,因爲從Java調用自定義本地方法時會有開銷。

但是,這是一個事實,許多Math函數的實現是在本機代碼...速度。 (JIT編譯器有調整功能來生成對「固有」本地方法的特殊快速調用,但是(AFAIK)不能在不修改JRE代碼庫的情況下自己使用它)。總之,如果您比較(純Java)實現的性能與標準(本地)Math.sqrt方法相比,您正在比較蘋果和橘子。

+0

我認爲7859067只是咆哮,意思是「根本不使用Java」,而不是「使用Java的本地方法」。 –

+0

也許吧。但是,他提出了一個重要的觀點,我正在給出一個「直接」的答案, –

相關問題