首页 > 编程语言 >C++ 计时器:chrono库介绍

C++ 计时器:chrono库介绍

时间:2023-06-20 12:14:08浏览次数:45  
标签:std clock chrono C++ 计时器 point time now

C++11有了chrono库,可以在不同系统中很容易的实现定时功能。

要使用chrono库,需要#include,其所有实现均在std::chrono namespace下。注意标准库里面的每个命名空间代表了一个独立的概念。

chrono是一个模版库,使用简单,功能强大,只需要理解三个概念:duration、time_point、clock

一 、时钟-CLOCK
chrono库定义了三种不同的时钟:

1  std::chrono::system_clock:  依据系统的当前时间 (不稳定)
2  std::chrono::steady_clock:  以统一的速率运行(不能被调整)
3  std::chrono::high_resolution_clock: 提供最高精度的计时周期(可能是steady_clock或者system_clock的typedef)

二、这三个时钟有什么区别呢?
system_clock就类似Windows系统右下角那个时钟,是系统时间。明显那个时钟是可以乱设置的。明明是早上10点,却可以设置成下午3点。

steady_clock则针对system_clock可以随意设置这个缺陷而提出来的,他表示时钟是不能设置的。

high_resolution_clock则是一个高分辨率时钟。

这三个时钟类都提供了一个静态成员函数now()用于获取当前时间,该函数的返回值是一个time_point类型,

system_clock除了now()函数外,还提供了to_time_t()静态成员函数。用于将系统时间转换成熟悉的std::time_t类型,得到了time_t类型的值,在使用ctime()函数将时间转换成字符串格式,就可以很方便地打印当前时间了。

 1 #include<iostream>
 2 #include<vector>
 3 #include<string>
 4 #include<ctime>//将时间格式的数据转换成字符串
 5 #include<chrono>
 6 using namespace std::chrono;
 7 using namespace std;
 8 int main()
 9 {
10     //获取系统的当前时间
11     auto t = system_clock::now();
12     //将获取的时间转换成time_t类型
13     auto tNow = system_clock::to_time_t(t);
14 
15     //ctime()函数将time_t类型的时间转化成字符串格式,这个字符串自带换行符
16     string str_time = std::ctime(&tNow);
17 
18     cout<<str_time;
19 
20     return 0;
21 }

三、持续的时间 - duration
td::chrono::duration<int,ratio<60,1>> ,表示持续的一段时间,这段时间的单位是由ratio<60,1>决定的,int表示这段时间的值的类型,函数返回的类型还是一个时间段duration

std::chrono::duration<double,ratio<60,1>>

由于各种时间段(duration)表示不同,chrono库提供了duration_cast类型转换函数。

duration_cast用于将duration进行转换成另一个类型的duration。

duration还有一个成员函数count(),用来表示这一段时间的长度

 1 #include<iostream>
 2 #include<string.h>
 3 #include<chrono>
 4 using namespace std::chrono;
 5 using namespace std;
 6 int main()
 7 {
 8     auto start = std::chrono::steady_clock::now();
 9     for(int i=0;i<100;i++)
10         cout<<"nice"<<endl;
11     auto end = std::chrono::steady_clock::now();
12 
13     auto tt = std::chrono::duration_cast<microseconds>(end - start);
14 
15     cout<<"程序用时="<<tt.count()<<"微秒"<<endl;
16     return 0;
17 }

四、时间点 - time_point
std::chrono::time_point 表示一个具体时间,如上个世纪80年代、你的生日、今天下午、火车出发时间等,只要它能用计算机时钟表示。鉴于我们使用时间的情景不同,这个time point具体到什么程度,由选用的单位决定。一个time point必须有一个clock计时

设置一个时间点:

std::time_point<clock类型> 时间点名字

1 //设置一个高精度时间点
2     std::time_point<high_resolution_clock> high_resolution_clock::now();
1 //设置系统时钟
2     std::chrono::time_point<std::chrono::system_clock> now=std::chrono::system_clock::now();

