1. 简述
C++ STL库中的 chrono 是一个关于日期和时间的库,它提供了一套丰富、灵活且类型安全的API,用于测量和操作时间。chrono 库是C++11标准的一部分,它使得我们可以进行高精度的时间测量,以及执行基于时间点的算术操作。
2. chrono的主要组件
(1)时间点(Time Points)
表示一个特定的时间点,例如“2023-07-06 12:00:00”。chrono 库提供了几种时间点类型,如 system_clock::time_point,steady_clock::time_point,high_resolution_clock::time_point 等。
(2)时间长度(Durations)
表示一段时间,例如“5小时”,“10分钟”或“2.5秒”。chrono 库提供了多种表示时间长度的类型,例如 hours,minutes,seconds,milliseconds,microseconds 和 nanoseconds。
(3)时钟(Clocks)
用于获取当前时间点。chrono 库中定义了几个时钟类型,包括 system_clock(表示从1970年1月1日开始的实时时钟),steady_clock(表示一个不会被调整的时钟,通常用于测量持续时间),high_resolution_clock(提供最高精度的时钟)等。
3. 定义时间点并获得时间
std::chrono::time_point是一个模板类,可以通过该类定义基于不同时钟的时间点。
如下,定义了一个基于system_clock的时间点。
std::chrono::time_point<std::chrono::system_clock> sys_time_tic;
之后可以通过如下方式获得某一时间点。
sys_time_tic = std::chrono::system_clock::now();
也可以定义一个steady_clock或high_resolution_clock的时间点,分别如下所示。
std::chrono::time_point<std::chrono::steady_clock> steady_time_tic;
std::chrono::time_point<std::chrono::high_resolution_clock> high_res_time_tic;
获取时间点的方式也有所不同,需要依赖于各自的时钟类型。
steady_time_tic = std::chrono::steady_clock::now();
high_res_time_tic = std::chrono::high_resolution_clock::now();
4. 定义一个时间长度
一般情况下,我们使用std::chrono::duration来定义一个时间长度。
其原型如下所示。
template<class Rep, class Period = std::ratio<1>>
class duration;
Rep是一个数值类型,用来表示此持续时间的长度。这可以是任何数值类型,但通常是整数类型(如 int64_t、long long 等)或浮点数类型(如 double、float)。这个类型决定了能够表示的时间精度和范围。
Period是一个表示时间单位的类型,它通常是 std::ratio 的一个特化,用来表示时间的分母和分子。例如,std::ratio<1> 表示以秒为单位,std::ratio<1, 1000> 表示以毫秒为单位。这个模板参数使得 duration 可以灵活地表示不同的时间单位。
std::chrono::duration还有很多变种,可以更方便的表示一段时间。
- std::chrono::hours
- std::chrono::minutes
- std::chrono::seconds
- std::chrono::milliseconds
- std::chrono::microseconds
- std::chrono::nanoseconds
举例来说,std::chrono::milliseconds类似于std::chrono::duration(int64_t, std::ratio(1, 1000)),但不完全等同,因为前者是一个特化类型,还包含了额外的一些特性。
5. 计算一个时间周期
假如我们想计算一个操作的执行时间,我们定义两个时间点,分别是sys_time_tic和sys_time_toc,那么我们就可以通过std::chrono::duration或std::chrono::duration_cast计算这一操作所花费的时间。
如下,通过std::chrono::duration计算操作所需的秒数。
std::chrono::duration<double> elapsed = sys_time_tic - sys_time_toc;
当然也可以直接的进行转换,下面两种方式是一样的。
std::chrono::milliseconds duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
通过count()获取实际的时长。
std::cout << "The operation took " << duration.count() << " milliseconds." << std::endl;