何か処理を実行する時に経過時間を取得したい場合や、タイムスタンプをカウンター的に使いたい時に重宝するstd::chronoライブラリ。
仕事でも登場回数多いけど、意外と忘れちゃう事が多いので、備忘録を兼ねてまとめておきます。
std::chronoで経過時間を取得
現在時刻を取得できる「std::chrono::system_clock::now()」を時間計測したい処理の前後に配置して、時間の差を求めます。
#include <chrono>
void main()
{
auto start = std::chrono::system_clock::now(); // 開始時刻
// ここで計測したい処理を実行する
{ ....... }
auto end = std::chrono::system_clock::now(); // 完了時刻
auto millisec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}
5行目、10行目の「std::chrono::systen_clock::now()」で現在時刻を取得して保存しています。
12行目で「完了時間 ー 開始時間」の経過時間を求めて、duration_castでミリ秒に変換して、countで整数値に変換しています。
時間の逆行が不安な場合は、「system_clock」ではなく「steady_clock」を使用しよう!
使い方は同じなので「system_clock」の部分を「steady_clock」に変えるだけ
std::chronoのsystem_clockをカウンター的に使う
std::chronoのsystem_clockを使ってエポックからの経過時間を取得して、カウンターの様にデータセットします。
サンプルとして、forループでvectorにデータをセットしていきます。
#include <vector>
#include <chrono>
void main() {
std::vector<uint64_t> timestmp;
for (int i = 0; i < 100; ++i) {
auto tp = std::chrono::system_clock::now();
timestmp.push_back(std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count();
}
}
8行目の「system_clock::now()」は経過時間を求めた時と同じで現在時刻を取得しています。
9行目の「tp.time_since_epoch()」でエポックからの経過時間を取得しています。エポックからの経過時間とは「現在時刻 ー エポック時刻」なので、経過時間取得時に「end - start」ってやってた部分が、エポックからの経過時間だと「time_since_epoch」で求められます。
エポックについて
system_clockのエポック(初期時間)は以下になっています。
- C++17以前:エポックは未規定だが、殆どの場合UNIX時間(1970年1月1日0時0分0秒)
- C++20以降:エポックは必ずUNIX時間(1970年1月1日0時0分0秒)
こっちも時間の逆行したくない場合は、「system_clock」を「steady_clock」に変更しよう!
おまけ
「system_clock」はシステムの時間を表現するクロックなので、コンピューターの時間に影響をうけます。
「steady_clock」は現実と同様に、決して逆行することのない時間を表現するクロックです。コンピューターの時間にも影響を受けません。
他にも、UTC(協定世界時)を表現した「utc_clock」や、TAI(国際原子時)を表現した「tai_clock」等があります。
基本的には、「system_clock」ぐらいしか使わないでしょう。
今回は、ここまで!