【问题标题】:Timing a block of code with C++ and Java使用 C++ 和 Java 对代码块进行计时
【发布时间】:2013-12-12 14:24:04
【问题描述】:

我正在尝试将计时方法的准确性与 C++ 和 Java 进行比较。

对于 C++,我通常使用 CLOCKS_PER_SEC,我运行我想要计时的代码块一段时间,然后根据代码块的执行次数计算它花费了多长时间。

对于 Java,我通常使用 System.nanoTime()

哪个更准确,我用于 C++ 的那个还是我用于 Java 的那个?有没有其他方法可以在 C++ 中计时,所以我不必重复这段代码来获得正确的测量结果?基本上,C++ 有System.nanoTime() 方法吗?

我知道两者都使用系统调用,这会导致相当大的延迟。这如何扭曲了时间的真实价值?有什么办法可以预防吗?

【问题讨论】:

    标签: java c++ time timing


    【解决方案1】:

    每个方法都有错误。在你花大量时间在这个问题上之前,你必须问自己“我需要我的答案有多准确”?通常解决方案是多次运行一个循环/一段代码,并跟踪测量的平均值/标准偏差。这是掌握测量重复性的好方法。之后,假设“开始时间”和“停止时间”调用之间的延迟是“可比的”(无论您使用什么函数),并且您有一个框架来理解这些问题。

    底线:clock() 函数通常提供微秒精度。

    请参阅https://stackoverflow.com/a/20497193/1967396 了解如何在 C 中进行此操作的示例(在这种情况下,使用 usec 精度时钟)。可以使用 ns 计时 - 例如,请参阅使用 clock_gettime(CLOCK_MONOTONIC_RAW, &tSpec);clock_gettime() still not monotonic - alternatives? 的答案

    请注意,您必须从该结构中分别提取秒和纳秒。

    【讨论】:

    • 在循环过程中,您真的可以通过跟踪标准偏差来确定方法的准确性吗?您的进程可能不是系统上运行的唯一进程,调度程序应该可以随时给它时间。
    • 我说标准差会给你一个可重复性的句柄:如果你多次这样做,你会得到相同的答案吗(几乎与“精度”相同)。这与 accuracy 不同:它是正确的答案吗?如果没有校准,您将无法知道这一点。很抱歉对命名法很挑剔。
    • @bruce14 - 其他需要注意的点 - 提供的大多数时钟(“挂钟”时钟除外)测量过程中经过的时间,因此它们可以补偿时间您的进程已暂停。 getrusage() 在这方面特别强大。
    • 我和你在一起,但 OP 要求准确性,所以这就是我质疑它的原因。但是您的第二条评论完全正确,因此我的问题无论如何都无关紧要。谢谢
    【解决方案2】:

    使用 System.nanoTime() 时要小心,因为它仍然受到您正在运行的机器可以提供的分辨率的限制。

    Java 的时间安排也很复杂,因为前几次通过函数会慢很多,直到它们针对您的系统进行优化。

    几乎所有现代系统都使用抢先式多线程和多核等 - 因此所有时间都会因运行而异。 (例如,如果控制在方法中从您的线程中切换)。

    要获得可靠的时间安排,您需要

    1. 在开始之前围绕您正在计时的事物运行数百次来预热系统。
    2. 多次运行代码并对结果取平均值。

    可靠性问题对于任何语言都是相同的,因此对于 C 和 Java 一样适用,因此 C 可能不需要预热循环,但您仍然需要获取大量样本并对它们进行平均。

    【讨论】:

    • 一个显示“热身”效果的好方法(在涉及网络连接时尤其明显,但即使内存缓存也可以播放)是记录每个循环后的(总)经过时间,然后绘制这些值与循环计数。在最初的几次迭代中,这条曲线的斜率可能会增加,然后稳定下来。我相信这正是您所描述的效果。
    • 缓存等可能会产生一些“热身”效果,即使在 C 中也是如此。在 Java 中,由于即时编译,这种效果更加明显。它最初几次运行字节码,然后逐渐越来越多的代码变成了针对其运行环境进行调整的汇编程序。
    • 根据标准,clock() 的时间应该是您的应用程序使用的 CPU 时间,因此切换出去然后再重新进入应该不会影响它。 (clock() 的 Windows 实现在这方面被破坏了。)当然,被另一个进程中断,然后继续,可能会影响缓存中有多少进程内存,进而影响性能。跨度>
    • 但是在你的应用程序中切换到另一个线程不会被检测到......并且你依赖于这种行为是一致和可靠的......
    猜你喜欢
    • 1970-01-01
    • 2015-01-11
    • 2021-05-07
    • 2011-06-06
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多