计算程序执行时间

本文介绍了多种在C++中计算程序执行时间的方法,包括使用OpenCV的cv.getTickCount()、Windows API的GetTickCount()、C++标准库的clock()函数以及CTime和GetLocalTime类。此外,还详细解释了如何通过这些方法计算秒、毫秒和FPS等性能指标,以评估算法的运行效率。并提供了一段示例代码,对比了两种不同的矩阵遍历操作在512*512图像上的执行时间。

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

计算程序执行耗时

  • 返回CPU执行的时间周期数,
cv.getTickCount,
  • 每秒CPU时间周期总数
cv.getTickFrequency

计算一段算法处理执行的时间秒数,代码结构如下:

e1 = cv.getTickCount()// your code executione2 = cv.getTickCount()time = (e2 - e1)/ cv.getTickFrequency()

time是以秒为单位。

计算秒/毫秒/FPS

在算法执行阶段,有三个经常使用的速度性能计量指标分别是秒、毫秒、FPS(每秒多少帧),根据上面的cv.getTickCount与cv.getTickFrequency两个函数,这三个指标的计算代码如下:

e1 = cv.getTickCount()
// your code execution
e2 = cv.getTickCount()

// 计算秒
time = (e2 - e1)/ cv.getTickFrequency()

// 计算毫秒
time2 =( (e2 - e1)/ cv.getTickFrequency() )*1000

// 计算FPS(每秒多少帧)
fps =( cv.getTickFrequency() / (e2 - e1) )



通过网上查阅资料,找到以下几种VC中求取程序运行时间的方法:
方法一 利用GetTickCount函数(ms)

//代码:
CString str;         
#include "windows.h"
double t1 = GetTickCount();//程序段开始前取得系统运行时间(ms)            
。。。。。。//to do sth
。。。。。。//to do sth
。。。。。。//to do sth
double t2 = GetTickCount();//程序段结束后取得系统运行时间(ms)         
double t = t2-t1;//程序运行时间(ms)   
str.Format("time:%f ms",t);//程序运行时间         

AfxMessageBox(str); 

另外一种:(这个比上面的稍微准确一点)

double ta = getTickCount();
。。。。。。//to do sth
。。。。。。//to do sth
。。。。。。//to do sth
Sleep(1000);
double tb = getTickCount();
cout << "tb-ta = " << 1000*(tb-ta)/getTickFrequency() << "ms" << endl;
 


 
方法二 利用C/C++计时函数(s)

//代码:
#include "time.h"

clock_t  start, finish;
start = clock(); 
。。。。。。//to do sth
。。。。。。//to do sth
。。。。。。//to do sth
finish = clock();
printf("%f seconds\n",(double)(finish-start)/CLOCKS_PER_SEC);


//VC/MFC中计算程序运行时间
方法三  利用CTime类 获取系统时间

//代码:
CString str;

//获取系统时间
CTime tm;
tm=CTime::GetCurrentTime();
str=tm.Format("现在时间是%Y年%m月%d日  %X");
AfxMessageBox(str);

方法四  利用GetLocalTime类 获取系统时间

SYSTEMTIME st;

CString strDate,strTime;

GetLocalTime(&st);

strDate.Format("M----",st.wYear,st.wMonth,st.wDay);

strTime.Format("-:-:-",st.wHour,st.wMinute,st.wSecond);

AfxMessageBox(strDate);

AfxMessageBox(strTime);


方法五 

//算法运行时间
int main()
{
    Mat img;
    int i, j;
    double t,t1;
    uchar* data;
    int imgSize;

    img = imread("lena_gray.jpg", 0);

    t = (double)cvGetTickCount();//
    for (j = 0; j < img.rows; j++)
    {
        for (i = 0; i < img.cols; i++)
        {
            img.at<uchar>(j, i) = 255;
        }
    }
    t1 = cvGetTickCount();
    t = (t1-t)/(cvGetTickFrequency()*1000);//
    cout << "at operation cost : " << t << "ms" << endl;//

    data = img.ptr<uchar>(0);
    imgSize = img.rows*img.cols*img.channels();
    t = cvGetTickCount();
    for (j = 0; j < imgSize; j++)
    {
        data[j] = 255;
    }
    t1 = (double)cvGetTickCount();
    t = (t1-t)/(cvGetTickFrequency()*1000);
    cout << "ptr operation cost : " << t << "ms" << endl;

    return 0;
}


经过计算,对512*512的图像进行编历,
at操作耗时为0.424076ms
ptr操作耗时为0.0346413ms

double duration;
duration = static_cast<double>(cv::getTickCount());
。。。。。。//to do sth
。。。。。。//to do sth
。。。。。。//to do sth
duration = static_cast<double>(cv::getTickCount())-duration;
duration /= cv::getTickFrequency(); // the elapsed time in ms

在C语言中统计算法运行时间有多种方法,不同方法的精度、适用场景和系统依赖性各异。以下是四种主流实现方式及其详细说明:


