C++进阶:chrono之clock

admin 2023年2月26日14:28:35评论16 views字数 3712阅读12分22秒阅读模式

概述

clock表示系统范围的实时壁钟,大多数系统上,系统时间可以在任何时候被调节。它是唯一有能力映射其时间点到 C 风格时间的 C++ 时钟。

C++20前,不指定 system_clock 的纪元,它多数情况下实现使用 Unix 时间(即从协调世界时 (UTC) 1970 年 1 月 1 日星期四 00:00:00 开始的时间,不计闰秒)。C++20后,system_clock 确定就是使用 Unix 时间。

chrono 库中提供了获取当前的系统时间的时钟类,包含的时钟一共有三种:

  • system_clock:系统的时钟,系统的时钟可以修改,甚至可以网络对时,因此使用系统时间计算时间差可能不准。

  • steady_clock:是固定的时钟,相当于秒表。开始计时后,时间只会增长并且不能修改,适合用于记录程序耗时

  • high_resolution_clock:和时钟类 steady_clock 是等价的(是它的别名)。

在这些时钟类的内部有 time_point、duration、Rep、Period 等信息,基于这些信息来获取当前时间,以及实现 time_t 和 time_point 之间的相互转换。

system_clock

成员类型

C++进阶:chrono之clock

成员函数

// 返回表示当前时间的时间点。static std::chrono::time_point<std::chrono::system_clock> now() noexcept;// 将 time_point 时间点类型转换为 std::time_t 类型static std::time_t to_time_t( const time_point& t ) noexcept;// 将 std::time_t 类型转换为 time_point 时间点类型static std::chrono::system_clock::time_point from_time_tstd::time_t t ) noexcept;

示例:

#include #include 
using namespace std;using namespace std::chrono;
int main(){ // 新纪元1970.1.1时间 system_clock::time_point epoch;
duration<int, ratio<60*60*24>> day(1); // 新纪元1970.1.1时间 + 1天 system_clock::time_point ppt(day);
using dday = duration<int, ratio<60 * 60 * 24>>; // 新纪元1970.1.1时间 + 10天 time_pointt(dday(10));
// 系统当前时间 system_clock::time_point today = system_clock::now(); // 转换为time_t时间类型 time_t tm = system_clock::to_time_t(today); cout << "today: " << ctime(&tm);
time_t tm1 = system_clock::to_time_t(today+day); cout << "tommorow: " << ctime(&tm1);
time_t tm2 = system_clock::to_time_t(epoch); cout << "epoch: " << ctime(&tm2);
time_t tm3 = system_clock::to_time_t(ppt); cout << "epoch+1d: " << ctime(&tm3);
time_t tm4 = system_clock::to_time_t(t); cout << "epoch+10d: " << ctime(&tm4);}

输出:

today:       Wed Jul  6 23:00:14 2022tommorow:    Thu Jul  7 23:00:14 2022epoch:      Thu Jan  1 00:00:00 1970epoch+1d:   Fri Jan  2 00:00:00 1970epoch+10d: Sun Jan 11 00:00:00 1970


steady_clock

如果我们通过时钟不是为了获取当前的系统时间,而是进行程序耗时的时长,此时使用 syetem_clock 就不合适了(外部可以进行修改),因为这个时间可以跟随系统的设置发生变化。在 C++11 中提供的时钟类 steady_clock 相当于秒表,只要启动就会进行时间的累加,并且不能被修改,非常适合于进行耗时的统计。

成员类型

成员类型跟system_clock一样,但是具体细节有些差异,如下:

C++进阶:chrono之clock

示例:

#include #include 
int main() { for (auto size = 1ull; size < 1000000000ull; size *= 100) { // record start time auto start = std::chrono::steady_clock::now(); // do some work std::cout << "do something ...." << std::endl; for (auto i = 0; i < 1000000; i++); //do something // record end time auto end = std::chrono::steady_clock::now(); std::chrono::duration<double> diff = end - start; std::cout << "Time use "<< diff.count() << " sn"; }}


high_resolution_clock

high_resolution_clock表示实现提供的拥有最小计次周期的时钟。它可以是system_clock或steady_clock的别名,或者第三个独立时钟。

high_resolution_clock 在不同标准库实现之间实现不一致,应该尽量避免使用它。通常它只是 std::chrono::steady_clockstd::chrono::system_clock 的别名,但实际是哪个取决于库或配置。它是 system_clock 时不是单调的(即时间能后退)。例如对于 gcc 的 libstdc++ 它是 system_clock ,对于 MSVC 它是 steady_clock ,而对于 clang 的 libc++ 它取决于配置。通常用户应该直接使用 std::chrono::steady_clock 或 std::chrono::system_clock 代替 std::chrono::high_resolution_clock ;对时长度量使用 steady_clock ,对壁钟时间使用 system_clock

其他的成员类型函数跟上面两哥们基本差不多,主要还是使用now方法:

#include #include 
int main() { for (auto size = 1ull; size < 1000000000ull; size *= 100) { // record start time auto start = std::chrono::high_resolution_clock::now(); // do some work std::cout << "do something ...." << std::endl; for (auto i = 0; i < 1000000; i++); //do something // record end time auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> diff = end - start; std::cout << "Time use "<< diff.count() << " sn"; }}

总的来说:

  • 对于system_clock,其起点是epoch,即1970-01-01 00:00:00 UTC,其刻度是1个tick,也就是_XTIME_NSECS_PER_TICK纳秒(一般是100纳秒)。

  • steady_clock的刻度是1纳秒,起点并非1970-01-01 00:00:00 UTC,一般是系统启动时间,这就是问题的关键。steady_clock的作用是为了得到不随系统时间修改而变化的时间间隔,所以凡是想得到绝对时点的用法都是错误的。steady_clock是没有to_time_t()的实现的,而system_clock是有的。

  • high_resolution_clock实际上和steady_clock一样。

一般使用场景是:

  • system_clock:用在需要得到绝对时点的场景

  • steady_clock:用在需要得到时间间隔,并且这个时间间隔不会因为修改系统时间而受影响的场景

  • high_resolution_clock:high_resolution_clock是system_clock或steady_clock之一,根据情况使用

clock时钟相关内容就到这里了。


作者:Codemaxi
链接:https://juejin.cn/post/7129503818621911048
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


原文始发于微信公众号(汇编语言):C++进阶:chrono之clock

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年2月26日14:28:35
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   C++进阶:chrono之clockhttp://cn-sec.com/archives/1575556.html

发表评论

匿名网友 填写信息