性能測定
スループットを測る、つまりある処理の時間を測るのは、プログラムを書いている限りよくあることです。
- 製品性能が要件を満たしているかを確認する
- テスト項目に性能があるから
- 社外で性能がらみの不具合発生
いろいろなところで時間を測ることがありますので、各プログラミング言語でどうやって時間を計測するかを知っておくことは重要です。
今回はC++における洗練された方法を紹介します。
「プログラミングC++」を参照して記事を作成しました。
簡単な使い方
chronoの簡単な使い方です。chronoはC++11からの機能ですので、gccのオプションに-std=c++11を入れておきます。#include <chrono>して使用してください。
以下のように、steady_clock::now()で時刻を取得できます。終了時にsteady_clock::durationで経過時間を取得します。
// 測定開始 std::chrono::steady_clock::time_point t = std::chrono::steady_clock::now(); // 何らかの処理 // 測定終了 std::chrono::steady_clock::duration d = std::chrono::steady_clock::now() - t; // かかった時間をトレース出力 std::cout << "something took " << std::chrono::duration_cast<std::chrono::milliseconds>(d).count() << "ms" << std::endl;
時間をとっただけでなくトレース出力するのとセットと思います。上記はミリ秒で出力する方法です。
3種類のclock
上記ではsteady_clockを使いましたが、用途によって3種類用意されています。
迷ったらsteady_clockでよいと思います。※システムによっては、3つとも同じ定義である可能性もあります。
system_clock | システム時間。強制的に戻ったり進んだりする可能性あり。 |
steady_clock | 安定して時間が進む。間隔は一定。 |
high_resolution_clock | システムが測定できる最小の単位で測定。 |
時間同士の算術
上記ではtime_pointを引き算して時間を計算しました。
duration型にしてしまえば、4測演算可能です。
時間測定には引き算以外必要でないと思いますので、割愛します。
※time_pointでなく単なる数を掛けたりしようとすると単位変換する必要があり面倒です。
単位の揃え方
上記例ではミリ秒で出力しました。duration_castで単位を指定することができます。
- hours
- minutes
- seconds
- milliseconds
- mircroseconds
- nanoseconds
を使用することができます。
クラスにして使う
せっかくですのでクラスにしておきます。コンストラクタで計測開始。time()をコールした時点で計測終了としています。
※引数は文字列の方がよいかIDにするのがよいかは各エンジニアの趣味の問題ですので、両方載せておきます。IDは開始で入れるのか、終了で入れるのか、いろいろ好みがあると思いますので、後はお好みで。
class Timer { public: Timer(){ // 測定開始 t = std::chrono::steady_clock::now(); } void time(std::string msg){ // 測定終了 std::chrono::steady_clock::duration d = std::chrono::steady_clock::now() - t; // かかった時間をトレース出力 std::cout << "Operation " << msg << " " << std::chrono::duration_cast<std::chrono::milliseconds>(d).count() << "ms" << std::endl; return; } void time(int id){ time(std::to_string(id)); return; } private: std::chrono::steady_clock::time_point t; };
使うときは以下のようにして使用します。
// 測定開始 Timer t; // 何らかの処理 // 測定終了 t.time(1);
まとめ
C++の時間測定chronoについて解説しました。
コメント