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类却能够根据构造函数传来的类型及模板参使用的类型对传来的数值进行转换.
这是静态编译的能力.
现在已经计算出了这个值并付给了对象的成员. 但这个对象已经不知道自己是什么单位了,
因为对象本身没有保留单位信息. 即单位信息做为模板类型参数不是运行期特性只是编译期特性.

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/906416.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电子电路仿真实验教学平台重磅上线!——深圳航天科技创新研究院倾力打造,助力高校教学数字化转型

在传统电子电路课堂中&#xff0c;实验室的灯光总与高昂的成本、拥挤的设备、反复的耗材损耗相伴&#xff0c;而教师不得不面对这样的现实&#xff1a;有限的硬件资源束缚着教学深度&#xff0c;不可逆的实验风险制约着创新探索&#xff0c;固化的时空场景阻碍着个性化学习。当…

面试真题 - 高并发场景下Nginx如何优化

Nginx是一款高性能的Web服务器和反向代理服务器&#xff0c;以其轻量级、高并发处理能力和稳定性闻名。在面对高并发场景时&#xff0c;合理的配置与优化策略至关重要&#xff0c;以确保服务的稳定性和响应速度。 以下是针对Nginx进行高并发优化的一些关键配置和策略&#xff…

算法与数据结构:质数、互质判定和裴蜀定理

文章目录 质数质数判定质数筛选质因数分解互质判定裴蜀定理 质数 首先回顾「质数」的定义&#xff1a;若一个正整数无法被除了 1 ​和它自身之外的任何自然数整除&#xff0c;则称该数为质数&#xff08;或素数&#xff09;&#xff0c;否则称该正整数为合数。 根据上述定义&…

代码随想录算法训练营第60期第四十二天打卡

大家好&#xff0c;今天还是继续我们的动态规划里面的背包问题&#xff0c;前面我们主要接触的是0-1背包和完全背包&#xff0c;其实这两个背包问题主要就是看看每一件物品我们是否有多件&#xff0c;如果每一件物品我们只能取一次的话那这样我们就是0-1背包&#xff0c;如果每…

第41天-Python+Qt四屏播放器开发指南

一、技术选型与工具准备 核心库: Pyqt5:Python标准GUI库,构建用户界面 os / sys:文件系统操作 开发环境: pip install pyqt5 最终效果与运行 import sys from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout # 添加缺失的布局管理器 from PyQt5.QtCore impor…

upload-labs通关笔记-第12关 文件上传之白名单GET法

目录 一、白名单过滤 二、%00截断 1、%00截断原理 2、空字符 3、截断条件 &#xff08;1&#xff09;PHP版本 < 5.3.4 &#xff08;2&#xff09;magic_quotes_gpc配置为Off &#xff08;3&#xff09;代码逻辑存在缺陷 三、源码分析 1、代码审计 &#xff08;1&…

Node.js数据抓取技术实战示例

Node.js常用的库有哪些呢&#xff1f;比如axios或者node-fetch用来发送HTTP请求&#xff0c;cheerio用来解析HTML&#xff0c;如果是动态网页的话可能需要puppeteer这样的无头浏览器。这些工具的组合应该能满足大部分需求。 然后&#xff0c;可能遇到的难点在哪里&#xff1f;…

数据结构(3)线性表-链表-单链表

我们学习过顺序表时&#xff0c;一旦对头部或中间的数据进行处理&#xff0c;由于物理结构的连续性&#xff0c;为了不覆盖&#xff0c;都得移&#xff0c;就导致时间复杂度为O&#xff08;n&#xff09;&#xff0c;还有一个潜在的问题就是扩容&#xff0c;假如我们扩容前是10…

【Unity】DOTween的常用函数解释

DOTween插件常用函数解释 1.DOTween.To&#xff08;通用变化动画&#xff09; 解释&#xff1a;将某一个值在一定的时间内变化到另一个值&#xff08;通用的函数&#xff09;&#xff0c;可用于大部分的动画变化 使用示例&#xff1a; using UnityEngine; using DG.Tweenin…

数据结构测试模拟题(1)

1、约瑟夫问题 #include<bits/stdc.h> using namespace std; const int N25; int e[N],ne[N],head-1,idx1; int n,m; void add_to_head(int x){e[idx]x;ne[idx]head;headidx; } void add(int k,int x){e[idx]x;ne[idx]ne[k];ne[k]idx; } int main(){cin>>n>>…

