std::chrono是C++11引入的日期時間處理庫,其中包含3種時鐘:system_clock,steady_clock,high_resolution_clock。近來須要使用高精度時間,很天然想到使用high_resolution_clock,然而使用後發現並不是預期的獲得自1970/1/1零點以後的計數,而是一個小得多的數字。那麼這三種時鐘有什麼區別,用在什麼狀況下,咱們來一探究竟。this
auto tp = std::chrono::high_resolution_clock::now(); std::cout << tp.time_since_epoch().count() << std::endl;
上述代碼輸出一個比較小的數字,high_resolution_clock的精度是納秒,不多是這麼小的數字。code
所謂時鐘,是指從一個時點開始,按照某個刻度的一個計數。以下代碼摘自VC2017。orm
struct system_clock { // wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime typedef long long rep; typedef ratio_multiply<ratio<_XTIME_NSECS_PER_TICK, 1>, nano> period; typedef chrono::duration<rep, period> duration; typedef chrono::time_point<system_clock> time_point; static constexpr bool is_steady = false;
對於system_clock,其起點是epoch,即1970-01-01 00:00:00 UTC,其刻度是1個tick,也就是_XTIME_NSECS_PER_TICK納秒。ip
typedef steady_clock high_resolution_clock;
high_resolution_clock實際上和steady_clock同樣。ci
struct steady_clock { // wraps QueryPerformanceCounter typedef long long rep; typedef nano period; typedef nanoseconds duration; typedef chrono::time_point<steady_clock> time_point; static constexpr bool is_steady = true;
steady_clock的刻度是1納秒,起點並不是1970-01-01 00:00:00 UTC,通常是系統啓動時間,這就是問題的關鍵。steady_clock的做用是爲了獲得不隨系統時間修改而變化的時間間隔,因此凡是想獲得絕對時點的用法都是錯誤的。steady_clock是沒有to_time_t()的實現的,而system_clock是有的。io
auto tp = std::chrono::system_clock::now(); std::time_t tt = std::chrono::system_clock::to_time_t(tp); std::cout << tt << "seconds from 1970-01-01 00:00:00 UTC" << std::endl;
auto tp1 = std::chrono::steady_clock::now(); //do something auto tp2 = std::chrono::steady_clock::now(); std::cout << std::chrono::duration_cast<std::chrono::microseconds>(tp2 - tp1).count() << "microseconds" << std::endl;