Fri*_*jof 62 java performance time
今天我做了一个快速的Benchmark来测试速度性能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));
Run Code Online (Sandbox Code Playgroud)
这是结果:
System.currentTimeMillis(): average of 12.7836022 / function call
System.nanoTime(): average of 34.6395674 / function call
Run Code Online (Sandbox Code Playgroud)
为什么跑步速度的差异如此之大?
基准系统:
Java 1.7.0_25
Windows 8 64-bit
CPU: AMD FX-6100
Run Code Online (Sandbox Code Playgroud)
Roh*_*ain 67
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().在大多数系统上,它将提供微秒级的分辨率.但请注意,此调用也可能需要几微秒才能在某些平台上执行.
Eel*_*lke 24
大多数操作系统(你没有提到你正在使用哪一个)都有一个内存计数器/时钟,它提供毫秒精度(或接近它).对于纳秒精度,大多数必须读取硬件计数器.与硬件通信比读取内存中的某些值要慢.