我正在尝试使用计时器测量算法的复杂性来测量执行时间,同时改变输入数组的大小。
我目前的代码很简单:
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中有一种简单的方法吗?
答案 0 :(得分:3)
测量执行时间是一个非常有趣但也很复杂的主题。要在Java中正确执行,您必须了解JVM的工作原理。 Here是developerWorks关于基准测试和测量的好文章。阅读它,它会帮助你很多。
作者还提供了一个用于执行基准测试的小框架。您可以使用此框架。它将为您提供所需的内容 - 占用CPU的时间,而不仅仅是之前和之后的两个时间戳。该框架还将处理JVM预热,并将跟踪即时编译。
您还可以为Eclipse使用this之类的性能监视器。这种性能监视器的问题在于它没有执行基准测试。它只跟踪应用程序当前使用的时间,内存和此类内容。但这不是一个真正的衡量标准 - 它只是特定时间的快照。
答案 1 :(得分:1)
答案 2 :(得分:1)
如果你想要当前线程(实际上是任意线程)的实际CPU时间而不是挂钟时间,那么你可以通过ThreadMXBean获得它。基本上,一开始就这样做:
ThreadMXBean thx = ManagementFactory.getThreadMXBean();
thx.setThreadCpuTimeEnabled(true);
然后,每当您想获得当前线程的经过的CPU时间时:
long cpuTime = thx.getCurrentThreadCpuTime();
你会看到ThreadMXBean也有调用来获取任意线程的CPU时间和其他信息。
关于时间复杂性的其他评论也适用。单个调用一段代码的时间可以取决于CPU的状态以及JIT编译器在该特定时刻决定做什么。算法的整体可伸缩性行为通常是在多个调用中出现的趋势,并且您将始终需要为您的计时中的某些“异常值”做好准备。
另外,请记住,仅仅因为特定时间表示以纳秒(或实际上是毫秒)计算并不意味着时间实际上具有该粒度。