在Java中,System.currentTimeMillis()是衡量时间性能的最佳方式吗?

17

System.currentTimeMillis()在Java中是否是测量时间性能的最佳方法?使用它来比较操作前后所花费的时间时,是否存在任何问题?是否有更好的替代方案?


1
这里有一个很好的答案:https://dev59.com/BGDVa4cB1Zd3GeqPhuUl#9458267 - Dmitry Minkovsky
6个回答

13

我希望不需要这样做- 当我不使用 nanoTime() 时,这是我的选择。


10
在Windows系统下使用Sun JDK6时,nanoTime存在一个需要注意的问题,即返回值取决于执行线程的CPU核心。如果线程在一个核心上开始执行,并在另一个核心上完成执行,则计算出的时间将有些偏差。例如,当我使用类似于long start = System.nanoTime(); doIt(); long elapsedNanos = System.nanoTime() - start;的代码时,最终得到的elapsedNanos值为负数。 - gustafc
如果在开始和结束时间之间,线程被挂起了,那么结束时间实际上也会反映出挂起的时间。因此,结束时间减去开始时间并不是线程实际执行所花费的时间。 - Java Spring Coder

2

除了System.nanoTime()之外,JMX可能是最好的可行选项:

java.lang.management.ManagementFactory.getThreadMXBean()

您可以查询当前线程的CPU时间(以纳秒为单位进行测量,但不具有纳秒精度,就像System.nanoTime一样)。


2

为什么Guava Stopwatch比System.currentTimeMillis()更好? - Gaurav

1
如果您需要单调时间度量,System.nanoTime是更好的选择。System.currentTimeMillis受UTC定时变化的影响 -- 闰秒、NTP更新和抖动,以及用户设置系统时钟。这可能会在某些种类的计时应用程序中导致一些惊人的失败。System.nanoTime应该对所有这些都免疫。
System.nanoTime存在的问题包括周期性数字溢出和长期时间不准确性,使得System.currentTimeMillis在较长时间跨度上更好(前提是用户不要改变系统时钟)。请注意,夏令时和时区变化不应影响System.currentTimeMillis。
*Windows的“与互联网同步时间”会进行阶梯状的更改。这可能非常具有破坏性,而正式的NTP客户端实现则通过调整客户端时间基础频率来“追踪”服务器。

nanoTime 的最近的“周期性数字溢出”将在 2262-04-11 23:47:16 UTC+0 发生。 - Yahor

0

在Java 1.5之前,只有System.currentTimeMillis。然而,该值的粒度取决于底层操作系统,可能很大。在Windows XP上,我有时会出现20毫秒的间隙。我听说Linux在1-2毫秒的范围内更好。

使用Java 1.5,您还可以使用System.nanoTime。我从来没有遇到过这个问题。


-1
一个需要注意的问题是,这个方法测量的是实际经过的时间,而不是 CPU 时间 - 因此它非常依赖于系统负载。如果你在一个空闲的机器上,那么这很好,但如果其他进程正在尝试工作,有时会产生有趣的结果。 这篇文章提供了一个有趣的解决方案。

因为引用的链接不再可用,所以被踩了。请引用相关信息。 - ooxi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接