QElapsedTimer

QElapsedTimer是Qt提供的一种跨平台的计时器类,用于精确测量代码执行时间和延迟,支持毫秒和纳秒级别。它能检查高分辨率定时器的可用性,并提供start(),restart(),elapsed()等接口。文章通过代码示例展示了如何使用QElapsedTimer进行计时以及实现延迟功能。在使用时需要注意计时器的有效性和适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍

QElapsedTimer是Qt框架中提供的一个类,主要用于测量代码执行时间和延迟时间。它可以在不同操作系统上提供准确的计时,并返回毫秒或纳秒级别的时间。

使用QElapsedTimer 可以轻松地测量一段程序的运行时间。例如,在两个函数之间测量时间,可以使用QElapsedTimer记录开始时间,然后再记录结束时间,最终计算两个时间值之差即可得到该函数的运行时间。

除了基本的计时功能外,QElapsedTimer还具有许多其他特性。例如,它可以在运行时检查操作系统的高分辨率定时器是否可用,以提供更准确的计时精度。另外,QElapsedTimer 还支持重置计时器(restart)功能,以允许测量间隔内发生的事件。

总之,QElapsedTimer 是Qt开发中非常常用的计时工具,能够帮助程序员快速、准确地测量代码的运行时间和延迟时间,从而优化代码性能。

接口函数

QElapsedTimer类提供了多个接口函数,以下是一些常用的接口函数及其作用:

  1. start():启动计时器,并返回当前时间值。
  2. restart():重新启动计时器,并返回从上一次启动以来的时间值。
  3. elapsed():返回从启动或重启计时器以来经过的毫秒数。
  4. nsecsElapsed():返回从启动或重启计时器以来经过的纳秒数。
  5. isValid():检查操作系统是否支持精准计时器,如果支持则返回true。
  6. invalidate():使计时器失效,即它不再返回正确的时间。
  7. hasExpired():用于检查QElapsedTimer计时器是否已经到达了设定的超时时间的函数

代码示例

下面代码演示了基本函数的使用方法和延时功能的实现。

#include <QtCore/QCoreApplication>
#include <QtCore/QElapsedTimer>
#include <QtCore/QDebug>
#include <QDateTime>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 创建 QElapsedTimer 对象
    QElapsedTimer timer;

    // 确认计时器有效性
    if (timer.isValid()) {
        qDebug() << "QElapsedTimer is valid before starting.";
    } else {
        qDebug() << "QElapsedTimer is invalid before starting.";
    }

    // 启动计时器
    timer.start();

    // 确认计时器有效性
    if (timer.isValid()) {
        qDebug() << "QElapsedTimer is valid when started.";
    } else {
        qDebug() << "QElapsedTimer is invalid when started.";
    }

    // 处理一些任务...
    for (int i = 0; i < 200000000; i++);

    // 记录结束时间点并计算耗时
    qint64 endTime = timer.nsecsElapsed();
    qDebug() << "Time elapsed:" << endTime << "ns";

    // 重启计时器并处理下一个任务
    quint64 restartTime = timer.restart(); //返回的是毫秒,上一次start到当前的时间
    qDebug() << "restarted time:" << restartTime << "ms";
    for (int i = 0; i < 400000000; i++);

    // 再次记录时间差并打印结果
    qint64 elapsedTime = timer.nsecsElapsed();
    qDebug() << "Total elapsed time:" << elapsedTime << "ns";

    // 使计时器失效
    timer.invalidate();
    if (timer.isValid()) {
        qDebug() << "QElapsedTimer is valid.";
    } else {
        qDebug() << "QElapsedTimer is invalid.";
    }

    //延时两秒1
    qDebug()<<"before delay1:"<<QDateTime::currentDateTime();
    QElapsedTimer timer2;
    timer2.start();
    while (timer2.elapsed() < 2000) {
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
    qDebug()<<"after delay1:"<<QDateTime::currentDateTime();

    //延时两秒2
    qDebug()<<"before delay2:"<<QDateTime::currentDateTime();
    QElapsedTimer timer3;
    timer3.start();
    while (!timer3.hasExpired(1999)) {
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
    qDebug()<<"after delay2:"<<QDateTime::currentDateTime();

    return a.exec();
}

运行代码输出如下结果:

QElapsedTimer is invalid before starting.
QElapsedTimer is valid when started.
Time elapsed: 309845260 ns
restarted time: 309 ms
Total elapsed time: 586009450 ns
QElapsedTimer is invalid.
before delay1: QDateTime(2023-06-12 16:46:25.016 CST Qt::LocalTime)
after delay1: QDateTime(2023-06-12 16:46:27.016 CST Qt::LocalTime)
before delay2: QDateTime(2023-06-12 16:46:27.016 CST Qt::LocalTime)
after delay2: QDateTime(2023-06-12 16:46:29.016 CST Qt::LocalTime)

结论:

1.start调用前QElapsedTimer是无效的

2.支持纳秒级别的计时

3.elapsed和restart返回的时间单位是毫秒

注意事项

使用QElapsedTimer计时器组件时,有以下一些注意事项:

  1. QElapsedTimer记录的是自系统启动或上次重启以来经过的时间,而不是当前时间。因此,使用elapsed()nsecsElapsed()方法来检查经过的时间时应格外小心。

  2. 调用restart()函数前必须先调用isValid()函数来检查计时器是否有效,否则将可能导致程序崩溃。

  3. 在Linux操作系统上,由于精度问题可能存在较大的误差,建议使用clock_gettime()等高精度的计时器来代替QElapsedTimer

  4. QElapsedTimer通常用于计算较短的时间间隔,如果需要计算较长的时间间隔,可以考虑使用QDateTimeQTime组件。

  5. 在计算耗时操作时,应该避免在繁忙的UI线程中进行,否则会影响UI的响应。

  6. 如果需要暂停计时器,在实现中需注意记录已经经历的时间,同时根据具体信息选择合适的参数数据类型。

实现原理

QElapsedTimer是Qt提供的计时器组件,它并不依赖于操作系统提供的计时器实现,而是通过使用CPU指令周期计数器来计算经过的时间。

在大多数计算机硬件上,CPU会有一个高精度的计时器,每个CPU时钟周期都会自动增加该计数器的值。在一定条件下,对比两个计数器的值就可以计算出时间差,从而得到经过的时间。

具体来说,QElapsedTimer主要利用了以下两种方式获取计时器值:

  1. 使用QBasicTimer在后台定期更新计时器值。当调用start()方法时,会创建一个QBasicTimer定时器并在后台以给定的间隔更新计时器值。通过elapsed()nsecsElapsed()函数可以获取并返回这个计时器值(单位为n秒),即所需要的经过的时间。

  2. 通过直接读取系统底层的计时器寄存器来获取计时器值。这种方式需要使用一些平台特定的汇编语言代码来访问硬件寄存器,因此不同平台之间实现所需的代码可能会有所不同。在此种情况下,通过调用clock_gettime()函数等进行精度控制。

综上所述,QElapsedTimer实现原理涉及底层硬件计时器、Qt计时框架和平台相关的代码实现,不同的实现方式可能也会使得其功能差异不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zw_ggr_2017

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值