另一个实例:

  1 #define _CRT_SECURE_NO_WARNINGS //localtime()需要这个宏
  2 #include<iostream>
  3 #include<chrono>
  4 #include<vector>
  5 #include<string>
  6 #include<algorithm>
  7 //#include<stdio.h>
  8 
  9 #include<iomanip> //put_time需要的头文件
 10 
 11 #include<sstream>
 12 
 13     // template <class _Rep>
 14     // struct treat_as_floating_point : is_floating_point<_Rep> {}; // tests for floating-point type
 15 
 16     // template <class _Rep>
 17     // _INLINE_VAR constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value;
 18 
 19     // // STRUCT TEMPLATE duration_values
 20     // template <class _Rep>
 21     // struct duration_values { // gets arithmetic properties of a type
 22     //     _NODISCARD static constexpr _Rep zero() noexcept {
 23     //         // get zero value
 24     //         return _Rep(0);
 25     //     }
 26 
 27     //     _NODISCARD static constexpr _Rep(min)() noexcept {
 28     //         // get smallest value
 29     //         return numeric_limits<_Rep>::lowest();
 30     //     }
 31 
 32     //     _NODISCARD static constexpr _Rep(max)() noexcept {
 33     //         // get largest value
 34     //         return (numeric_limits<_Rep>::max)();
 35     //     }
 36     // };
 37 
 38 //时间长度
 39 void Func1(){
 40     //chrono重载了各种运算符
 41     std::chrono::hours             c1(1);                //1小时
 42     std::chrono::minutes           c2(60);               //60分钟
 43     std::chrono::seconds           c3(60*60);            //60*60s
 44     std::chrono::milliseconds      c4(60*60*1000);       //60*60*1000毫秒
 45     std::chrono::microseconds      c5(60*60*1000*1000);  //微秒 溢出
 46     std::chrono::nanoseconds       c6(60*1000*1000*1000);//纳秒 溢出
 47 
 48     if(c1==c2){
 49         std::cout<<"c1==c2"<<std::endl;
 50     }
 51     if(c1==c3){
 52         std::cout<<"c1==c3"<<std::endl;
 53     }
 54     if(c2==c3){
 55         std::cout<<"c2==c3"<<std::endl;
 56     }
 57 
 58     //获取时钟周期的值,返回的是int整数
 59     std::cout<<"c1= "<<c1.count()<<std::endl;
 60     std::cout<<"c2= "<<c2.count()<<std::endl;
 61     std::cout<<"c3= "<<c3.count()<<std::endl;
 62     std::cout<<"c4= "<<c4.count()<<std::endl;
 63 
 64     std::chrono::seconds             c7(1);               //1秒
 65     std::chrono::milliseconds        c8(1*1000);          //1000毫秒;1s
 66     std::chrono::microseconds        c9(1*1000*1000);     //1000*1000微秒 1s
 67     std::chrono::nanoseconds         c10(1*1000*1000*1000);//1000*1000*1000纳秒 1s;
 68 
 69     std::cout<<c7.count()<<std::endl;
 70     std::cout<<c8.count()<<std::endl;
 71     std::cout<<c9.count()<<std::endl;
 72     std::cout<<c10.count()<<std::endl;
 73 }
 74 
 75 //系统时间
 76 /**
 77  * @brief 
 78  * 
 79  * system_clock 类支持了对系统时钟的访问, 提供了三个静态成员函数:
 80 返回当前时间的时间点。
 81 static std::chrono::time_point<std::chrono::system_clock> now() noexcept;
 82 将时间点 time_point 类型转换为 std::time_t 类型。
 83 static std::time_t to_time_t( const time_point& t ) noexcept;
 84 将 std::time_t 类型转换为时间点 time_point 类型。
 85 static std::chrono::system_clock::time_point from_time_t( std::time_t t ) noexcept;
 86  */
 87 
 88 void Func2(){
 89     //静态成员函数 static std::chrono::time_point<std::chrono::system_clock> now() noexcept
 90     //这些都可以简写用auto now=std::chrono::system_clock()::now()接收
 91     //1、静态成员函数 static std::chrono::system_clock::now()用来获取系统时间,C++时间
 92     std::chrono::time_point<std::chrono::system_clock> now=std::chrono::system_clock::now();
 93 
 94     //2、静态成员函数 static std::chrono::system_clock::to_time_t()把C++系统时间转换为time_t (utc时间)
 95     time_t t_now=std::chrono::system_clock::to_time_t(now);
 96 
 97     //3、std::localtime()函数把time_t时间转换为本地时间(北京时间)
 98     // std::localtime()不是线程安全的,VS用localtime_t()代替,linux用local_time_r()代替
 99     //tm结构体
100     tm* tm_now=localtime(&t_now);
101 
102     //格式化输出tm结构体中的成员
103     std::cout<<std::put_time(tm_now,"%Y-%m-%d %H:%M:%S")<<std::endl;
104     std::cout<<std::put_time(tm_now,"%Y-%m-%d")<<std::endl;
105     std::cout<<std::put_time(tm_now,"%H:%M:%S")<<std::endl;
106 
107     //但是通常C++一般不打印出时间,而是把时间存储到一个字符串中
108 
109     std::stringstream ss;  //创建stringstream对象 ss,需要包含<sstream>头文件
110     ss<<std::put_time(tm_now,"%Y-%m-%d %H:%M:%S");
111     std::string time_str=ss.str();
112     std::cout<<time_str<<std::endl;
113 }   
114 
115 // struct steady_clock { // wraps QueryPerformanceCounter
116 //         using rep                       = long long;
117 //         using period                    = nano;
118 //         using duration                  = nanoseconds;
119 //         using time_point                = chrono::time_point<steady_clock>;
120 //         static constexpr bool is_steady = true;
121 
122 //         _NODISCARD static time_point now() noexcept { // get current time
123 //             const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot
124 //             const long long _Ctr  = _Query_perf_counter();
125 //             static_assert(period::num == 1, "This assumes period::num == 1.");
126 //             // Instead of just having "(_Ctr * period::den) / _Freq",
127 //             // the algorithm below prevents overflow when _Ctr is sufficiently large.
128 //             // It assumes that _Freq * period::den does not overflow, which is currently true for nano period.
129 //             // It is not realistic for _Ctr to accumulate to large values from zero with this assumption,
130 //             // but the initial value of _Ctr could be large.
131 //             const long long _Whole = (_Ctr / _Freq) * period::den;
132 //             const long long _Part  = (_Ctr % _Freq) * period::den / _Freq;
133 //             return time_point(duration(_Whole + _Part));
134 //         }
135 //     };
136 
137 //     using high_resolution_clock = steady_clock;
138 // } // namespace chrono
139 
140 //计时器 steady_clock 类相当于秒表,操作系统只要启动就会进行时间的累加,常用于耗时的统计(精确到纳秒) 。
141 void Func3(){
142     //静态成员函数std::chrono::steady_clock::now()获取时间的开始点
143     std::chrono::time_point<std::chrono::steady_clock> start=std::chrono::steady_clock::now();
144     //auto start=std::chrono::steady_clock::now();
145     //执行一些代码,消耗时间
146     std::vector<std::string> vec1{"banana","apple","pear"};
147     std::for_each(vec1.begin(),vec1.end(),[&vec1](std::string str){
148         std::cout<<str<<" ";
149     });
150     std::cout<<std::endl;
151     //静态成员函数std::chrono::steady_clock::now()获取时间的结束点
152     auto end=std::chrono::steady_clock::now();
153 
154     //计算消耗的时间,单位是纳秒
155     auto dt=end-start;
156     std::cout<<"耗时: "<<dt.count()<<"纳秒 ("<<(double)dt.count()/(1000*1000*1000)<<"秒) "<<std::endl;
157 
158 }
159 
160 int main(int argc,char* argv[]){
161     Func1();
162     Func2();
163     Func3();
164     return 0;
165 }

