【问题标题】:Why is System.nanoTime() way slower (in performance) than System.currentTimeMillis()?为什么 System.nanoTime() 比 System.currentTimeMillis() 慢(在性能上)?
【发布时间】:2013-10-03 20:13:39
【问题描述】:

今天我做了一点快速的基准测试来测试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

【问题讨论】:

标签: java performance time


【解决方案1】:

可能仅适用于 Windows。有关类似问题,请参阅 this answer

基本上,System.currentTimeMillis() 只是读取一个由 Windows 维护的全局变量(这就是它具有低粒度的原因),而 System.nanoTime() 实际上必须进行 IO 操作。

【讨论】:

    【解决方案2】:

    您可能想要做的是使用纳米时间然后四舍五入到最接近的毫秒,因此如果一个操作花费了 8000 纳秒,它将被计为 1 毫秒,而不是 0。

    算术笔记:

    8000 纳秒是 8 微秒是 0.008 毫秒。四舍五入将花费 0 毫秒。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      【解决方案4】:

      您是在 Windows 上测量的,不是吗。我在 2008 年完成了这个练习。nanoTime 在 Windows 上比 currentTimeMillis 慢。我记得,在 Linux 上,nanotime 比 currentTimeMillis 快,而且肯定比在 Windows 上快。

      需要注意的重要一点是,如果您尝试测量多个亚毫秒操作的聚合,则必须使用 nanotime,就好像操作在不到 1/1000 秒的时间内完成您的代码,比较 currentTimeMillis 将显示操作是瞬时的,因此其中 1,000 个仍然是瞬时的。您可能想要做的是使用 nanotime 然后四舍五入到最接近的毫秒,因此如果一个操作花费了 8000 纳秒,它将被计为 1 毫秒,而不是 0。

      【讨论】:

        【解决方案5】:

        大多数操作系统(您没有提到您使用的是哪一个)都有一个内存计数器/时钟,可提供毫秒精度(或接近该精度)。对于纳秒精度,大多数必须读取硬件计数器。与硬件通信比读取内存中的一些值要慢。

        【讨论】:

          猜你喜欢
          • 2019-07-04
          • 1970-01-01
          • 2011-08-15
          • 1970-01-01
          • 1970-01-01
          • 2011-08-25
          • 2010-11-20
          • 1970-01-01
          相关资源
          最近更新 更多