std::chrono學習筆記
chrono是一個模版庫,提供關於日期和時間的一些功能。
先舉個例子,如果我想知道看這篇博文花了多長時間:
(1)首先需要有一個能提供時鐘(clock)的設備(電腦、手機、手錶、掛鐘等)
(2)記錄開始閱讀和結束閱讀的時間點(time_point);
(3)計算兩次的時間之差就是閱讀持續時間(duration)。
chrono的模板庫常用的3個模板也是這3個:duration、time_point、clock。
在使用時,需要引用chrono頭文件。
#include <chrono>
clock
既然談到時間,總需要找一個時鐘作爲參照吧,就像我們想知道當前時間,可以看牆上的掛鐘,可以看手錶,可以看手機。clock就是這個時鐘,在計算機中一般都會有一套或多套時鐘系統供程序使用。
在std::chrono庫中,有3種時鐘:
- system_clock
- steady_clock
- hight_definition_clock
一般情況下,他們3個沒有太大的區別,hight_definition_clock、steady_clock僅僅是system_clock的typedef,但是有爲什麼要區分呢,因爲在有些情況下,他們是存在差異的。
情況1:system_clock和steady_clock的差異
比如windows系統可以提供時鐘,如果認爲時間不準,我們還可以進行調整。在沒有調整時間前,system_clock和steady_clck是一樣的,他們的讀數都是單調勻速增加的;但是如果調整時間後,它們兩者的讀數就會出現差異,system_clock的讀數就會出現跳變,而steady_clock依然保持線性單調遞增,不受clock調整的影響,這個特點非常方便我們統計時間耗時(duration)。
情況2:system_clock與hight_definition_clock的差異
如果系統提供的時鐘(clock)不止一種,有的時鐘精度高(分辨率),有的精度低,hight_definition_clock使用時精度最高的clock,但是system_clock就不一定了。
clock主要用於獲取當前的時間,通過now()獲取,方法如下。關於time_point在下面講解。
std::chrono::system_clock::time_point current_time = std::chrono::system_clock::now();
time_point
time_point是具體的時間,比如某年某月某日幾點幾分幾秒,time_point依賴於clock的計時。
通過上文中的方法可以將當前時間賦值給current_time,current_time的時間數據是一個數字,表示當前時間是經過了多少個計時單位了,那麼計時的起點是什麼時候呢?爲了讓不同地區、不同國家、不同的設備有一個統一標準,可以通過time_since_epoch().count()計算以 1970 年 1 月 1 日 00:00 UTC 爲起點的時間。
std::chrono::system_clock::time_point current_time = std::chrono::system_clock::now();
cout << "current_time = " << current_time.time_since_epoch().count() << endl;
duration
duration表示一段時間,也就是持續時間,是一個時間的長度,比如1個小時、35秒、33毫秒。
它的模板類如下,包含兩個參數,Rep是必需要指定的,Period是可選擇輸入的,簡單的說Rep表示數據的類型,如int、float等;Period可以理解爲時間的單位,默認是1秒,自己也可自定義修改,就是duration每增加1與之對應的時間是多少。
template <class Rep, class Period = ratio<1> > class duration;
- 使用默認1秒作爲計量單位
typedef std::chrono::duration<int> t_int;
typedef std::chrono::duration<double> t_float;
// duration每增加1,表示的時間的變化量爲1秒
- 使用自定義的值作爲計量單位
// duration每增加1,時間的變化爲0.001秒
typedef std::chrono::duration<float, std::ratio<1,1000>> mSec_float; // 1/1000秒作爲計量單位,也就毫秒
// duration每增加1,時間的變化爲60秒
typedef std::chrono::duration<int, ratio<60, 1>> minute_int; // 60/1秒爲計量電位,也就是1分鐘
上面ratio有兩個參數ratio<num, den>,那麼實際的單位爲num/den秒。
除了可以通過ratio來自定義時間的計量單位,也可以使用std庫中預定義好的變量,本質上也是使用ratio定義好的。
使用方法如下
std::chrono::duration<int, std::milli> // 毫秒
std::chrono::duration<int, std::micro> // 微秒
std::chrono::duration<int, std::nano> // 納秒
- 如何定義、修改duration的變量
#include <chrono>
#include <iostream>
using namespace std;
int main(int argc, int** argv[]) {
typedef std::chrono::duration<int, std::milli> mSec_t;
mSec_t t1(2000);
cout << "t1 = " << t1.count() << endl;
// t1 = 3000; // 不能這樣賦值
t1 = mSec_t(3000); // 修改變量
cout << "t1 = " << t1.count() << endl;
system("pause");
return 0;
}
一個例子
通過獲取兩個時刻的時間,然後計算時間長度。
#include <chrono>
#include <iostream>
#include <thread>
#include <ctime>
using namespace std;
int main() {
// DEMO:通過獲取兩個時刻的時間,然後計算時間長度
using namespace std::chrono;
// Step one: 定義一個clock
typedef system_clock sys_clk_t;
// Step two: 分別獲取兩個時刻的時間
typedef system_clock::time_point time_point_t;
// 第1個時間
time_point_t time01 = sys_clk_t::now();
// 延時5秒
std::this_thread::sleep_for(std::chrono::duration<int>(5));
// 第2個時間
time_point_t time02 = sys_clk_t::now();
// Step three: 計算時間差
cout << "dt_time(system_clock period) = " << (time02 - time01).count() << endl;
typedef duration<int, std::ratio<1, 1000>> mili_sec_t;
cout << "\ndt_time(user define period) = " <<
(time_point_cast<mili_sec_t>(time02) - time_point_cast<mili_sec_t>(time01)).count() << endl;
system("pause");
return 0;
}
運行結果如下:
system_clock的計時單位是10-7秒。