输出结果:

 1 PS D:\时间操作 chrono 库\bin\Debug> .\main.exe
 2 c1==c2
 3 c1==c3
 4 c2==c3
 5 c1= 1
 6 c2= 60
 7 c3= 3600
 8 c4= 3600000
 9 1
10 1000
11 1000000
12 1000000000
13 2023-01-04 22:32:43
14 2023-01-04
15 22:32:43
16 2023-01-04 22:32:43
17 banana apple pear
18 耗时: 733400纳秒 (0.0007334秒)
19 PS D:\时间操作 chrono 库\bin\Debug> 

 

标签:std,clock,chrono,C++,计时器,point,time,now
From: https://www.cnblogs.com/ybqjymy/p/17493272.html

相关文章

  • 【剑指 Offer】数组中重复的数字(C++_Easy_遍历/哈希/快排/原地)
    题目在一个长度为n的数组nums里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。测试样例输入:[2,3,1,0,2,5,3]输出:2或3限制2<=n<=100000题解题解一:遍历对vector容器......
  • 【计算机算法设计与分析】线性时间选择(C++_分治递归)
    问题描述给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素。思路线性时间选择有两种方法:(1)随机选择快排的标准元素。(2)将集合分为n个由五个元素组成的集合,对每个五元素集合求其中位数,再对所有的五元素集合的中位数求其中位数,作为快排的标准元素。CodeV-1(Ran......
  • 【剑指 Offer】用两个栈实现队列(C++_Easy_栈/队列)
    1.题目用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead操作返回-1)2.示例2.1示例1输入:[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”......
  • 【计算机算法设计与分析】6-5 最小重量机器设计问题(C++_回溯法/分支限界法)
    问题描述设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设wij是从供应商j处购得的部件i的重量,cij是相应的价格。设计一个优先队列式分支限界法,给出总价格不超过d的最小重量机器设计。对于给定的机器部件重量和机器部件价格,设计一个优先队列式分......
  • 【蓝桥杯_真题演练】换零钞(C++_遍历)
    题目x星球的钞票的面额只有:100元,5元,2元,1元,共4种。小明去x星旅游,他手里只有2张100元的x星币,太不方便,恰好路过x星银行就去换零钱。小明有点强迫症,他坚持要求200元换出的零钞中2元的张数刚好是1元的张数的10倍,剩下的当然都是5元面额的。银行的工作人员有点为难,你能帮助算出:在满足小......
  • 【蓝桥杯_真题演练】第九届C/C++省赛B组_C-乘积尾零(C++_数论)
    Problem如下的10行数据,每行有10个整数,请你求出它们的乘积的末尾有多少个零?56504542355447394641143871907390432927587949611356595245743230514434670435949937117368663397475975573070228714539899148657223135117040145510512072928809......
  • PTA_乙级_1015 德才论(C++_模拟_快排)
    宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”现给出一批考生的德才分数,请根据司马光的理论给出录取排名。输入格式:输入第一行给出3个......
  • P3371 【模板】单源最短路径(弱化版)(C++_SPFA算法_链式向前星)
    题目背景本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步P4779。题目描述如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。输入格式第一行包含三个整数n,m,s,分别表示点的个数、有向边的个数、出发点的编号。接下来m行每行包含三个......
  • C++ primer plus学习之第二章
    1.引用:intival=1024;int&refval=ival;//正确,refval时ival的别名int&re;//错误,引用必须被初始化int&ii=42;//错误:不能为非常量引用绑定字面值constint&ii=42;//正确:可以为常量引用绑定字面值2.初始化空指针int*p=0;int*p=NULL;int*p=nullptr;//最好用这个任何非零指......
  • 总结C++中#include<>和#include""的区别
    查找目录不同1、#include<>编译器直接从系统类库目录里查找头文件比如在vs中,使用#include<>编译器会直接在vs安装目录下在编译器自带的库文件中进行搜索。如果类库目录下查找失败,编译器会终止查找,直接报错:Nosuchfileordirectory.如果我们自定义一个头文件"aaa.h",将其放在......