介绍
QElapsedTimer是Qt框架中提供的一个类,主要用于测量代码执行时间和延迟时间。它可以在不同操作系统上提供准确的计时,并返回毫秒或纳秒级别的时间。
使用QElapsedTimer 可以轻松地测量一段程序的运行时间。例如,在两个函数之间测量时间,可以使用QElapsedTimer记录开始时间,然后再记录结束时间,最终计算两个时间值之差即可得到该函数的运行时间。
除了基本的计时功能外,QElapsedTimer还具有许多其他特性。例如,它可以在运行时检查操作系统的高分辨率定时器是否可用,以提供更准确的计时精度。另外,QElapsedTimer 还支持重置计时器(restart)功能,以允许测量间隔内发生的事件。
总之,QElapsedTimer 是Qt开发中非常常用的计时工具,能够帮助程序员快速、准确地测量代码的运行时间和延迟时间,从而优化代码性能。
接口函数
QElapsedTimer类提供了多个接口函数,以下是一些常用的接口函数及其作用:
- start():启动计时器,并返回当前时间值。
- restart():重新启动计时器,并返回从上一次启动以来的时间值。
- elapsed():返回从启动或重启计时器以来经过的毫秒数。
- nsecsElapsed():返回从启动或重启计时器以来经过的纳秒数。
- isValid():检查操作系统是否支持精准计时器,如果支持则返回true。
- invalidate():使计时器失效,即它不再返回正确的时间。
- 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
计时器组件时,有以下一些注意事项:
-
QElapsedTimer
记录的是自系统启动或上次重启以来经过的时间,而不是当前时间。因此,使用elapsed()
和nsecsElapsed()
方法来检查经过的时间时应格外小心。 -
调用
restart()
函数前必须先调用isValid()
函数来检查计时器是否有效,否则将可能导致程序崩溃。 -
在Linux操作系统上,由于精度问题可能存在较大的误差,建议使用
clock_gettime()
等高精度的计时器来代替QElapsedTimer
。 -
QElapsedTimer
通常用于计算较短的时间间隔,如果需要计算较长的时间间隔,可以考虑使用QDateTime
或QTime
组件。 -
在计算耗时操作时,应该避免在繁忙的UI线程中进行,否则会影响UI的响应。
-
如果需要暂停计时器,在实现中需注意记录已经经历的时间,同时根据具体信息选择合适的参数数据类型。
实现原理
QElapsedTimer
是Qt提供的计时器组件,它并不依赖于操作系统提供的计时器实现,而是通过使用CPU指令周期计数器来计算经过的时间。
在大多数计算机硬件上,CPU会有一个高精度的计时器,每个CPU时钟周期都会自动增加该计数器的值。在一定条件下,对比两个计数器的值就可以计算出时间差,从而得到经过的时间。
具体来说,QElapsedTimer
主要利用了以下两种方式获取计时器值:
-
使用
QBasicTimer
在后台定期更新计时器值。当调用start()
方法时,会创建一个QBasicTimer
定时器并在后台以给定的间隔更新计时器值。通过elapsed()
和nsecsElapsed()
函数可以获取并返回这个计时器值(单位为n秒),即所需要的经过的时间。 -
通过直接读取系统底层的计时器寄存器来获取计时器值。这种方式需要使用一些平台特定的汇编语言代码来访问硬件寄存器,因此不同平台之间实现所需的代码可能会有所不同。在此种情况下,通过调用
clock_gettime()
函数等进行精度控制。
综上所述,QElapsedTimer
实现原理涉及底层硬件计时器、Qt计时框架和平台相关的代码实现,不同的实现方式可能也会使得其功能差异不同。