从C++11起,C++提供了更加现代的时间工具,定义在<chrono>
中,namespace std::chrono
下。
chrono
库主要定义了三种类型:时钟(clock)、时间点(time point)和时间段(duration)。时钟产生时间点,时间点相减得到时间段,时间点加减时间段得到时间点。由于有auto
自动类型推导和运算符重载的存在,我们在使用时很少需要写明与时间相关的变量的类型。
C++标准规定了3种时钟:
-
system_clock
,系统范围的挂钟,可以理解为桌面右下角的时钟,这个时钟是可以调节的,因此system_clock
的返回值可能不是单调的; -
steady_clock
,稳定的、单调的时钟,不受系统时间调节的影响,因而适合于测量时间间隔,通常测量程序运行时间就用steady_clock
; -
high_resolution_clock
,可用的最高精度的时钟,可以是上面两个的别名。
每个时钟都有静态方法now
返回当前的时间点,is_steady
常量表示时钟是否单调(steady_clock::is_steady
一定为true
)。system_clock
是唯一能与C中time_t
互通的时钟。
时钟定义了成员类型period
,表示一个时钟周期的时长(以秒为单位)。在MSVC和GCC中,steady_clock::period
都是nano
,理论上的分辨率为纳秒。
两个时间点相减可以得到时间段,调用其count
函数可以获得其数值,这个时间段的类型是由实现定义的。标准还定义了milliseconds
、seconds
等类型,为了得到以我们想要的单位表示的时间段,可以用duration_cast
来转换:
#include <iostream>
#include <chrono>
int work()
{
int sum = 0;
for (int i = 0; i < 1e8; ++i)
sum += i * i;
return sum;
}
int main()
{
auto start = std::chrono::steady_clock::now();
volatile int result = work();
auto finish = std::chrono::steady_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(finish - start);
std::cout << duration.count() << "ms" << std::endl;
}
但是这样只能输出整数毫秒,如果想要更精确一点,一种方法是转换成microseconds
以后除以1000.0
,更优雅地可以自己定义一种时间段类型,如duration<double, milli>
,其中double
表示这种时间段类型用double
来存储时钟周期数量,milli
表示时钟周期为1ms。从由整数表示的duration
到由浮点数表示的duration
的转换可以由duration
的构造函数来完成,无需再用duration_cast
:
auto start = std::chrono::steady_clock::now();
volatile int result = work();
auto finish = std::chrono::steady_clock::now();
using milliseconds = std::chrono::duration<double, std::milli>;
milliseconds duration = finish - start;
std::cout << duration.count() << "ms" << std::endl;
示例:
auto start = std::chrono::steady_clock::now();//计时开始
N = p * q;
auto finish = std::chrono::steady_clock::now();
using milliseconds = std::chrono::duration<double, std::milli>;
milliseconds duration = finish - start;
std::cout << "first run time is "<<duration.count() << "ms" << std::endl;//计时结束