Java中的CPU执行时间

时间:2011-09-19 06:34:59

标签: java time execution

我想计算我的函数在Java中执行需要多少CPU时间。目前我正在做如下。

   long startTime = System.currentTimeMillis();
    myfunction();
    long endTime = System.currentTimeMillis();
    long searchTime = endTime - startTime;

但我发现,对于相同的I / P,我会根据系统负载获得不同的时间。

那么,如何获得我的函数执行所需的精确CPU时间。

5 个答案:

答案 0 :(得分:25)

  1. System.currentTimeMillis()只会测量wall-clock time,而不会测量CPU时间。
  2. 如果您需要挂钟时间,那么System.nanoTime()通常比currentTimeMillis()更精确(并且永远不会更糟)。
  3. ThreadMXBean.getThreadCPUTime()可以帮助您了解给定线程使用了多少CPU时间。使用ManagementFactory.getThreadMXBean()获取ThreadMXBeanThread.getId()以查找您感兴趣的主题的id。请注意,每个JVM都不需要支持此方法!< / LI>

答案 1 :(得分:7)

随着JVM的升温,所用的时间会有所不同。第二次运行它总是比第一次快。 (第一次必须加载类并调用静态块)在运行方法10,000次之后,它将再次更快(将代码编译为本机机器代码的默认阈值)

为了获得微基准测试的可重现平均时间,我建议您忽略前10,000次迭代并在此之后运行2-10秒。

e.g。

long start = 0;
int runs = 10000; // enough to run for 2-10 seconds.
for(int i=-10000;i<runs;i++) {
    if(i == 0) start = System.nanoTime();
    // do test
}
long time = System.nanoTime() - start;
System.out.printf("Each XXXXX took an average of %,d ns%n", time/runs);

非常重要:每种方法只能执行其中一个循环。这是因为它根据使用方式优化了整个方法。如果你有一个像这样的繁忙循环,后面的循环将显得较慢,因为它们没有运行并且将被很好地优化。

答案 2 :(得分:1)

进行微基准测试的正确方法是学习并正确使用Java micobenchmark harness (JMH),从OpenJDK 12开始,JEP 230 Microbenchmark Suite对此进行了补充。搜索“ java jmh”将产生一些有用的教程的链接。我喜欢Jakob Jenkov's blog post,当然也喜欢Aleksey Shipilëv的任何东西,他是JMH的主要开发者和维护者。只需在提供的链接上选择JMH演讲中的最新版本即可。

Java基准测试并非易事,而经过测试的代码所做的工作越少,兔子漏洞就越深。当试图控制性能问题时,时间戳可能会非常误导。带有时间戳的地方是您尝试测量外部事件的等待时间(例如,等待对HTTP请求的答复等),只要您可以确保在两次事件之间花费的时间可以忽略不计。取消等待线程的阻塞并采用“之后”时间戳,只要首先适当地解除阻塞线程即可。当且仅当等待至少在几十毫秒的数量级时,通常是这种情况。如果您在某事上等待 seconds ,那就很好。尽管如此,预热和缓存效应仍会发生,并且每天都会破坏您的测量结果对实际性能的适用性。

就测量“确切的CPU时间”而言,可以采用Joachim Sauer的答案所详述的方法。使用JMH时,可以从外部测量CPU使用率,然后根据测得的迭代次数取平均值,但是由于这将包括线束的开销,该方法适合进行比较测量,但平均而言不适合得出“我的函数xy” ,在我使用的CPU体系结构的每次迭代中,都会花费如此多的CPU秒数。”在现代的CPU和JVM上,这种观察实际上是不可能的。

答案 3 :(得分:0)

你可以在这里寻找答案:

How do I time a method's execution in Java?

有很多例子来计算方法的执行时间

答案 4 :(得分:0)

有许多分析器(Jprofile,Jprobe,Yourkit)可用于分析此类数据。不仅如此,还有更多......(例如内存利用率,线程详细信息等)