2013-09-27 58 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毫秒。

相关问题