Helm配置之为特定Deployment配置特定Docker仓库(覆盖全局配置)

文章目录 Helm配置之为特定Deployment配置特定Docker仓库(覆盖全局配置)需求方法1:使用Helm覆盖值方法2: 在Lens中临时修改Deployment配置步骤 1: 创建 Docker Registry Secret步骤 2: 在 Deployment 中引用 Secret参考资料Helm配置之为特定Deployment配置特定Docker仓库(覆…

BERT 作为Transformer的Encoder 为什么采用可学习的位置编码

摘要 BERT 在位置编码上与原始 Transformer 论文中的 sin/cos 公式不同&#xff0c;选择了可学习&#xff08;learned&#xff09;的位置嵌入方案。本文将从 Transformer 原始位置编码选项入手&#xff0c;分析 BERT 选择 learned positional embeddings 的四大核心原因&#x…

【Linux 学习计划】-- gcc、g++、动静态库链接

目录 什么是gcc、g gcc、g 相关操作详解 预处理、编译、汇编、链接来源 动静态链接是什么 结语 什么是gcc、g gcc、g其实就是编译器&#xff0c;是帮助我们从.c或者.cc&#xff0c;.cpp文件编译成可执行程序的 其中&#xff0c;我们如果要编译c语言文件的话&#xff0c;…

前端读取本地项目中 public/a.xlsx 文件中的数据 vue3

前端读取本地项目中 public/a.xlsx 文件中的数据 vue3 项目中需要在 Vue3 项目中读取 public/a.xlsx 文件&#xff0c;可以使用 fetch API 来获取文件内容 一、安装 xlsx 首先&#xff0c;你需要安装 xlsx 库&#xff1a; npm install xlsx二、在需要用的页面里引入xlsx im…

MySQL:to many connections连接数过多

当你遇到 MySQL: Too many connections 错误时&#xff0c;意味着当前连接数已达到 MySQL 配置的最大限制。这通常是由于并发连接过多或连接未正确关闭导致的。 一、查看当前连接数 查看 MySQL 当前允许的最大连接数 SHOW VARIABLES LIKE max_connections;查看当前使用的最大…

2024年热门AI趋势及回顾

人工智能的崛起 2024 年可能会被铭记为人工智能不再是一种技术新奇事物&#xff0c;而是成为现实的一年。微软、Salesforce 和 Intuit 等巨头将人工智能融入主流企业解决方案&#xff1b;从文案写作到数据分析&#xff0c;专门的人工智能应用程序和服务如雨后春笋般涌现&#…

LangFlow技术深度解析:可视化编排LangChain应用的新范式 -(2)流编辑器系统

Flow Editor System | langflow-ai/langflow | DeepWiki 流编辑器系统 相关源文件 流编辑器系统是 Langflow 的核心交互式组件&#xff0c;允许用户直观地创建、编辑和管理 LLM 驱动的应用程序。它提供了一个直观的画布&#xff0c;用户可以在其中添加节点、将其与边缘连接并…

驱动-定时-秒-字符设备

文章目录 目的相关资料参考实验驱动程序-timer_dev.c编译文件-Makefile测试程序-timer.c分析 加载驱动-运行测试程序总结 目的 通过定时器timer_list、字符设备、规避竞争关系-原子操作&#xff0c;综合运用 实现一个程序&#xff0c;加深之前知识的理解。 实现字符设备驱动框…

[Java实战]Spring Boot整合Kafka:高吞吐量消息系统实战(二十七)

[Java实战]Spring Boot整合Kafka&#xff1a;高吞吐量消息系统实战&#xff08;二十七&#xff09; 一、引言 Apache Kafka作为一款高吞吐量、低延迟的分布式消息队列系统&#xff0c;广泛应用于实时数据处理、日志收集和事件驱动架构。结合Spring Boot的自动化配置能力&…

Kotlin Multiplatform--04:经验总结(持续更新)

Kotlin Multiplatform--04&#xff1a;经验总结&#xff08;持续更新&#xff09; 引言 引言 本章用来记载笔者开发过程中的一些经验总结 一、Ktor设置Header 在官方文档中&#xff0c;想要设置Header的示例代码如下&#xff1a; client.get("https://ktor.io&qu…