当前位置: 首页 > news >正文

std::chrono类的简单使用实例及分析


author: hjjdebug
date: 2025年 05月 20日 星期二 14:36:17 CST
descrip: std::chrono类的简单使用实例及分析


文章目录

  • 1.实例代码:
  • 2. 代码分析:
    • 2.1 auto t1 = std::chrono::high_resolution_clock::now();
      • 2.1.1 什么是 system_clock
      • 2.1.2 什么是 chrono::time_point?
      • 2.1.3 什么是duration?
        • 2.1.3.1 duration 的一个实例
      • 2.1.4 这么多的内涵,到底怎样理解time_point呢?
      • 2.1.5 time_point t1 在gdb中的表示
    • 2.2 auto delta_t = t2 - t1;
    • 2.3 auto dur_obj = std::chrono::duration<double, std::milli>(delta_t);
      • 2.3.1 duration 对象能够知道数值代表的是毫秒,纳秒或者其它单位吗?

1.实例代码:

$ cat main.cpp
#include <iostream>
#include <unistd.h> //for sleep
#include <chrono>
using namespace std;int main() {//now()是类的静态函数, auto t1 = std::chrono::high_resolution_clock::now(); //t1 是time_point 对象, time_point 对象是什么?// 被测代码sleep(1);auto t2 = std::chrono::high_resolution_clock::now();  // 返回的是时间点对象auto delta_t = t2 - t1; //2个time_point 对象相减,肯定被重构了. 返回的是 duration 对象, duration 对象是什么?auto dur_obj = std::chrono::duration<double, std::milli>(delta_t); //构造函数,参数是duration对象,返回ms为单位的duration对象std::cout << "耗时:" << dur_obj.count() << "ms" <<endl; //访问其数值,通过count(), 我们构建的是ms为单位的对象,所以单位就是msdur_obj = std::chrono::duration<double, std::milli>(500); //另一个构造函数,给500就打印500,单位还是ms,由std::milli类型决定的.std::cout << "测试打印:" << dur_obj.count() << "ms" <<endl;return 0;
}

执行结果
$ ./temp
耗时:1000.14ms
测试打印:500ms

代码很短,可是内涵很丰富. 是c++模板类的入门之路.
下面几乎是逐句分析了.

2. 代码分析:

2.1 auto t1 = std::chrono::high_resolution_clock::now();

std: namespace
chrono: namespace
大命名空间下的小命名空间,此时的命名空间为std::chrono
using high_resolution_clock = system_clock;
using 与typedef 类似, 也与#define 有可比性. 就是说high_resolution_clock 这个类型
是 system_clock 类型的小名, 它们是一个类型. 由此引出 system_clock 类型

2.1.1 什么是 system_clock

    struct system_clock{ //定义了一堆类型别名, 告诉编译器说, 别慌, 有一堆类型记住它们的小名.typedef chrono::nanoseconds duration; //使用ns做durationtypedef duration::rep rep;typedef duration::period period;typedef chrono::time_point<system_clock, duration> time_point;//静态变量是属于类的变量, 是全局的.static constexpr bool is_steady = false;//静态函数是属于类的函数. 恰似普通的函数, 执行不使用this指针,有3个//成员函数 now() to_time_t(time_point &t), from_time_t(std::time_t t)static time_point now() noexcept;static std::time_tto_time_t(const time_point& __t) noexcept{return std::time_t(duration_cast<chrono::seconds>(__t.time_since_epoch()).count());}static time_pointfrom_time_t(std::time_t __t) noexcept{typedef chrono::time_point<system_clock, seconds> __from;return time_point_cast<system_clock::duration>(__from(chrono::seconds(__t)));}};

now 是system_clock 类的静态成员函数, 返回一个time_point 类型对象

2.1.2 什么是 chrono::time_point?

看一下它的声明,
template<class Clock, class Duration = typename Clock::duration> class time_point;
它是一个类模板. 有两个类型参数.
时钟类型决定了时间的来源, 有system_clock, steady_clock,high_resolution_clock(是system_clock的代名词)

system_clock, 前面已经有交代.
剧透一下 system_clock 的纪元为 1970-01-01 00:00:00 UTC), unix时间戳起点
system_clock是time_point类模板的第一个参数.

