C++11計(jì)時(shí)器之chrono庫簡(jiǎn)介
C++11計(jì)時(shí)器:chrono庫介紹
C++11有了chrono庫,可以在不同系統(tǒng)中很容易的實(shí)現(xiàn)定時(shí)功能。
要使用chrono庫,需要#include,其所有實(shí)現(xiàn)均在std::chrono namespace下。注意標(biāo)準(zhǔn)庫里面的每個(gè)命名空間代表了一個(gè)獨(dú)立的概念。
chrono是一個(gè)模版庫,使用簡(jiǎn)單,功能強(qiáng)大,只需要理解三個(gè)概念:duration、time_point、clock
一 、時(shí)鐘-CLOCK
chrono庫定義了三種不同的時(shí)鐘:
std::chrono::system_clock: 依據(jù)系統(tǒng)的當(dāng)前時(shí)間 (不穩(wěn)定) std::chrono::steady_clock: 以統(tǒng)一的速率運(yùn)行(不能被調(diào)整) std::chrono::high_resolution_clock: 提供最高精度的計(jì)時(shí)周期(可能是steady_clock或者system_clock的typedef)
二、這三個(gè)時(shí)鐘有什么區(qū)別呢?
system_clock就類似Windows系統(tǒng)右下角那個(gè)時(shí)鐘,是系統(tǒng)時(shí)間。明顯那個(gè)時(shí)鐘是可以亂設(shè)置的。明明是早上10點(diǎn),卻可以設(shè)置成下午3點(diǎn)。
steady_clock則針對(duì)system_clock可以隨意設(shè)置這個(gè)缺陷而提出來的,他表示時(shí)鐘是不能設(shè)置的。
high_resolution_clock則是一個(gè)高分辨率時(shí)鐘。
這三個(gè)時(shí)鐘類都提供了一個(gè)靜態(tài)成員函數(shù)now()用于獲取當(dāng)前時(shí)間,該函數(shù)的返回值是一個(gè)time_point類型,
system_clock除了now()函數(shù)外,還提供了to_time_t()靜態(tài)成員函數(shù)。用于將系統(tǒng)時(shí)間轉(zhuǎn)換成熟悉的std::time_t類型,得到了time_t類型的值,在使用ctime()函數(shù)將時(shí)間轉(zhuǎn)換成字符串格式,就可以很方便地打印當(dāng)前時(shí)間了。
#include<iostream>
#include<vector>
#include<string>
#include<ctime>//將時(shí)間格式的數(shù)據(jù)轉(zhuǎn)換成字符串
#include<chrono>
using namespace std::chrono;
using namespace std;
int main()
{
//獲取系統(tǒng)的當(dāng)前時(shí)間
auto t = system_clock::now();
//將獲取的時(shí)間轉(zhuǎn)換成time_t類型
auto tNow = system_clock::to_time_t(t);
//ctime()函數(shù)將time_t類型的時(shí)間轉(zhuǎn)化成字符串格式,這個(gè)字符串自帶換行符
string str_time = std::ctime(&tNow);
cout<<str_time;
return 0;
}三、持續(xù)的時(shí)間 - duration
td::chrono::duration<int,ratio<60,1>> ,表示持續(xù)的一段時(shí)間,這段時(shí)間的單位是由ratio<60,1>決定的,int表示這段時(shí)間的值的類型,函數(shù)返回的類型還是一個(gè)時(shí)間段duration
std::chrono::duration<double,ratio<60,1>>
由于各種時(shí)間段(duration)表示不同,chrono庫提供了duration_cast類型轉(zhuǎn)換函數(shù)。
duration_cast用于將duration進(jìn)行轉(zhuǎn)換成另一個(gè)類型的duration。
duration還有一個(gè)成員函數(shù)count(),用來表示這一段時(shí)間的長度
#include<iostream>
#include<string.h>
#include<chrono>
using namespace std::chrono;
using namespace std;
int main()
{
auto start = std::chrono::steady_clock::now();
for(int i=0;i<100;i++)
cout<<"nice"<<endl;
auto end = std::chrono::steady_clock::now();
auto tt = std::chrono::duration_cast<microseconds>(end - start);
cout<<"程序用時(shí)="<<tt.count()<<"微秒"<<endl;
return 0;
}四、時(shí)間點(diǎn) - time_point
std::chrono::time_point 表示一個(gè)具體時(shí)間,如上個(gè)世紀(jì)80年代、你的生日、今天下午、火車出發(fā)時(shí)間等,只要它能用計(jì)算機(jī)時(shí)鐘表示。鑒于我們使用時(shí)間的情景不同,這個(gè)time point具體到什么程度,由選用的單位決定。一個(gè)time point必須有一個(gè)clock計(jì)時(shí)
設(shè)置一個(gè)時(shí)間點(diǎn):
std::time_point<clock類型> 時(shí)間點(diǎn)名字
//設(shè)置一個(gè)高精度時(shí)間點(diǎn)
std::time_point<high_resolution_clock> high_resolution_clock::now();//設(shè)置系統(tǒng)時(shí)鐘 std::chrono::time_point<std::chrono::system_clock> now=std::chrono::system_clock::now();
另一個(gè)實(shí)例:
#define _CRT_SECURE_NO_WARNINGS //localtime()需要這個(gè)宏
#include<iostream>
#include<chrono>
#include<vector>
#include<string>
#include<algorithm>
//#include<stdio.h>
#include<iomanip> //put_time需要的頭文件
#include<sstream>
// template <class _Rep>
// struct treat_as_floating_point : is_floating_point<_Rep> {}; // tests for floating-point type
// template <class _Rep>
// _INLINE_VAR constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value;
// // STRUCT TEMPLATE duration_values
// template <class _Rep>
// struct duration_values { // gets arithmetic properties of a type
// _NODISCARD static constexpr _Rep zero() noexcept {
// // get zero value
// return _Rep(0);
// }
// _NODISCARD static constexpr _Rep(min)() noexcept {
// // get smallest value
// return numeric_limits<_Rep>::lowest();
// }
// _NODISCARD static constexpr _Rep(max)() noexcept {
// // get largest value
// return (numeric_limits<_Rep>::max)();
// }
// };
//時(shí)間長度
void Func1(){
//chrono重載了各種運(yùn)算符
std::chrono::hours c1(1); //1小時(shí)
std::chrono::minutes c2(60); //60分鐘
std::chrono::seconds c3(60*60); //60*60s
std::chrono::milliseconds c4(60*60*1000); //60*60*1000毫秒
std::chrono::microseconds c5(60*60*1000*1000); //微秒 溢出
std::chrono::nanoseconds c6(60*1000*1000*1000);//納秒 溢出
if(c1==c2){
std::cout<<"c1==c2"<<std::endl;
}
if(c1==c3){
std::cout<<"c1==c3"<<std::endl;
}
if(c2==c3){
std::cout<<"c2==c3"<<std::endl;
}
//獲取時(shí)鐘周期的值,返回的是int整數(shù)
std::cout<<"c1= "<<c1.count()<<std::endl;
std::cout<<"c2= "<<c2.count()<<std::endl;
std::cout<<"c3= "<<c3.count()<<std::endl;
std::cout<<"c4= "<<c4.count()<<std::endl;
std::chrono::seconds c7(1); //1秒
std::chrono::milliseconds c8(1*1000); //1000毫秒;1s
std::chrono::microseconds c9(1*1000*1000); //1000*1000微秒 1s
std::chrono::nanoseconds c10(1*1000*1000*1000);//1000*1000*1000納秒 1s;
std::cout<<c7.count()<<std::endl;
std::cout<<c8.count()<<std::endl;
std::cout<<c9.count()<<std::endl;
std::cout<<c10.count()<<std::endl;
}
//系統(tǒng)時(shí)間
/**
* @brief
*
* system_clock 類支持了對(duì)系統(tǒng)時(shí)鐘的訪問, 提供了三個(gè)靜態(tài)成員函數(shù):
返回當(dāng)前時(shí)間的時(shí)間點(diǎn)。
static std::chrono::time_point<std::chrono::system_clock> now() noexcept;
將時(shí)間點(diǎn) time_point 類型轉(zhuǎn)換為 std::time_t 類型。
static std::time_t to_time_t( const time_point& t ) noexcept;
將 std::time_t 類型轉(zhuǎn)換為時(shí)間點(diǎn) time_point 類型。
static std::chrono::system_clock::time_point from_time_t( std::time_t t ) noexcept;
*/
void Func2(){
//靜態(tài)成員函數(shù) static std::chrono::time_point<std::chrono::system_clock> now() noexcept
//這些都可以簡(jiǎn)寫用auto now=std::chrono::system_clock()::now()接收
//1、靜態(tài)成員函數(shù) static std::chrono::system_clock::now()用來獲取系統(tǒng)時(shí)間,C++時(shí)間
std::chrono::time_point<std::chrono::system_clock> now=std::chrono::system_clock::now();
//2、靜態(tài)成員函數(shù) static std::chrono::system_clock::to_time_t()把C++系統(tǒng)時(shí)間轉(zhuǎn)換為time_t (utc時(shí)間)
time_t t_now=std::chrono::system_clock::to_time_t(now);
//3、std::localtime()函數(shù)把time_t時(shí)間轉(zhuǎn)換為本地時(shí)間(北京時(shí)間)
// std::localtime()不是線程安全的,VS用localtime_t()代替,linux用local_time_r()代替
//tm結(jié)構(gòu)體
tm* tm_now=localtime(&t_now);
//格式化輸出tm結(jié)構(gòu)體中的成員
std::cout<<std::put_time(tm_now,"%Y-%m-%d %H:%M:%S")<<std::endl;
std::cout<<std::put_time(tm_now,"%Y-%m-%d")<<std::endl;
std::cout<<std::put_time(tm_now,"%H:%M:%S")<<std::endl;
//但是通常C++一般不打印出時(shí)間,而是把時(shí)間存儲(chǔ)到一個(gè)字符串中
std::stringstream ss; //創(chuàng)建stringstream對(duì)象 ss,需要包含<sstream>頭文件
ss<<std::put_time(tm_now,"%Y-%m-%d %H:%M:%S");
std::string time_str=ss.str();
std::cout<<time_str<<std::endl;
}
// struct steady_clock { // wraps QueryPerformanceCounter
// using rep = long long;
// using period = nano;
// using duration = nanoseconds;
// using time_point = chrono::time_point<steady_clock>;
// static constexpr bool is_steady = true;
// _NODISCARD static time_point now() noexcept { // get current time
// const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot
// const long long _Ctr = _Query_perf_counter();
// static_assert(period::num == 1, "This assumes period::num == 1.");
// // Instead of just having "(_Ctr * period::den) / _Freq",
// // the algorithm below prevents overflow when _Ctr is sufficiently large.
// // It assumes that _Freq * period::den does not overflow, which is currently true for nano period.
// // It is not realistic for _Ctr to accumulate to large values from zero with this assumption,
// // but the initial value of _Ctr could be large.
// const long long _Whole = (_Ctr / _Freq) * period::den;
// const long long _Part = (_Ctr % _Freq) * period::den / _Freq;
// return time_point(duration(_Whole + _Part));
// }
// };
// using high_resolution_clock = steady_clock;
// } // namespace chrono
//計(jì)時(shí)器 steady_clock 類相當(dāng)于秒表,操作系統(tǒng)只要啟動(dòng)就會(huì)進(jìn)行時(shí)間的累加,常用于耗時(shí)的統(tǒng)計(jì)(精確到納秒) 。
void Func3(){
//靜態(tài)成員函數(shù)std::chrono::steady_clock::now()獲取時(shí)間的開始點(diǎn)
std::chrono::time_point<std::chrono::steady_clock> start=std::chrono::steady_clock::now();
//auto start=std::chrono::steady_clock::now();
//執(zhí)行一些代碼,消耗時(shí)間
std::vector<std::string> vec1{"banana","apple","pear"};
std::for_each(vec1.begin(),vec1.end(),[&vec1](std::string str){
std::cout<<str<<" ";
});
std::cout<<std::endl;
//靜態(tài)成員函數(shù)std::chrono::steady_clock::now()獲取時(shí)間的結(jié)束點(diǎn)
auto end=std::chrono::steady_clock::now();
//計(jì)算消耗的時(shí)間,單位是納秒
auto dt=end-start;
std::cout<<"耗時(shí): "<<dt.count()<<"納秒 ("<<(double)dt.count()/(1000*1000*1000)<<"秒) "<<std::endl;
}
int main(int argc,char* argv[]){
Func1();
Func2();
Func3();
return 0;
}輸出結(jié)果:
PS D:\時(shí)間操作 chrono 庫\bin\Debug> .\main.exe
c1==c2
c1==c3
c2==c3
c1= 1
c2= 60
c3= 3600
c4= 3600000
1
1000
1000000
1000000000
2023-01-04 22:32:43
2023-01-04
22:32:43
2023-01-04 22:32:43
banana apple pear
耗時(shí): 733400納秒 (0.0007334秒)
PS D:\時(shí)間操作 chrono 庫\bin\Debug>
到此這篇關(guān)于C++11計(jì)時(shí)器:chrono庫介紹的文章就介紹到這了,更多相關(guān)C++ chrono計(jì)時(shí)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C++日期與時(shí)間 chrono庫介紹及使用教程
- C/C++時(shí)間庫chrono的使用總結(jié)
- 深入理解C++中std::chrono庫的使用
- 關(guān)于C++使用std::chrono獲取當(dāng)前秒級(jí)/毫秒級(jí)/微秒級(jí)/納秒級(jí)時(shí)間戳問題
- c++11 chrono全面解析(最高可達(dá)納秒級(jí)別的精度)
- C++11中的時(shí)間庫std::chrono(引發(fā)關(guān)于時(shí)間的思考)
- C++中Boost.Chrono時(shí)間庫的使用方法
- C++算法計(jì)時(shí)器的實(shí)現(xiàn)示例
- C++實(shí)現(xiàn)統(tǒng)計(jì)代碼運(yùn)行時(shí)間計(jì)時(shí)器的簡(jiǎn)單實(shí)例
相關(guān)文章
C語言實(shí)現(xiàn)超市信息管理系統(tǒng)
C++實(shí)現(xiàn)選擇排序(selectionSort)
構(gòu)造函數(shù)不能聲明為虛函數(shù)的原因及分析
C語言學(xué)習(xí)之條件和?if...else語句詳解
C語言實(shí)現(xiàn)可保存的動(dòng)態(tài)通訊錄的示例代碼
Qt實(shí)現(xiàn)定時(shí)器的兩種方法分享

