Java - 测量方法执行时间

时间:2012-05-05 16:32:20

标签: java multithreading timing stopwatch

我正在尝试使用计时器测量算法的复杂性来测量执行时间,同时改变输入数组的大小。

我目前的代码很简单:

public void start() {
    start = System.nanoTime();
}

public long stop() {
    long time = System.nanoTime() - start;
    start = 0;
    return time;
}

看起来工作正常,直到数组的大小变得非常大,而我期望的O(n)复杂度算法看起来似乎是O(n ^ 2)。我认为这是由于CPU的线程化,其他进程在运行期间切入的时间更长,n值更大。

基本上,我想测量我的进程运行的时间,而不是自我调用算法以来已经花了多长时间。在Java中有一种简单的方法吗?

3 个答案:

答案 0 :(得分:3)

测量执行时间是一个非常有趣但也很复杂的主题。要在Java中正确执行,您必须了解JVM的工作原理。 Here是developerWorks关于基准测试和测量的好文章。阅读它,它会帮助你很多。

作者还提供了一个用于执行基准测试的小框架。您可以使用此框架。它将为您提供所需的内容 - 占用CPU的时间,而不仅仅是之前和之后的两个时间戳。该框架还将处理JVM预热,并将跟踪即时编译。

您还可以为Eclipse使用this之类的性能监视器。这种性能监视器的问题在于它没有执行基准测试。它只跟踪应用程序当前使用的时间,内存和此类内容。但这不是一个真正的衡量标准 - 它只是特定时间的快照。

答案 1 :(得分:1)

Java中的基准测试是一个问题,尤其是因为随着您的方法得到越来越多的优化,JIT会产生奇怪的效果。考虑使用像Caliper这样的专用工具。如何使用它并测量不同输入大小的性能的示例是here

答案 2 :(得分:1)

如果你想要当前线程(实际上是任意线程)的实际CPU时间而不是挂钟时间,那么你可以通过ThreadMXBean获得它。基本上,一开始就这样做:

ThreadMXBean thx = ManagementFactory.getThreadMXBean();
thx.setThreadCpuTimeEnabled(true);

然后,每当您想获得当前线程的经过的CPU时间时:

long cpuTime = thx.getCurrentThreadCpuTime();

你会看到ThreadMXBean也有调用来获取任意线程的CPU时间和其他信息。

关于时间复杂性的其他评论也适用。单个调用一段代码的时间可以取决于CPU的状态以及JIT编译器在该特定时刻决定做什么。算法的整体可伸缩性行为通常是在多个调用中出现的趋势,并且您将始终需要为您的计时中的某些“异常值”做好准备。

另外,请记住,仅仅因为特定时间表示以纳秒(或实际上是毫秒)计算并不意味着时间实际上具有该粒度。