time_point类模板的第二个参数类型duration 是什么?

2.1.3 什么是duration?

duration 是一个类型,这里先给duration的一个实例.

2.1.3.1 duration 的一个实例
(gdb) ptype dur_obj
type = struct std::chrono::duration<double, std::ratio<1, 1000> > [with _Rep = double, _Period = std::ratio<1, 1000>] {private:_Rep __r;public:duration(void);duration(const std::chrono::duration<_Rep, _Period> &);~duration();std::chrono::duration<_Rep, _Period> & operator=(const std::chrono::duration<_Rep, _Period> &);_Rep count(void) const;std::chrono::duration<_Rep, _Period> operator+(void) const;std::chrono::duration<_Rep, _Period> operator-(void) const;std::chrono::duration<_Rep, _Period> & operator++(void);std::chrono::duration<_Rep, _Period> operator++(int);std::chrono::duration<_Rep, _Period> & operator--(void);std::chrono::duration<_Rep, _Period> operator--(int);std::chrono::duration<_Rep, _Period> & operator+=(const std::chrono::duration<_Rep, _Period> &);std::chrono::duration<_Rep, _Period> & operator-=(const std::chrono::duration<_Rep, _Period> &);std::chrono::duration<_Rep, _Period> & operator*=(const _Rep &);std::chrono::duration<_Rep, _Period> & operator/=(const _Rep &);static std::chrono::duration<_Rep, _Period> zero(void);static std::chrono::duration<_Rep, _Period> min(void);static std::chrono::duration<_Rep, _Period> max(void);void duration<int>(const int &);void duration<double>(const _Rep &);void duration<long, std::ratio<1, 1000000000> >(const std::chrono::duration<long, std::ratio<1, 1000000000> > &);typedef _Rep rep;
}

它有一个私有成员变量 _Rep __r, __Rep 是represent的简写, 是类模板的第一个类型参数.可能是double或long
类模板还有第2个类型参数, 此处是 std::ratio<1,1000> 类型, 这个类型起码有2个类属性可以使用
std::ratio<1,1000>::num=1
std::ratio<1,1000>::den=1000
至于其它构造,析构,重载运算符就不具体分析了.

2.1.4 这么多的内涵,到底怎样理解time_point呢?

时间点对象timepoint是时间点类模板用system_clock 和 nanoseconds 为类型参数实例化后的一个对象.它有一个duration类型的变量记录其属性
其值说明是从 1970-01-01 00:00:00 开始的 纳秒数, 用long int 表示的数

2.1.5 time_point t1 在gdb中的表示

time_point 包含一个duration 对象 __d, duration对象包含一个实现类型(long或double)变量 __r
(gdb) p t1
$1 = {
__d = {
__r = 1747640811095678930 //1970-01-01 00:00:00开始的时间, 单位仅从对象本身是看不出来的.
}
}
//从类模板类型参数上知道它是ns, 但模板类型参数仅仅是编译期属性, 编译期知道它是ns, 但运行期就不知道了.

