美文网首页
C++中常用的跨平台计时方案总结

C++中常用的跨平台计时方案总结

作者: BarretX | 来源:发表于2021-04-05 14:02 被阅读0次

计时是发掘系统中时间性能瓶颈的必不可少的一环。

由于C++语言存在各种不同的实现版本,可选用的计时方案也比较多,本文介绍了各种常用的跨平台计时方案,包括:

  • C计时方案clock
  • C计时方案time
  • STL计时方案std::chrono::clocks
  • QT计时方案QTime
  • Boost计时方案timer

而对于平台依赖的方案,不在本文的介绍范围之内,比如:Windows平台下的GetTickCountQueryPerformanceCounter,*inux平台下的hrtimergettimeofday
本文以task()函数为例来说明各计时方案用法,在之后的代码中,就不再定义了:

void task()
{
    static int value = 0;
    while(0 <= value++);
}

C计时方案clock

clock是C标准库中的函数,在time.h中声明,函数签名如下:

#include <time.h>

clock_t clock(void);

值得说明一下的是,clock返回的是处理器调用某个进程或函数所花费的时间,而不是系统时钟时间,也就是说,如果调用过程有sleep,不会计算在内。
此外,函数返回结果clock_t类型值需要除以CLOCKS_PER_SEC才能得到秒数值。而且对于不同平台,CLOCKS_PER_SEC的值也是不一样的,笔者知道的取值有10001000000
下面代码说明用法:

#include <iostream>
#include <ctime>

void task();

int main()
{
    std::clock_t start = std::clock();
    task();
    std::clock_t end = std::clock();

    double duration = (end - start)/(double)CLOCKS_PER_SEC;
    std::cout << duration << std::endl;
}

C计时方案time

timeclock一样,也是在time.h中声明的C标准库函数,函数签名如下:

#include <time.h>

time_t time (time_t *__timer);

clock不同的是,time传入一个time_t*,然后返回系统时钟时间,而不是CPU时间。
其基本用法如下:

#include <iostream>
#include <ctime>

void task();

int main()
{
    std::time_t start, end;
    
    std::time(&start);
    task();
    std::time(&end);

    double duration = std::difftime(end, start);
    std::cout << duration << std::endl;
}

STL计时方案std::chrono::clocks

C++ 11提供了高精度时间的标准库chrono,其中抽象了三个概念:

  • 时间点:std::chrono::steady_clock::time_point
  • 时钟:std::chrono::clocks
  • 时间间隔:std::chrono::duration

std::chrono::clocks用来计时,实现的时钟有三个:

  • system_clock:系统时钟,与系统显示时间保持一致,可人为修改。
  • steady_clock:稳定时钟,不随系统时间变化,不可修改。
  • high_resolution_clock:高精度时间,目前存在移植性问题,暂不推荐使用。

由此可见,采用steady_clock最合适。
下面来看基本用法:

#include <iostream>
#include <chrono>

void task();

int main()
{
    std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
    task();
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

    std::chrono::milliseconds duration = 
            std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    std::cout << duration.count() / 1000.0 << std::endl;
}

其中(end - start)需要利用duration_cast转换成需要的统计单位。

QT计时方案QTime

QT计时方案主要采用QTime这个类,用到函数:

  • QTime::start()方法用于启动计时器
  • QTime::restart()方法用于重启计时器
  • QTime::elapsed()方法返回计时器从启动(startrestart)到当前的毫秒数。

用法简单举例如下:

#include <QTime>
#include <iostream>

void task();

int main()
{
    QTime time;

    time.start();
    task();
    int duration = time.elapsed();

    std::cout << duration / 1000.0 << std::endl;
}

Boost计时方案timer

Boost是业界比较流行的C++库,其中用到的计时类boost::timer与QT非常相似:

  • 对象构造完成时,定时器启动
  • boost::timer::restart()重新启动定时器
  • boost::timer::elapsed()返回启动的时间,单位为秒

下面说明用法:

#include <boost/timer.hpp>
#include <iostream>

void task();

int main()
{
    boost::timer t;
    task();
    double duration = t.elapsed();

    std::cout << duration << std::endl;
}

总结

本文介绍了常用的跨平台计时方案,从功能角度考虑,clock返回CPU运行时间,而其余均返回时钟时间;从精度角度来看,std::chrono::clocks精度最高,达到纳秒级别;从接口的角度,QTimeboost::timer提供了专门的timer类,接口更加优雅,其余方案仅仅是对时钟的一种使用。
综合考虑,笔者会推荐std::chrono::clocks

名称 功能 精度 接口设计 通用性
clock CPU时间 毫秒/微秒 一般
time 时钟时间 毫秒/微秒 一般 一般
std::chrono::clocks 时钟时间 纳秒 一般
QTime 时钟时间 毫秒 一般
boost::timer 时钟时间 毫秒/微秒 一般

说在最后

计时 一般指代码块从开始到结束,系统运行的时间,也可能指CPU时间片的时间,是一个不太精确的数值。如果需要精确考虑某个线程运行时间或某个过程的系统时间和用户时间,则需要进一步考虑其他解决方案。

相关文章

  • C++中常用的跨平台计时方案总结

    计时是发掘系统中时间性能瓶颈的必不可少的一环。 由于C++语言存在各种不同的实现版本,可选用的计时方案也比较多,本...

  • Websocket 库和 JSON RPC 库选型

    WebSocket 库选型 C/C++ 跨平台 WebSocket 库备选方案: uWebSockets GitH...

  • 跨平台方案总结

    介绍 最近出现的 React Native 再次让跨平台移动端开发这个话题火起来了,曾经大家以为在手机上可以像桌面...

  • 【matlab】matlab传参调用shell

    穿插在python, R, matlab, C++, shell 的后果就是各种跨平台调用。。。之前总结过pyth...

  • Live555 框架简述,以及相关类图和协作图

    简述 是一个为流媒体提供解决方案的跨平台的C++开源项目,它实现了标准流媒体传输,是一个为流媒体提供解决方案的跨平...

  • linux, windows, mac, ios等平台GCC预编

    写跨平台c/c++程序的时候,需要搞清各平台下面的预编译宏,区分各平台代码。而跨平台c/c++编程,GCC基本在各...

  • 1.VS建立QT动态库

    1.VS建立QT动态库1)右键点击解决方案>>添加>>新建项目 2)Visual C++>>跨平台>>Qt>>Qt...

  • 网络协议(一)

    以下内容来自于小码哥"网络协议从入门到底层原理" C\C++跨平台的原理: C\C++跨平台: 使用平台相关的编译...

  • C++与Rust引用外部符号的比较

    文档列表见:Rust 移动端跨平台复杂图形渲染项目开发总结 - 目录 通常,C/C++通过#include导入外部...

  • Mediapipe介绍

    Mediapipe是google的一个开源项目,支持跨平台的常用ML方案。项目主页戳这里[https://medi...

网友评论

      本文标题:C++中常用的跨平台计时方案总结

      本文链接:https://www.haomeiwen.com/subject/ayzrkltx.html