簡體   English   中英

Java-執行時間

[英]Java - Time of execution

我有以下代碼:

public static void main(String[] args) {

    long f = System.nanoTime();

    int a = 10 + 10;

    long s =System.nanoTime();

    System.out.println(s - f);

    long g = System.nanoTime();

    int b = 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10;

    long h =System.nanoTime();

    System.out.println(h - g);

}

輸出結果:
測試1:

427
300

測試2:

533
300

測試3:

431
398

根據我的測試場景,為什么int b = 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10 + 10; int a = 10 + 10;執行得更快int a = 10 + 10;

眾所周知,微基准測試很難做到正確,特別是在Java等“智能”語言中,編譯器和Hotspot可以進行很多優化。 幾乎可以肯定,您沒有測試自己認為要測試的內容。 閱讀《 有缺陷的微基准測試解剖》以獲取更多詳細信息和示例(這是一篇相當古老的文章,但是原理仍然有效)。

在這種特殊情況下,我馬上就能看到至少三個問題:

  • 該代碼根本不會執行任何加法運算,因為編譯器將為變量分配其編譯時常量值。 (即好像您的代碼讀取int a = 20; int b = 120;
  • 在大多數系統上, nanoTime的粒度很高。 加上操作系統的負載,這將意味着您在測量中的實驗誤差遠大於結果本身的大小。
  • 即使發生了添加,您也沒有“預熱” VM。 通常,由於這個原因,您放第二個操作都會更快。

潛伏着更多的潛在危害。

故事的寓意是在現實條件下測試您的代碼 ,以查看其行為方式。 孤立地測試小部分代碼並假定總體性能將是這些部分的總和,這絕對不准確。

首先 Java編譯器執行常量表達式的優化,因此您的代碼在編譯時將轉換為:

int b = 120;

結果,JVM幾乎同時執行了對a=20b=120分配。

第二 您對大型系統進行簡短測量(我的意思是包括操作系統,交換進程,另一個運行進程...的整個計算機)。 因此,您可以在非常短的時間內獲得隨機系統的快照。 這就是為什么你不能推斷真或假的那a任務是要快b 為了證明這一點,您必須將代碼測量置於相當大的循環中-大約重復進行1,000,000次。 如此大的重復次數可以讓您放寬期望(從這個詞的數學意義上來說)

這不是衡量性能的正確方法。

首先,不要測量這么小的代碼。 而是像@NilsH所建議的那樣調用它數百萬次,然后通過將經過的時間除以調用次數來獲得平均時間。

其次,JVM可能會對您的代碼執行優化,因此您需要給它一個“熱身”時間。 在開始測量之前,使數百萬人“不運行”,而根本不計時間。

暫無
暫無

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

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