如何测量用Java编写的代码速度?
我计划开发一款软件,使用目前所有可用的AI和ML算法来解决数独问题,并将其与简单的暴力方法进行比较。我需要测量每种算法的时间,希望能提供关于最佳测量方法的建议。非常重要的是,程序必须在任何机器上都有用,无论CPU处理能力/内存如何。
谢谢。
如何测量用Java编写的代码速度?
我计划开发一款软件,使用目前所有可用的AI和ML算法来解决数独问题,并将其与简单的暴力方法进行比较。我需要测量每种算法的时间,希望能提供关于最佳测量方法的建议。非常重要的是,程序必须在任何机器上都有用,无论CPU处理能力/内存如何。
谢谢。
正如其他人所建议的,System.currentTimeMillis()
非常好用,但请注意以下注意事项:
System.currentTimeMillis()
度量的是经过的物理时间("墙上时钟时间"),而不是CPU时间。如果机器上运行了其他应用程序,您的代码将获得较少的CPU并且速度会降低。因此,请仅在闲置系统上进行基准测试。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%的变化。
我通常使用
System.currentTimeMillis()
计算时间差的方法:long start = System.currentTimeMillis();
/* do your algorithm iteration */
long elapsed = System.currentTimeMillis() - start;
请注意,根据您使用的操作系统,该函数的精度可能大于1毫秒(也可能是十分之一毫秒),因此您需要对其进行调整,以便对您的分析有用。
编辑:还有一种替代方法可以使用System.nanoTime()
完成相同的操作,但是您无法保证准确性达到纳秒级别。
这是另一种使用纳秒的方式
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);