如何衡量用 Java 编写的代码的速度? (人工智能算法)

发布于 2024-08-24 12:26:08 字数 189 浏览 4 评论 0原文

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

我计划开发软件,使用所有当前可用的 AI 和 ML 算法来解决数独问题,并将时间与简单的暴力比较 -力法。我需要测量每个算法的时间,我想询问最好的方法是什么?非常重要的是,程序必须在任何机器上都可用,无论 CPU 功率/内存如何。

谢谢。

How can I measure the speed of code written in Java?

I planning to develop software which will solve Sudoku using all presently available AI and ML algorithms and compare time against simple brute-force method. I need to measure time of each algorithm, I would like to ask for suggestions on what is the best way of doing that? Very important, program must be useful on any machine regardless to CPU power/memory.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

比忠 2024-08-31 12:26:08

正如其他人所建议的,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% 的变化。

As suggested by others, System.currentTimeMillis() is quite good, but note the following caveats:

  • System.currentTimeMillis() measures elapsed physical time ("wall clock time"), not CPU time. If other applications are running on the machine, your code will get less CPU and its speed will decrease. So, bench only on otherwise idle systems.
  • Similarly, a multi-threaded application on a multicore system may get extra, hidden CPU. The elapsed time measure does not capture the whole of the complexity of multi-threaded applications.
  • Java needs a bit of "warm-up". The VM will first interpret code (which is slow), and, if a given method is used too many times, then the JIT compiler will translate the method to native code. Only at that point will the method reach its top speed. I recommend that you perform a few "empty loops" before calling System.currentTimeMillis().
  • Accuracy of System.currentTimeMillis() is rarely of 1 ms. On many systems, accuracy is no better than 10 ms, or even more. Also, the JVM will sometimes run the GC, inducing noticeable pauses. I suggest that you organize your measure in a loop and insist upon running for at least a few seconds.

This yields the following code:

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);
}

As you see, there is first ten "empty" runs. Then the program runs the method in a loop, as many times as necessary so that the loop takes at least ten seconds. Ten seconds ought to be enough to smooth out GC runs and other system inaccuracies. When I bench hash function implementations, I use two seconds, and even though the function itself triggers no memory allocation at all, I still get variations of up to 3%.

尘曦 2024-08-31 12:26:08

我通常用来

System.currentTimeMillis()

计算时间增量:

long start = System.currentTimeMillis();
/* do your algorithm iteration */
long elapsed = System.currentTimeMillis() - start;

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

编辑:还有一种选择是使用 System.nanoTime() 执行相同的操作,但您不能保证精度为纳秒。

I usually use

System.currentTimeMillis()

to calculate deltas of time:

long start = System.currentTimeMillis();
/* do your algorithm iteration */
long elapsed = System.currentTimeMillis() - start;

Mind that depending on the operating system you use the precision of the funcion could be greater than 1 millisecond (also tenth of msecs) so you'll have to tweak it to be useful for your analysis.

EDIT: there is also the alternative of doing the same thing with System.nanoTime() but you don't have any guarantee that accuracy will be of nanoseconds.

年少掌心 2024-08-31 12:26:08

这是另一种方式(使用纳秒)

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);

纳秒是额外的,但很好。

This is another way (with nanoseconds)

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);

The nanos are extra, but nice.

墨落成白 2024-08-31 12:26:08

如果您对测量的高精度感兴趣,您应该测量 CPU 时间,而不是“挂钟时间”。这样您就不会测量操作系统执行其他操作所花费的时间。为了测量这个时间,您也许可以查看 Java benchmarking CPU time

If you are interested in a lot of precision in your measurements, you should measure CPU time, not 'wall clock time'. That way you will not measure the time the OS spends doing something else. In order to measure this time you can perhaps look at Java benchmarking CPU time

你在看孤独的风景 2024-08-31 12:26:08

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

Although all the answers here are valid, I would propose that measuring real time may not be an entirely relevant to your goal, which is to compare and contrast varying search algorithms to find the "best". In this case, it's much simpler to count the number of nodes you search. While it's nice to also know the run time, there's a lot of noise involved since each algorithm may hit the CPU/cache/memory/disk in a particular way. By measuring nodes, you're looking at the single most important measure of how good a search algorithm is, since the fewer nodes it searches, the quicker it will find the answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文