ChatGPT解决这个技术问题 Extra ChatGPT

在 Qt 中获取经过的时间

我正在寻找 Qt 中与 GetTickCount() 的等价物

可以让我测量一段代码运行所需的时间,如下所示:

uint start = GetTickCount();
// do something..
uint timeItTook = GetTickCount() - start;

有什么建议么?

对于 Qt 6,您不能使用 QTime,因为 QTime::elapsed()QTime::start() 在 Qt 5 中已经过时。

B
BaCaRoZzo

我认为使用 QElapsedTimer 可能会更好,因为这就是该类首先存在的原因。它是在 Qt 4.7 中引入的。请注意,它也不受系统时钟时间变化的影响。

示例用法:

#include <QDebug>
#include <QElapsedTimer>
...
...
QElapsedTimer timer;
timer.start();
slowOperation();  // we want to measure the time of this slowOperation()
qDebug() << timer.elapsed();

B
BaCaRoZzo

QTime 怎么样?根据您的平台,它应该具有 1 毫秒的精度。代码看起来像这样:

QTime myTimer;
myTimer.start();
// do something..
int nMilliseconds = myTimer.elapsed();

在我的 WinXP 虚拟机上,它似乎只有 10 毫秒的准确度 - 任何人都可以确认/否认这一点吗?对于我正在测试的操作,我得到了 0、10 和 20 的值。
在计时时,Windows 不如类 UNIX 操作系统准确。
IIRC,在 Windows XP 上,默认报告的系统时钟分辨率为 15 毫秒,但是通过一些简单的依赖于 Windows 的 winapi 调用,如果主板上只有 1 毫秒或更好的 RTSC,您仍然可以获得更好的分辨率
QTime 不提供 CPU 时间。它提供了总的实时时间,这意味着您也在测量所有其他过程所花费的时间。所以它对于测量代码的执行时间不是很有用。
这是一个等待发生的微妙而可怕的错误。它受系统时钟的影响。上帝禁止在您的计时器运行时发生夏令时。
s
sivabudh

即使第一个答案被接受,其他阅读答案的人也应该考虑 sivabudh 的建议。
QElapsedTimer 也可以用来计算以纳秒为单位的时间。
代码示例:

QElapsedTimer timer;
qint64 nanoSec;
timer.start();
//something happens here
nanoSec = timer.nsecsElapsed();
//printing the result(nanoSec)
//something else happening here
timer.restart();
//some other operation
nanoSec = timer.nsecsElapsed();

同样:这测量的是实时时间,而不是进程消耗的 CPU 时间。
它通过获取应用程序消耗的处理器滴答数并乘以每个滴答声的纳秒数来计算它。它测量进程消耗的 CPU 时间。
它测量自 start() 以来经过的时间,而不是进程消耗的时间。这是一个实时计时器。当进程被抢占时(由于多任务处理),时间会继续流逝,QElapsedTimer 也会对其进行测量。如果 QElapsedTimer 在进程被抢占时停止测量时间,它将几乎毫无用处。
@NikosC。来自 Qt 博客“Qt 有许多计时器,但对基准测试最有用的是 QElapsedTimer”,然后“QElapsedTimer 将使用最准确的时钟。但这也意味着计时器的实际分辨率和准确性可能会有很大差异系统之间。”。它从中选择最准确的时钟: qt-project.org/doc/qt-5/qelapsedtimer.html#ClockType-enum
D
Damien

扩展之前的答案,这是一个可以为您完成所有工作的宏。

#include <QDebug>
#include <QElapsedTimer>
#define CONCAT_(x,y) x##y
#define CONCAT(x,y) CONCAT_(x,y)

#define CHECKTIME(x)  \
    QElapsedTimer CONCAT(sb_, __LINE__); \
    CONCAT(sb_, __LINE__).start(); \
    x \
    qDebug() << __FUNCTION__ << ":" << __LINE__ << " Elapsed time: " <<  CONCAT(sb_, __LINE__).elapsed() << " ms.";

然后你可以简单地使用:

CHECKTIME(
    // any code
    for (int i=0; i<1000; i++)
    {
       timeConsumingFunc();
    }
)

输出:

onSpeedChanged:102 经过时间:2 毫秒。


B
BaCaRoZzo

如果要使用 QElapsedTimer,则应考虑此类的开销。

例如,以下代码在我的机器上运行:

static qint64 time = 0;
static int count = 0;
QElapsedTimer et;
et.start();
time += et.nsecsElapsed();
if (++count % 10000 == 0)
    qDebug() << "timing:" << (time / count) << "ns/call";

给我这个输出:

timing: 90 ns/call 
timing: 89 ns/call 
...

您应该自己衡量这一点,并尊重您的时间开销。


我同意。我试过 QElapsedTimer。它似乎有一些与使用该类相关的开销。但非常轻微。差别不是很大。但 QTime 似乎给了我更快的执行时间。我测量了 4 种方法的数字运算代码(3 次使用 QTime,3 次使用 QElapsedTimer)。 QElapsed 计时器平均测量 8.046 秒,QTime 平均测量 8.016 秒,相差 30 毫秒。对于大多数目的来说并不重要,但可能是为了绝对精确。这是在 Windows 7 64 位 PC Intel i5 上运行 QT 5.3.1 32 位。
请参阅此处的主题qtcentre.org/threads/…