(gdb) ptype t1 , 
type = struct std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1, 1000000000> > > [with _Clock = std::chrono::_V2::system_clock, _Dur = std::chrono::duration<long, std::ratio<1, 1000000000> >] {private:_Dur __d;  //私有成员变量, duration 类型public:time_point(void);time_point(const _Dur &);_Dur time_since_epoch(void) const;std::chrono::time_point<_Clock, _Dur> & operator+=(const _Dur &);std::chrono::time_point<_Clock, _Dur> & operator-=(const _Dur &);static std::chrono::time_point<_Clock, _Dur> min(void);static std::chrono::time_point<_Clock, _Dur> max(void);typedef _Dur duration;
}(gdb) p t2
$2 = {__d = {__r = 1747640813823889979 //unix 时间点到现在的时间间隔}
}

2.2 auto delta_t = t2 - t1;

//两个时间点之差是duration 变量
//2个time_point 对象相减,运算被重构了. 返回的是 duration 对象
(gdb) p delta_t //一种duration 对象
$3 = {
__r = 2728211049
}
(gdb) p dur_obj //另一种duration 对象
$4 = {
__r = 2728.211049
}

2.3 auto dur_obj = std::chrono::duration<double, std::milli>(delta_t);

代码分析:
std::chrono namespace
duration<double, std::milli>: 是一个实例化模板类
std::chrono::duration<double,std::milli>(delta_t);
类名称后面跟上一个参数(这里是duration为参数)就是构建对象的过程(copy构造)
auto dur_obj = std::chrono::duration<double, std::milli>(delta_t); (赋值构造)
把一个无名对象赋值给一个有名对象 dur_obj

duration 对象是什么?数值代表了什么意思?
请参考2.1.4 说明duration 对象是什么类型

2.3.1 duration 对象能够知道数值代表的是毫秒,纳秒或者其它单位吗?

答: 对于一个duration 对象
$4 = {
__r = 2728.211049
}
duration 本身并不知道数值代表的是ms,ns或其它单位.
但是duration类却能够根据构造函数传来的类型及模板参使用的类型对传来的数值进行转换.
这是静态编译的能力.
现在已经计算出了这个值并付给了对象的成员. 但这个对象已经不知道自己是什么单位了,
因为对象本身没有保留单位信息. 即单位信息做为模板类型参数不是运行期特性只是编译期特性.

那我们怎么知道数值的单位是什么呢?
这是你自己的问题, 你自己根据数值的转变过程确定它应该是什么单位.

相关文章:

  • JavaScript性能优化实战(13):性能测试与持续优化
  • 后期:daplink
  • 可编辑PPT | 华为安全架构设计方法指南华为数字化转型架构解决方案
  • npm vs npx 终极指南:从原理到实战的深度对比 全面解析包管理器与包执行器的核心差异,助你精准选择工具
  • 完善网络安全等级保护,企业需注意:
  • kotlin 将一个list按条件分为两个list(partition )
  • centos 9 Kickstart + Ansible自动化部署 —— 筑梦之路
  • 阅读笔记---城市计算中用于预测学习的时空图神经网络研究综述
  • JVM的面试相关问题
  • List优雅分组
  • Python打卡DAY31
  • STM32+ESP8266+ONENET+微信小程序上传数据下发指令避坑指南
  • .NET 10 - 尝试一下Minimal Api的Validation新特性
  • LangChain4j入门(六)整合提示词(Prompt)
  • RK3588 ArmNN CPU/GPU ResNet50 FP32/FP16/INT8 推理测试
  • .NET外挂系列:3. 了解 harmony 中灵活的纯手工注入方式
  • 如何自学FPGA设计?
  • 2.4.2死锁的处理策略-预防死锁
  • DB31/T 1552-2025《居民电子健康档案应用系统等级评估指南》:上海地方标准全面解析
  • notepad++
  • 中国社科院国际合作局副局长廖凡调任世界经济与政治研究所所长
  • 35款移动应用存在违法违规收集使用个人信息情况,涉及智谱清言、Kimi等
  • 德国放弃长期以来的反核立场,寻求修复德法合作关系
  • 上海地铁:一孩童鞋子卡于电梯梯级处,其间未造成人员受伤
  • 工程院院士、武汉纺织大学校长徐卫林拟任湖北省属本科高校党委书记
  • 花290多万维修保质期仅一年多?媒体四问凤阳鼓楼“瓦片脱落”