为什么 System.nanoTime() 比 System.currentTimeMillis() 慢(在性能上)? [英] Why is System.nanoTime() way slower (in performance) than System.currentTimeMillis()?

查看:28
本文介绍了为什么 System.nanoTime() 比 System.currentTimeMillis() 慢(在性能上)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天我做了一个快速的 Benchmark 来测试 System.nanoTime()System.currentTimeMillis() 的速度性能:

long startTime = System.nanoTime();for(int i = 0; i <1000000; i++) {长测试 = System.nanoTime();}长结束时间 = System.nanoTime();System.out.println("总时间:"+(endTime-startTime));

结果如下:

System.currentTimeMillis():12.7836022/函数调用的平均值System.nanoTime():34.6395674/函数调用的平均值

为什么跑速差异这么大?

基准系统:

Java 1.7.0_25视窗 8 64 位中央处理器:AMD FX-6100

解决方案

来自这篇 Oracle 博客:><块引用>

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().在大多数系统上,它会给出微秒量级的分辨率.但请注意,在某些平台上此调用的执行时间也可能需要几微秒.

Today I did a little quick Benchmark to test speed performance of System.nanoTime() and 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));

This are the results:

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

Why are the differences in running speed so big?

Benchmark system:

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

解决方案

From this Oracle blog:

System.currentTimeMillis() is implemented using the GetSystemTimeAsFileTime method, which essentially just reads the low resolution time-of-day value that Windows maintains. Reading this global variable is naturally very quick - around 6 cycles according to reported information.

System.nanoTime() is implemented using the QueryPerformanceCounter/ QueryPerformanceFrequency API (if available, else it returns currentTimeMillis*10^6). QueryPerformanceCounter(QPC) is implemented in different ways depending on the hardware it's running on. Typically it will use either the programmable-interval-timer (PIT), or the ACPI power management timer (PMT), or the CPU-level timestamp-counter (TSC). Accessing the PIT/PMT requires execution of slow I/O port instructions and as a result the execution time for QPC is in the order of microseconds. In contrast reading the TSC is on the order of 100 clock cycles (to read the TSC from the chip and convert it to a time value based on the operating frequency).

Perhaps this answer the question. The two methods use different number of clock cycles, thus resulting in slow speed of the later one.

Further in that blog in the conclusion section:

If you are interested in measuring/calculating elapsed time, then always use System.nanoTime(). On most systems it will give a resolution on the order of microseconds. Be aware though, this call can also take microseconds to execute on some platforms.

这篇关于为什么 System.nanoTime() 比 System.currentTimeMillis() 慢(在性能上)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