[英]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
的粒度很高。 加上操作系統的負載,這將意味着您在測量中的實驗誤差遠大於結果本身的大小。 潛伏着更多的潛在危害。
故事的寓意是在現實條件下測試您的代碼 ,以查看其行為方式。 孤立地測試小部分代碼並假定總體性能將是這些部分的總和,這絕對不准確。
首先 。 Java編譯器執行常量表達式的優化,因此您的代碼在編譯時將轉換為:
int b = 120;
結果,JVM幾乎同時執行了對a=20
和b=120
分配。
第二 。 您對大型系統進行簡短測量(我的意思是包括操作系統,交換進程,另一個運行進程...的整個計算機)。 因此,您可以在非常短的時間內獲得隨機系統的快照。 這就是為什么你不能推斷真或假的那a
任務是要快b
。 為了證明這一點,您必須將代碼測量置於相當大的循環中-大約重復進行1,000,000次。 如此大的重復次數可以讓您放寬期望(從這個詞的數學意義上來說)
這不是衡量性能的正確方法。
首先,不要測量這么小的代碼。 而是像@NilsH所建議的那樣調用它數百萬次,然后通過將經過的時間除以調用次數來獲得平均時間。
其次,JVM可能會對您的代碼執行優化,因此您需要給它一個“熱身”時間。 在開始測量之前,使數百萬人“不運行”,而根本不計時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.