2013-09-27 57 views
55

今天我做了一些快速的基準測試的System.nanoTime()System.currentTimeMillis()高速性能:爲什麼System.nanoTime()方法比System.currentTimeMillis()更慢?

long startTime = System.nanoTime(); 

for(int i = 0; i < 1000000; i++) { 
    long test = System.nanoTime(); 
} 

long endTime = System.nanoTime(); 

System.out.println("Total time: "+(endTime-startTime)); 

這是結果:

System.currentTimeMillis(): average of 12.7836022/function call 
System.nanoTime():   average of 34.6395674/function call 

爲什麼在運行速度這麼大的差異?

基準系統:

Java 1.7.0_25 
Windows 8 64-bit 
CPU: AMD FX-6100 
+0

可能的重複[爲什麼System.nanoTime()和System.currentTimeMillis()漂移如此之快?](http://stackoverflow.com/questions/5839152/why-do-system-nanotime-and-system - 當前timemillis漂移分開如此迅速) – chrylis

+0

這篇文章可能會回答你的問題:http://stackoverflow.com/a/5839267/658907 – matts

+0

'nanoTime'比'currentTimeMillis'更精確,這可能是原因。 – Thomas

回答

61

this Oracle blog

System.currentTimeMillis()使用 GetSystemTimeAsFileTime方法,它本質上只是讀出低 解決時間的日值Windows維護執行。根據 報告的信息,讀取此 全局變量自然非常快 - 大約6個週期。

System.nanoTime()使用實施 QueryPerformanceCounter/ QueryPerformanceFrequency API(如果有的話, 否則返回currentTimeMillis*10^6)QueryPerformanceCounter(QPC)在這取決於它的運行對硬件的不同方式 實現的。通常它會使用 要麼可編程間隔計時器( PIT)或ACPI電源 管理計時器(PMT)或CPU級別時間戳計數器(TSC) 訪問PIT/PMT需要執行慢速I/O端口指令 ,因此執行時間爲QPC的排列順序爲 微秒,而讀取TSC的順序是100時鐘 週期(從芯片讀取TSC並根據工作頻率將其轉換爲時間值 )。

也許這回答了這個問題。這兩種方法使用不同數量的時鐘週期,從而導致後者的速度變慢。

而且在結論部分,其博客:

如果你有興趣在測量/計算經過的時間,然後一直使用System.nanoTime()。在大多數系統上,它將提供微秒級的分辨率。請注意,這個調用在某些平臺上也可能需要幾微秒來執行

+10

很好的答案。另外這個網站:http://stas-blogspot.blogspot.nl/2012/02/what-is-behind-systemnanotime.html有人做了一些研究,也顯示了不同操作系統下System.nanoTime背後的源代碼。 – MystyxMac

23

大多數OS的(使用的是哪一個你沒有提)有一個在內存計數器/時鐘,提供誤差在毫秒級(或接近)。對於納秒精度,大多數讀取硬件計數器。與硬件通信速度較慢,然後讀取內存中的某些值。

3

它可能只在Windows上。見this answer也有類似的問題。

基本上,System.currentTimeMillis()只是讀取由Windows維護的全局變量(這是它的低粒度),而System.nanoTime()實際上必須執行IO操作。

0

你正在測量,在Windows上,是不是。我在2008年完成了這個練習。nanoTime在Windows上比currentTimeMillis慢。我記得,在Linux上,nanotime比currentTimeMillis快,而且肯定比在Windows上快。

重要的是要注意的是,如果您要測量多個亞毫秒操作的聚合,則必須使用nanotime,就好像操作在小於1/1000秒的時間內完成代碼一樣,比較currentTimeMillis將顯示這些瞬間的操作仍然是瞬時的。你可能會想要做的就是使用nanotime然後四捨五入到最接近的毫秒,因此,如果操作了8000納秒它將被算作1毫秒,不是0

0

你可能想要做的就是使用nanotime然後舍入到最接近的毫秒,因此,如果把8000納秒的操作將被計數爲1毫秒,而不是0。

算術注:

8000納秒爲8微秒爲0.008毫秒。四捨五入將使其達到0毫秒。

相關問題