簡體   English   中英

用Java測量時間

[英]Measuring time in Java

所以我試圖測量兩個不同的算法實現完成給定任務所花費的時間,結果如下:

i    alg1  alg2
4   0.002   0.0
5   0.001   0.0
6   0.003   0.002
7   0.023   0.01
8   0.055   0.041
9   0.056   0.0
10  0.208   0.101
11  1.767   0.694
12  18.581  7.784

i只是一些輸入參數。

我已經使用以下(天真)函數測量了算法的性能:

private double getDuration() {
    return (double)(System.currentTimeMillis() - startTime) / (double)1000;
}

獲得更多真實結果(除了0.0,顯然不是真的!)比使用System.currentTimeMillis()更好的方法是什么? 我知道我可以一遍又一遍地運行算法並總結他們的結果,但我有這種直覺,可能有一些更健壯的方法來測量Java中的傳遞時間(如果可能的話, realusersys !)。

謝謝

對於基本計時,您可以使用Guava的Stopwatch (或者如果您不想引入整個Guava庫,只需獲取其源代碼)。 有關更完整的基准測試解決方案,請查看同一團隊的Caliper

這兩個都基於System.nanoTime() ,您應該System.currentTimeMillis()來測量經過的時間。 基本原因是System.currentTimeMillis()是一個“時鍾”(試圖返回System.nanoTime()時間),而System.nanoTime()是一個“計時器”(它嘗試從某個任意點返回時間)。

當你想要弄清楚單個事件發生的時候,你想要一個時鍾,所以你可以用你的手表或牆上的時鍾(或其他計算機的時鍾)排隊。 但它不適合測量同一系統上兩個事件之間的經過時間,因為計算機偶爾會調整其內部時鍾對應於掛壁時間的概念。 例如,如果你這樣做

long timeA = System.currentTimeMillis();
doStuff();
long timeB = System.currentTimeMillis();
System.out.println("Elapsed time: " + (timeB - timeA));

如果在執行doStuff()時NTP向后調整,則可能會得到否定結果。 System.nanoTime() ,作為計時器而不是時鍾,應該忽略該調整,從而避免這個問題。

(請注意,以上所有內容都是概念性的;不幸的是,在實現級別上事情可能會變得混亂。但這並不會改變建議: System.nanoTime()應該是您可以在平台上獲得的最佳計時器,而System.currentMilliseconds()應該是你能得到的最佳時鍾。)

System.nanoTime(); 也許,正是你在尋找的。 並添加標准偏差和平均時間的計算。

您應該考慮多次運行算法並對結果求平均值。

這有三個原因:

  1. 由於您已確定的原因,它使計時更容易。

  2. JVM“預熱”並且代碼的性能將會發生變化:熱點JVM在您運行多次方法之前不會完全編譯。 如果你沒有通過這個,你的結果就不具代表性。

  3. 平均時間,避免因GC等外部事件或計算機上運行的其他事件造成的虛假影響總是一個好主意。

根據經驗,嘗試運行你的algos 10,000次作為熱身,然后10,000次運行。 修改數字以適合您的運行時...

這是一篇解釋同樣事情的文章

您可以檢測代碼並計算執行的字節碼數。 你可以用bycounter做到這一點

這可能不適合您的目的。 如果程序只有很少的字節碼,那么它可能無法准確測量哪個程序實際上更高效,因為執行字節碼的成本可能會有很大差異。 此外,如果在程序期間有網絡或磁盤讀取,字節碼計數可能會給出錯誤的比較。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM