ネタ元
// Stopwatch.hpp
// ネタ元:https://takap-tech.com/entry/2019/05/13/235416
#pragma once
// #pragma execution_character_set("utf-8")
#include <chrono>
#include <memory>
namespace diagnostics
{
/**
* C#の System.Stopwatch クラスっぽい動きをする時間測定クラス
*/
class Stopwatch
{
// 動作しているかのフラグ
// true : 動作中 / false : 停止中
bool isRunning = false;
// 測定開始時刻
std::chrono::system_clock::time_point begin;
// 測定開始時刻
std::chrono::system_clock::time_point end;
// 合計時間
std::chrono::nanoseconds elapsed;
Stopwatch() = default; // CreateNew or StartNewで作って!
public:
// 意味ないと思うのでmove以外禁止
~Stopwatch() = default;
Stopwatch(const Stopwatch&) = delete;
Stopwatch& operator=(const Stopwatch) = delete;
Stopwatch(Stopwatch&&) = default;
Stopwatch& operator=(Stopwatch&&) = default;
bool getIsRunning() { return this->isRunning; }
// 任意の型で計測時間を取り出す
// Tempalte
// Unit : 取得したい時間の型
// Ratio : 時間の単位
template <typename Unit, class Ratio>
Unit getElapsed()
{
if (this->isRunning)
{
return std::chrono::duration_cast<std::chrono::duration<Unit, Ratio>>(
std::chrono::system_clock::now() - this->begin).count(); // TooLong!!
}
else
{
return std::chrono::duration_cast<std::chrono::duration<Unit, Ratio>>(this->elapsed).count();
}
}
// 経過時間を秒の倍精度浮動小数点として取り出す
double getElapsedSeconds()
{
return this->getElapsed<double, std::ratio<1>>();
}
// 経過時間をミリ秒の倍精度浮動小数点として取り出す
double getElapsedMilliseconds()
{
return this->getElapsed<double, std::milli>();
}
// 経過時間をナノ秒として取り出す
long long getElapsedNanoseconds()
{
return this->getElapsed<long long, std::nano>();
}
void reset()
{
elapsed = std::chrono::nanoseconds(0);
begin = end = std::chrono::system_clock::now();
}
void restart()
{
this->reset();
this->start();
}
void start()
{
if (this->isRunning)
{
return;
}
this->isRunning = true;
begin = end = std::chrono::system_clock::now();
}
void stop()
{
if (!this->isRunning)
{
return;
}
this->isRunning = false;
end = std::chrono::system_clock::now();
this->elapsed = this->elapsed + std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
}
static std::unique_ptr<Stopwatch> createNew()
{
std::unique_ptr<Stopwatch> sw(new Stopwatch());
return sw;
}
static std::unique_ptr<Stopwatch> startNew()
{
auto sw = createNew();
sw->start();
return sw;
}
};
}
使い方
void Foo()
{
// 時間測定を開始した状態でインスタンスを作成
auto sw1 = diagnostics::Stopwatch::startNew();
// ~~何らかの処理~~
sw1->stop(); // 時間測定を停止
// 結果を取得
cout << "Elapsed(nano sec) = " << sw1->getElapsedNanoseconds() << endl;
cout << "Elapsed(milli sec) = " << sw1->getElapsedMilliseconds() << endl;
cout << "Elapsed(sec) = " << sw1->getElapsedSeconds() << endl;
// > Elapsed(nano sec) = 74255700
// > Elapsed(milli sec) = 74.2557
// > Elapsed(sec) = 0.0742557
sw1->reset(); // リセットして計測を再開
sw1->start();
}