如何测量用 Java 编写的代码的速度? (人工智能算法)
Posted
技术标签:
【中文标题】如何测量用 Java 编写的代码的速度? (人工智能算法)【英文标题】:How can I measure the speed of code written in Java? (AI algorithms) 【发布时间】:2011-01-25 03:00:05 【问题描述】:如何衡量用 Java 编写代码的速度?
我计划开发软件,该软件将使用所有当前可用的 AI 和 ML 算法来解决数独问题,并将时间与简单的蛮力方法进行比较。我需要测量每个算法的时间,我想请教一下最好的方法是什么?非常重要,无论 CPU 功率/内存如何,程序都必须在任何机器上都有用。
谢谢。
【问题讨论】:
与主要问题无关,但考虑到您计划编写软件来解决数独问题,您可能会感兴趣。看看 Norvig 的解决方案。 norvig.com/sudoku.html +1 谢谢,是的,我知道这个解决方案 - 好东西 【参考方案1】:根据其他人的建议,System.currentTimeMillis()
相当不错,但请注意以下注意事项:
System.currentTimeMillis()
测量经过的物理时间(“挂钟时间”),而不是 CPU 时间。如果机器上正在运行其他应用程序,您的代码将获得更少的 CPU 并且其速度会降低。因此,只能在闲置的系统上进行测试。
同样,多核系统上的多线程应用程序可能会获得额外的隐藏 CPU。耗用时间度量并未涵盖多线程应用程序的全部复杂性。
Java 需要一些“热身”。 VM 将首先解释代码(这很慢),并且,如果给定的方法被使用太多次,那么 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% 的变化。
【讨论】:
【参考方案2】:我经常用
System.currentTimeMillis()
计算时间增量:
long start = System.currentTimeMillis();
/* do your algorithm iteration */
long elapsed = System.currentTimeMillis() - start;
请注意,根据您使用的操作系统,函数的精度可能大于 1 毫秒(也是十分之一毫秒),因此您必须对其进行调整以对您的分析有用。
编辑:也可以用System.nanoTime()
做同样的事情,但你不能保证精确到纳秒。
【讨论】:
【参考方案3】:这是另一种方式(以纳秒计)
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);
纳米是额外的,但很好。
【讨论】:
在“大多数”机器上,纳米是没有意义的。【参考方案4】:如果您对测量的高精度感兴趣,您应该测量 CPU 时间,而不是“挂钟时间”。这样你就不会测量操作系统花在做其他事情上的时间。为了测量这个时间你也许可以看看Java benchmarking CPU time
【讨论】:
【参考方案5】:尽管这里的所有答案都是有效的,但我建议测量实时可能与您的目标并不完全相关,即比较和对比不同的搜索算法以找到“最佳”。在这种情况下,计算您搜索的 节点 的数量要简单得多。虽然知道运行时间也很好,但由于每种算法都可能以特定方式影响 CPU/缓存/内存/磁盘,因此会涉及很多噪音。通过测量节点,您可以看到衡量搜索算法好坏的最重要的衡量标准,因为它搜索的节点越少,它找到答案的速度就越快。
【讨论】:
以上是关于如何测量用 Java 编写的代码的速度? (人工智能算法)的主要内容,如果未能解决你的问题,请参考以下文章