Qt测算程序运行时间
【问题描述】程序运行时间是编程的一项重要指标,在QT中如何测算程序的运行时间呢?
【解析】
测试函数
- #include <math.h>
- void function()
- {
- unsigned int i,j;
- double y;
- for(i=0;i<1000;i++)
- for(j=0;j<1000;j++)
- y=sin((double)i);
- }
#include <math.h>
void function()
{
unsigned int i,j;
double y;
for(i=0;i<1000;i++)
for(j=0;j<1000;j++)
y=sin((double)i);
}
方法1 利用QTime,其精度为ms级
- #include <QDebug>
- #include <QTime>
- QTime time;
- time.start();
- function();
- qDebug()<<time.elapsed()/1000.0<<"s";
#include <QDebug>
#include <QTime>
QTime time;
time.start();
function();
qDebug()<<time.elapsed()/1000.0<<"s";
运行结果:0.109 s
方法2 利用gettimeofday(),其精度为us级
- #include <QDebug>
- #include <sys/time.h>
- struct timeval tpstart,tpend;
- float timeuse;
- gettimeofday(&tpstart,NULL);
- function();
- gettimeofday(&tpend,NULL);
- timeuse=(1000000*(tpend.tv_sec-tpstart.tv_sec) + tpend.tv_usec-tpstart.tv_usec)/1000000.0;
- qDebug()<<timeuse<<"s";
#include <QDebug>
#include <sys/time.h>
struct timeval tpstart,tpend;
float timeuse;
gettimeofday(&tpstart,NULL);
function();
gettimeofday(&tpend,NULL);
timeuse=(1000000*(tpend.tv_sec-tpstart.tv_sec) + tpend.tv_usec-tpstart.tv_usec)/1000000.0;
qDebug()<<timeuse<<"s";
运行结果:0.109375 s
方法3 利用clock(),其精度为ms级
- #include <QDebug>
- #include <sys/time.h>
- double time_Start = (double)clock();
- function();
- double time_End = (double)clock();
- qDebug()<<(time_End - time_Start)/1000.0<<"s";
#include <QDebug>
#include <sys/time.h>
double time_Start = (double)clock();
function();
double time_End = (double)clock();
qDebug()<<(time_End - time_Start)/1000.0<<"s";
运行结果:0.11 s
方法4 利用windows.h(VC)函数,提精度为us级
QueryPerformanceFrequency() - 基本介绍
类型:Win32API
原型:BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
作用:返回硬件支持的高精度计数器的频率。
返回值:非零,硬件支持高精度计数器;零,硬件不支持,读取失败。
供WIN9X使用的高精度定时器:QueryPerformanceFrequency()和QueryPerformanceCounter(),要求计算机从硬件上支持高精度定时器。
函数的原形是:
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
BOOL QueryPerformanceCounter (LARGE_INTEGER *lpCount);
数据类型LARGEINTEGER既可以是一个作为8字节长的整数,也可以是作为两个4字节长的整数的联合结构,其具体用法根据编译器是否支持64位而定。该类型的定义如下:
typeef union _ LARGE_INTEGER
{
struct
{
DWORD LowPart;
LONG HighPart;
};
LONGLONG QuadPart;
} LARGE_INTEGER;
在定时前应该先调用QueryPerformanceFrequency()函数获得机器内部计时器的时钟频率。接着在需要严格计时的事件发生前和发生之后分别调用QueryPerformanceCounter(),利用两次获得的计数之差和时钟频率,就可以计算出事件经历的精确时间。测试函数SLEEP(100)的精确持续时间方法:
LARGE_INTEGER litmp;
LONGLONG qt1,qt2;
double dft,dff,dfm;
QueryPerformanceFrequency(&litmp);//获得时钟频率
dff=(double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);//获得初始值
qt1=litmp.QuadPart;Sleep(100);
QueryPerformanceCounter(&litmp);//获得终止值
qt2=litmp.QuadPart;
dfm=(double)(qt2-qt1);
dft=dfm/dff;//获得对应的时间值
需要注意的是DFT计算的结果单位是秒。
QueryPerformanceFrequency高精度计时
利用这两个函数可以创建跟硬件时钟的晶振一样精确的计时器。
在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率,
1.如下函数查询cpu时钟频率,(如我的cpu是2.89GHz,得到2893460000)
BOOL QueryPerformanceFrequency( LARGE_INTEGER *lpFrequency // current frequency);
2.再获取高精确度性能计数器的值
BOOL QueryPerformanceCounter( LARGE_INTEGER *lpPerformanceCount // counter value);
计数器的值除以频率得到当前系统运行时间(秒):
LARGE_INTEGER startTime = (*lpPerformanceCount) /(*lpFrequency )
3.运行所需计时的代码段后再次获取性能计数器的值
BOOL QueryPerformanceCounter( LARGE_INTEGER *lpPerformanceCount2 // counter value);
计数器的值除以频率得到当前系统运行时间(秒):
LARGE_INTEGER endTime =(*lpPerformanceCount2) /(*lpFrequency )
4.endTime-startTime即为两次调用QueryPerformanceCounter期间的精度计时时间。
这结果是秒级的,如果要更精确的可以将时钟频率除以相应值再作后面计算。
如要获得毫秒级的:LARGE_INTEGER tick=*lpFrequency/1000
LARGE_INTEGER startTime = (*lpPerformanceCount) /tick
LARGE_INTEGER endTime =(*lpPerformanceCount2) /tick
endTime-startTime
- #include <QDebug>
- #include <windows.h>
- LARGE_INTEGER litmp;
- LONGLONG Qpart1,Qpart2,Useingtime;
- double dfMinus,dfFreq,dfTime;
- //获得CPU计时器的时钟频率
- QueryPerformanceFrequency(&litmp);//取得高精度运行计数器的频率f,单位是每秒多少次(n/s),
- dfFreq = (double)litmp.QuadPart;
- QueryPerformanceCounter(&litmp);//取得高精度运行计数器的数值
- Qpart1 = litmp.QuadPart; //开始计时
- function(); //待测试的计算函数等
- QueryPerformanceCounter(&litmp);//取得高精度运行计数器的数值
- Qpart2 = litmp.QuadPart; //终止计时
- dfMinus = (double)(Qpart2 - Qpart1);//计算计数器值
- dfTime = dfMinus / dfFreq;//获得对应时间,单位为秒,可以乘1000000精确到微秒级(us)
- Useingtime = dfTime*1000000;
- qDebug()<<dfTime<<"s";
#include <QDebug>
#include <windows.h>
LARGE_INTEGER litmp;
LONGLONG Qpart1,Qpart2,Useingtime;
double dfMinus,dfFreq,dfTime;
//获得CPU计时器的时钟频率
QueryPerformanceFrequency(&litmp);//取得高精度运行计数器的频率f,单位是每秒多少次(n/s),
dfFreq = (double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);//取得高精度运行计数器的数值
Qpart1 = litmp.QuadPart; //开始计时
function(); //待测试的计算函数等
QueryPerformanceCounter(&litmp);//取得高精度运行计数器的数值
Qpart2 = litmp.QuadPart; //终止计时
dfMinus = (double)(Qpart2 - Qpart1);//计算计数器值
dfTime = dfMinus / dfFreq;//获得对应时间,单位为秒,可以乘1000000精确到微秒级(us)
Useingtime = dfTime*1000000;
qDebug()<<dfTime<<"s";
运行结果:0.107415 s
【代码清单】
- #include <QDebug>
- #include <QTime>
- #include <sys/time.h>
- #include <windows.h>
- #include <math.h>
- void function();
- int main(void)
- {
- qDebug()<<"-------------------------------";
- //-1-
- QTime time;
- time.start();
- function();
- qDebug()<<time.elapsed()/1000.0<<"s";
- //-2-
- struct timeval tpstart,tpend;
- float timeuse;
- gettimeofday(&tpstart,NULL);
- function();
- gettimeofday(&tpend,NULL);
- timeuse=(1000000*(tpend.tv_sec-tpstart.tv_sec) + tpend.tv_usec-tpstart.tv_usec)/1000000.0;
- qDebug()<<timeuse<<"s";
- //-3-
- double time_Start = (double)clock();
- function();
- double time_End = (double)clock();
- qDebug()<<(time_End - time_Start)/1000.0<<"s";
- //-4-
- LARGE_INTEGER litmp;
- LONGLONG Qpart1,Qpart2,Useingtime;
- double dfMinus,dfFreq,dfTime;
- //获得CPU计时器的时钟频率
- QueryPerformanceFrequency(&litmp);//取得高精度运行计数器的频率f,单位是每秒多少次(n/s),
- dfFreq = (double)litmp.QuadPart;
- QueryPerformanceCounter(&litmp);//取得高精度运行计数器的数值
- Qpart1 = litmp.QuadPart; //开始计时
- function(); //待测试的计算函数等
- QueryPerformanceCounter(&litmp);//取得高精度运行计数器的数值
- Qpart2 = litmp.QuadPart; //终止计时
- dfMinus = (double)(Qpart2 - Qpart1);//计算计数器值
- dfTime = dfMinus / dfFreq;//获得对应时间,单位为秒,可以乘1000000精确到微秒级(us)
- Useingtime = dfTime*1000000;
- qDebug()<<dfTime<<"s";
- return 0;
- }
- void function()
- {
- unsigned int i,j;
- double y;
- for(i=0;i<1000;i++)
- for(j=0;j<1000;j++)
- y=sin((double)i);
- }