ratio
先看一下ratio
的定義
template<intmax_t N,intmax_t D=1>
class ratio;
ratio
是由非型別引數定義的模板,用來定義一個比率N/D
,如ratio<1,-2>
表示-0.5
標準庫中定義的常用ratio
型別
type | definition | 說明 |
---|---|---|
ratio<1,1000> | std::milli | 1/1000 |
ratio<1,1000000> | std::micro | 1/1000000 |
ratio<1,1000000000> | std::nano | 1/100000000 |
... | ... | ... |
duration
duration
的定義
template<class Rep, class Period=ratio<1>>
class duration;
表示一個時間段,時間的單位由ratio
指定,如Period=ratio<60,1>
,表示60/1
秒,預設為1/1
,即預設時間單位為1s
如下時間段的定義
std::chrono::duration<int> seconds(2); // 表示2秒
std::chrono::duration<int,std::milli> ms(2); // 表示2毫秒
std::chrono::duration<int,std::ratio<60>> min(2); // 表示2分鐘
標準庫中定義的常用duration
型別
std::chrono::hours
std::chrono::minutes
std::chrono::seconds
std::chrono::milliseconds
std::chrono::microseconds
std::chrono::nanoseconds
成員函式count()
返回Rep
型別的Period
的數量
std::chrono::duration<int,std::ratio<60*60*24>> one_day(2); // 2 days
one_day.count();
標準庫還提供了duration_cast
用於轉換duration
型別
template<class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep,Period>& dtn)
如下時間段的轉換
// 2s
std::chrono::duration<int> seconds(2);
// s to min
auto minutes= std::chrono::duration_cast<duration<double,std::ratio<60>>>(seconds);
time_point
由時鐘表示的時間點,一個time_point
必須由一個 clock 計時
template<class Clock,class Duration=typename Clock::duration>
class time_point;
獲取當前系統時間
// get time
std::chrono::system_clock::time_point now= std::chrono::system_clock::now();
// to time_t
std::time_t now_c= std::chrono::system_clock::to_time_t(now);
std::cout<< ctime(&now_c);
標準庫還提供了time_point_cast
用於指定時間單位
函式原型如下
template<class ToDuration, class Clock, class Duration>
time_point<Clock,ToDuration> time_point_cast(const time_point<Clock,Duration>& tp);
如下應用,將當前時間與紀元(Thu Jan 1 08:00:00 1970)間隔天數列印
typedef std::chrono::duration<int,std::ratio<60*60*24>> Day;
time_point<system_clock,Day> today= time_point_cast<Day>(system_clock::now());
std::cout<< today.time_since_epoch().count();
時鐘
每一個時鐘類中都有確定的time_point
、duration
、Rep
和Period
system_clock
std::chrono::system_clock
表示當前系統時鐘
成員函式
函式名 | 說明 |
---|---|
now() |
獲取當前時間time_point |
to_time_t() |
將time_point 轉換成time_t |
from_time_t() |
將time_t 轉換成time_point |
如下示例,在當前時間上增加一天,並列印
std::chrono::duration<int,std::ratio<60*60*24>> one_day(1);
system_clock::time_point today= system_clock::now();
system_clock::time_point tomorrow= today+one_day;
std::time_t tt;
tt= system_clock::to_time_t(today);
std::cout<< ctime(&tt);
缺點:system_clock
系統時鐘可以修改,如網路對時,所以計時可能不準
steady_clock
該時鐘不可修改,每次 tick 都保證了穩定的時間間隔
如下示例,獲取程式執行時間
steady_clock::time_point t1= steady_clock::now()
/* your code */
steady_clock::time_point t2= steady_clock::now()
duration<double> time_span= duration_cast<duration<double>>(t2-t1);
std::cout<< time_span.count();
high_resolution_clock
最高精度的時鐘,也是不可修改的
注:
儘量不要使用count()
和time_since_epoch()
標準庫提供了型別安全的機制,防止使用者在單位轉換時出錯,但是這兩個函式是例外的
下面提供自定義宏來測試程式碼執行時間
#include <chrono>
#define TIMERSTART(tag) auto tag##_start = std::chrono::steady_clock::now(), tag##_end=tag##_start
#define TIMEREND(tag) tag##_end = std::chrono::steady_clock::now()
#define DURATION_s(tag) printf("%s costs %d s\n",#tag, std::chrono::duration_cast<std::chrono::seconds>(tag##_end-tag##_start).count())
#define DURATION_ms(tag) printf("%s costs %d ms\n",#tag, std::chrono::duration_cast<std::chrono::milliseconds>(tag##_end-tag##_start).count());
#define DURATION_us(tag) printf("%s costs %d us\n",#tag, std::chrono::duration_cast<std::chrono::microseconds>(tag##_end-tag##_start).count());
#define DURATION_ns(tag) printf("%s costs %d ns\n",#tag, std::chrono::duration_cast<std::chrono::nanoseconds>(tag##_end-tag##_start).count());
// usage:
// TIMERSTART(for_loop);
// for (int i = 0; i < 100000; i++) {
// i*i;
// }
// TIMEREND(for_loop);
// DURATION_ms(for_loop);