如何衡量用Java编写的代码速度?(AI算法)

18

如何测量用Java编写的代码速度?

我计划开发一款软件,使用目前所有可用的AI和ML算法来解决数独问题,并将其与简单的暴力方法进行比较。我需要测量每种算法的时间,希望能提供关于最佳测量方法的建议。非常重要的是,程序必须在任何机器上都有用,无论CPU处理能力/内存如何。

谢谢。


1
与主要问题无关,但也许会对你计划编写解决数独的软件有所帮助。请查看Norvig的解决方案。http://norvig.com/sudoku.html - hashable
+1 谢谢,是的我知道这个解决方案 - 很好的东西。 - Registered User
5个回答

21

正如其他人所建议的,System.currentTimeMillis() 非常好用,但请注意以下注意事项:

  • System.currentTimeMillis()度量的是经过的物理时间("墙上时钟时间"),而不是CPU时间。如果机器上运行了其他应用程序,您的代码将获得较少的CPU并且速度会降低。因此,请仅在闲置系统上进行基准测试。
  • 同样,在多核系统上运行的多线程应用程序可能会获得额外的隐藏CPU。经过时间的度量不能捕获多线程应用程序复杂性的全部内容。
  • Java需要一点“预热”。虚拟机将首先解释代码(这很慢),如果一个给定的方法使用次数过多,那么JIT编译器将把该方法转换为本地代码。只有在那个时候,该方法才能达到最高速度。我建议在调用 System.currentTimeMillis() 之前执行几个“空循环”。
  • System.currentTimeMillis() 的精度很少为1毫秒。在许多系统上,精度不超过10毫秒,甚至更多。此外,JVM有时会运行GC,引发明显的暂停。我建议您将测量组织成一个循环,并坚持运行至少几秒钟。

这导致以下代码:

for (int i = 0; i < 10; i ++) {
    runMethod();
}
int count = 10;
for (;;) {
    long begin = System.currentTimeMillis();
    for (int i = 0; i < count; i ++)
        runMethod();
    long end = System.currentTimeMillis();
    if ((end - begin) < 10000) {
        count *= 2;
        continue;
    }
    reportElapsedTime((double)(end - begin) / count);
}

你会发现,最开始有十个“空”运行。然后程序会在一个循环中多次运行该方法,直到循环至少需要十秒钟。十秒钟应该足以平滑GC运行和其他系统不准确性。当我测试哈希函数实现时,我使用两秒钟,即使该函数本身不触发任何内存分配,我仍然会获得高达3%的变化。


14

我通常使用

System.currentTimeMillis()
计算时间差的方法:
long start = System.currentTimeMillis();
/* do your algorithm iteration */
long elapsed = System.currentTimeMillis() - start;

请注意,根据您使用的操作系统,该函数的精度可能大于1毫秒(也可能是十分之一毫秒),因此您需要对其进行调整,以便对您的分析有用。

编辑:还有一种替代方法可以使用System.nanoTime()完成相同的操作,但是您无法保证准确性达到纳秒级别。


5

这是另一种使用纳秒的方式

long nanos = System.nanoTime();
// execute your stuff
long duration = System.nanoTime() - nanos;
int seconds = (int) (duration / 1000000000);
int milliseconds = (int) (duration / 1000000) % 1000;
int nanoseconds = (int) (duration % 1000000);
System.out.printf("%d seconds, %d milliseconds en %d nanoseconds\n", seconds, milliseconds, nanoseconds);

纳米级别的技术是额外的,但非常好。

2
在“大多数”机器上,纳秒是没有意义的。 - Jonathon Faust

4
尽管这里的所有答案都是正确的,但我建议实时测量可能并不完全与您的目标相关,即比较和对比不同的搜索算法以找到“最佳”算法。在这种情况下,更简单的方法是计算您搜索的节点数。虽然了解运行时间也很好,但由于每个算法可能以特定方式命中CPU/缓存/内存/磁盘,因此会有很多噪音。通过测量节点数,您正在查看搜索算法效果最好的最重要的度量,因为它搜索的节点越少,就越快地找到答案。

4
如果您对测量具有高精度要求,您应该测量CPU时间而不是“挂钟时间”。这样您就不会测量操作系统执行其他任务所花费的时间。为了测量此时间,您可以查看Java基准测试CPU时间

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