如何衡量用Java编写的代码的速度?
我计划开发软件,使用所有目前可用的AI和ML算法解决数独,并将时间与简单的强力方法进行比较。我需要测量每种算法的时间,我想问一下最好的方法是什么?非常重要的是,无论CPU功率/内存如何,程序都必须在任何机器上都有用。
谢谢。
答案 0 :(得分:19)
正如其他人所建议的,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%的变化。
答案 1 :(得分:12)
我通常使用
System.currentTimeMillis()
计算时间的增量:
long start = System.currentTimeMillis();
/* do your algorithm iteration */
long elapsed = System.currentTimeMillis() - start;
请注意,根据您使用的操作系统,功能的精度可能大于1毫秒(也是十分之一毫秒),因此您必须调整它以便对您的分析有用。
编辑:还可以选择使用System.nanoTime()
执行相同的操作,但您无法保证准确度为纳秒。
答案 2 :(得分: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);
纳米是额外的,但很好。
答案 3 :(得分:4)
如果您对测量中的大量精确度感兴趣,则应测量CPU时间,而不是“挂钟时间”。这样你就不会衡量操作系统花费其他时间的时间。为了衡量这个时间,您可以查看Java benchmarking CPU time
答案 4 :(得分:4)
虽然这里的所有答案都是有效的,但我建议测量实时可能与您的目标不完全相关,即比较和对比不同的搜索算法以找到“最佳”。在这种情况下,计算搜索的节点的数量要简单得多。虽然很高兴知道运行时间,但由于每种算法都可能以特定方式击中CPU /缓存/内存/磁盘,因此会产生很多噪音。通过测量节点,您可以看到搜索算法有多好的唯一最重要的衡量标准,因为它搜索的节点越少,它就能越快找到答案。