⏱️ 1. ​​使用 clock()函数(标准库方法)​

​原理​​:测量CPU实际执行代码的时间(处理器时间),不包括I/O等待或睡眠时间。

​精度​​:毫秒级(依赖系统时钟频率)。

​适用场景​​:单线程CPU密集型算法。

​示例代码​​:

#include <stdio.h>
#include <time.h>

int main() {
    clock_t start = clock();
    
    // 待测算法
    for (int i = 0; i < 1000000; i++); // 示例循环
    
    clock_t end = clock();
    double time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
    printf("CPU 时间: %.6f 秒\n", time_used);
    return 0;
}

注意​​:多线程环境下可能不准确,因线程切换导致CPU时间统计偏差。


⏱️ 2. ​​使用 time()函数(低精度墙上时间)​

​原理​​:返回自1970年1月1日(Unix纪元)起的秒数,测量实际流逝时间(墙上时间)。

​精度​​:秒级。

​适用场景​​:长时间运行(>1秒)的算法,如批处理任务。

​示例代码​​:

#include <stdio.h>
#include <time.h>

int main() {
    time_t start = time(NULL);
    
    // 待测算法
    sleep(2); // 模拟耗时操作
    
    time_t end = time(NULL);
    double elapsed = difftime(end, start);
    printf("墙上时间: %.2f 秒\n", elapsed);
    return 0;
}

缺点​​:无法测量短于1秒的操作。


⏱️ 3. ​​使用 gettimeofday()(微秒级精度)​

​原理​​:获取系统当前时间(墙上时间),精确到微秒。

​精度​​:微秒级(10⁻⁶秒)。

​适用场景​​:需高精度但非跨平台的场景(如Linux/macOS)。

​示例代码​​:

#include <stdio.h>
#include <sys/time.h>

int main() {
    struct timeval start, end;
    gettimeofday(&start, NULL);
    
    // 待测算法
    for (int i = 0; i < 1000000; i++);
    
    gettimeofday(&end, NULL);
    long seconds = end.tv_sec - start.tv_sec;
    long micros = end.tv_usec - start.tv_usec;
    double elapsed = seconds + micros / 1e6;
    printf("时间: %.6f 秒\n", elapsed);
    return 0;
}

注意​​:系统时间调整(如NTP同步)可能导致结果异常。


⏱️ 4. ​​高精度计时器(纳秒级)​

​Windows:QueryPerformanceCounter
#include <stdio.h>
#include <windows.h>

int main() {
    LARGE_INTEGER freq, start, end;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&start);
    
    // 待测算法
    for (int i = 0; i < 1000000; i++);
    
    QueryPerformanceCounter(&end);
    double elapsed = (end.QuadPart - start.QuadPart) / (double)freq.QuadPart;
    printf("时间: %.9f 秒\n", elapsed);
    return 0;
}
Linux:clock_gettime()
#include <stdio.h>
#include <time.h>

int main() {
    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    
    // 待测算法
    for (int i = 0; i < 1000000; i++);
    
    clock_gettime(CLOCK_MONOTONIC, &end);
    double elapsed = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
    printf("时间: %.9f 秒\n", elapsed);
    return 0;
}

特点​​:

  • ​精度​​:纳秒级(10⁻⁹秒)。

  • ​时钟源​​:CLOCK_MONOTONIC避免系统时间跳变影响。


📊 ​​方法对比与选择建议​

​方法​

​精度​

​测量时间类型​

​系统依赖​

​适用场景​

clock()

毫秒级

CPU时间

跨平台

单线程CPU密集型任务

time()/difftime()

秒级

墙上时间

跨平台

长时间任务(>1秒)

gettimeofday()

微秒级

墙上时间

POSIX系统(Linux/macOS)

需高精度但非跨平台

QueryPerformanceCounter/clock_gettime()

纳秒级

墙上时间

系统特定API

极致精度要求


⚠️ ​​实际应用注意事项​

  1. 1.

    ​多次测量取平均值​​:减少系统调度和外部干扰的影响,尤其短时任务。

  2. 2.

    ​避免I/O操作​​:测量期间尽量减少文件读写、打印等操作,避免额外耗时干扰。

  3. 3.

    ​编译器优化​​:使用 volatile防止循环被优化掉,例如:

volatile int sum = 0;
for (int i = 0; i < 1000000; i++) sum += i;
  1. 4.

    ​多线程环境​​:优先使用墙上时间(如clock_gettime()),因CPU时间可能漏计其他线程占用。


💎 ​​总结​

  • ​基础需求​​:用 clock()或 time()即可满足多数场景。

  • ​高精度需求​​:

    • Windows优先选 QueryPerformanceCounter

    • Linux/macOS选 clock_gettime(CLOCK_MONOTONIC)

  • ​关键原则​​:根据算法类型(CPU密集型 vs I/O密集型)和精度要求选择合适方法,并通过多次测量提升准确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值