如何测量用 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 编写的代码的速度? (人工智能算法)的主要内容,如果未能解决你的问题,请参考以下文章

如何测量数据结构的内存使用情况? [复制]

使用java获取网络利用率

一文解码:如何在人工智能热潮下实现产业“智”变

零基础如何转行Python人工智能?

如何在没有缓存的情况下测量文件读取速度?

如何使用请求测量下载速度和进度?