c++11 chrono全面解析(最高可達納秒級別的精度)
chrono是c++ 11中的時間庫,提供計時,時鐘等功能。
學習chrono,關(guān)鍵是理解里面時間段(Durations)、時間點(Time points)的概念。
1.精度:
時鐘節(jié)拍(時間精度):
template <intmax_t N, intmax_t D = 1> class ratio;
其中N表示分子,D表示分母,默認用秒表示的時間單位。
N對應(yīng)于其成員num,D對應(yīng)于其成員den
常用的單位:
ratio<60, 1>? ??? ??? ??? ??? ??minute
ratio<1, 1>? ??? ??? ??? ??? ????second
ratio<1, 1000>? ??? ??? ??? ?millisecond
...
ratio主要是是為后面將要講解的時間段,時間點等提供精度(單位)
#include<iostream> #include<chrono> using namespace std; int main() { cout << "millisecond : "; cout << std::chrono::milliseconds::period::num << "/" << std::chrono::milliseconds::period::den << "s" <<endl; system("pause"); return 0; }
2.時間段:
template <class Rep, class Period = ratio<1> > class duration;
std::chrono::duration 表示一段時間,比如兩個小時,12.88秒,半個時辰,一炷香的時間等等
Rep表示一種數(shù)值類型,用來表示Period的數(shù)量,比如int float double。
Period是ratio類型,用來表示上面所說的單位精度,比如second milisecond。
chrono中宏定義了許多特例化了的duration: 就是常見的hours,miniutes,seconds,milliseconds等,使用std::chrono::milliseconds直接使用。
(1)構(gòu)造函數(shù)很簡單
(1)duration() = default; //默認構(gòu)造 (2)duration (const duration& dtn); //(2)(3)拷貝構(gòu)造 (3)template<class Rep2, class Period2> constexpr duration (const duration<Rep2,Period2>& dtn); (4)template<class Rep2> //傳遞一個某類型(int等)的數(shù)值,構(gòu)造一個時間段 constexpr explicit duration (const Rep2& n);
(2)成員函數(shù)count()返回單位時間的數(shù)量。
#include <iostream> #include <chrono> int main() { std::chrono::milliseconds mscond(1000); // 1 second std::cout << mscond.count() << " milliseconds.\n"; std::cout << mscond.count() * std::chrono::milliseconds::period::num / std::chrono::milliseconds::period::den; std::cout << " seconds.\n"; system("pause"); return 0; }
(2)當不要求截斷值的情況下(時轉(zhuǎn)換成秒是沒問題,但是秒轉(zhuǎn)換成時就不行)時間段的轉(zhuǎn)換是隱式
的。顯示轉(zhuǎn)換可以由 std::chrono::duration_cast<> 來完成。
比如 std::chrono::milliseconds ms(54802);
std::chrono::seconds s=std::chrono::duration_cast<std::chrono::seconds>(ms);
這里的結(jié)果就是截斷的,而不是進行了舍入,所以s最后的值將為54。
3.時間點:
template <class Clock, class Duration = typename Clock::duration> class time_point;
std::chrono::time_point 表示一個具體時間,如上個世紀80年代、今天下午3點、火車出發(fā)時間等,只要它能用計算機時鐘表示。
第一個模板參數(shù)Clock用來指定所要使用的時鐘(標準庫中有三種時鐘,system_clock,steady_clock和high_resolution_clock。見4時鐘詳解),第二個模板函數(shù)參數(shù)用來表示時間的計量單位(特化的std::chrono::duration<> )
時間點都有一個時間戳,即時間原點。chrono庫中采用的是Unix的時間戳1970年1月1日 00:00。所以time_point也就是距離時間戳(epoch)的時間長度(duration)。
(1)構(gòu)造函數(shù):
(1) |
time_point(); //默認構(gòu)造函數(shù),時間戳作為其值 |
---|---|
(2) |
template <class Duration2> time_point (const time_point<clock,Duration2>& tp); //拷貝構(gòu)造函數(shù) |
(3) |
explicit time_point (const duration& dtn); //使用duration構(gòu)造,就是距離時間戳的時間長度 |
(2)時間點有個重要的函數(shù):duration time_since_epoch() ?(用于獲取當前時間點距離時間戳的時間長度)
即經(jīng)常用來得到當前時間點到1970年1月1日00:00的時間距離、該函數(shù)返回的duration的精度和構(gòu)造time_point的時鐘(Clock)有關(guān)(見4時鐘詳解)。
#include <iostream> #include <chrono> #include <ctime> using namespace std; int main() { //距離時間戳2兩秒 chrono::time_point<chrono::system_clock, chrono::seconds> tp(chrono::seconds(2)); cout << "to epoch : " <<tp.time_since_epoch().count() << "s" <<endl; //轉(zhuǎn)化為ctime,打印輸出時間點 time_t tt = chrono::system_clock::to_time_t(tp); char a[50]; ctime_s(a, sizeof(a), &tt); cout << a; system("pause"); return 0; }
可以看出,時間戳就是使用的Unix的時間戳。
4.時鐘:(代表當前系統(tǒng)的時間)
chrono中有三種時鐘:system_clock,steady_clock和high_resolution_clock。每一個clock類中都有確定的time_point, duration, Rep, Period類型。
system_clock是不穩(wěn)定的。因為時鐘是可調(diào)的,即這種是完全自動適應(yīng)本地賬戶的調(diào)節(jié)。這種調(diào)節(jié)可能造成的是,首次調(diào)用now()返回的時間要早于上次調(diào)用now()所返回的時間,這就違反了節(jié)拍頻率的均勻分布。穩(wěn)定鬧鐘對于超時的計算很重要,所以C++標準庫提供一個穩(wěn)定時鐘 std::chrono::steady_clock。std::chrono::high_resolution_clock 是標準庫中提供的具有最小節(jié)拍周期(因此具有最高的精度的時鐘)。
上文所說time_since_epoch(),以及將要介紹的now()函數(shù)的返回值都依賴于時鐘的精度,測試時鐘的精度的一種方法就是:
#include <iostream> #include <chrono> using namespace std; int main() { cout << "system clock : "; cout << chrono::system_clock::period::num << "/" << chrono::system_clock::period::den << "s" << endl; cout << "steady clock : "; cout << chrono::steady_clock::period::num << "/" << chrono::steady_clock::period::den << "s" << endl; cout << "high resolution clock : "; cout << chrono::high_resolution_clock::period::num << "/" << chrono::high_resolution_clock::period::den << "s" << endl; system("pause"); return 0; }
windows系統(tǒng)的測試結(jié)果是system_clock的精度是100納秒,而high_resolution的精度是1納秒,對于程序來說,一般毫秒級就夠了,所以說chrono提供的時鐘精度綽綽有余。
(1)成員函數(shù)static time_point now() noexcept; 用于獲取系統(tǒng)的當前時間。
(2)由于各種time_point表示方式不同,chrono也提供了相應(yīng)的轉(zhuǎn)換函數(shù) time_point_cast。
template <class ToDuration, class Clock, class Duration> time_point<Clock,ToDuration> time_point_cast (const time_point<Clock,Duration>& tp);
傳一個要轉(zhuǎn)換為的精度的duration模板參數(shù)和一個要轉(zhuǎn)換的time_point參數(shù)(用法見下面綜合應(yīng)用)
(3)其他成員函數(shù):
to_time_t() time_point轉(zhuǎn)換成time_t秒
from_time_t() 從time_t轉(zhuǎn)換成time_point
綜合應(yīng)用:
輸出當前時間,并且計算當前的時間距離1970年1月1日00:00的毫秒數(shù)
#include <iostream> #include <chrono> #include <ctime> using namespace std; int main() { //定義毫秒級別的時鐘類型 typedef chrono::time_point<chrono::system_clock, chrono::milliseconds> microClock_type; //獲取當前時間點,windows system_clock是100納秒級別的(不同系統(tǒng)不一樣,自己按照介紹的方法測試),所以要轉(zhuǎn)換 microClock_type tp = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now()); //轉(zhuǎn)換為ctime.用于打印顯示時間 time_t tt = chrono::system_clock::to_time_t(tp); char _time[50]; ctime_s(_time,sizeof(_time),&tt); cout << "now time is : " << _time; //計算距離1970-1-1,00:00的時間長度,因為當前時間點定義的精度為毫秒,所以輸出的是毫秒 cout << "to 1970-1-1,00:00 " << tp.time_since_epoch().count() << "ms" << endl; system("pause"); return 0; }
通過兩張圖片對比,時間點上相差48-34=14秒、、下面的一長串數(shù)字,切掉3位(毫秒)、是28-14=14秒、、正確!說明這一串數(shù)字的最后三位就是毫秒數(shù)、、充分說明了達到了毫秒級別。
將上面的程序中millisconds換成microseconds或者更小的單位,便可達到微妙,甚至更高的精度。
到此這篇關(guān)于c++11 chrono全面解析(最高可達納秒級別的精度)的文章就介紹到這了,更多相關(guān)c++11 chrono內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實現(xiàn)圖的鄰接矩陣存儲和廣度、深度優(yōu)先遍歷實例分析
這篇文章主要介紹了C++實現(xiàn)圖的鄰接矩陣存儲和廣度、深度優(yōu)先遍歷,實例分析了C++實現(xiàn)圖的遍歷技巧,非常具有實用價值,需要的朋友可以參考下2015-04-04C語言中關(guān)于scanf函數(shù)的一些問題詳解
這篇文章主要為大家介紹了C語言中關(guān)于scanf函數(shù)的一些問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2021-12-12C++使用MySQL-Connector/C++連接MySQL出現(xiàn)LNK2019錯誤的解決方法
這篇文章主要介紹了C++使用MySQL-Connector/C++連接MySQL出現(xiàn)LNK2019錯誤的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03c++11中關(guān)于std::thread的join的詳解
這篇文章主要介紹了c++11中關(guān)于std::thread的join詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-03-03C++自定義API函數(shù)實現(xiàn)大數(shù)相乘算法
這篇文章主要為大家詳細介紹了C++自定義API函數(shù)實現(xiàn)大數(shù)相乘算法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-09-09