C/C++で高精度に実行時間を測定する方法(chronoライブラリ活用)
プログラムのパフォーマンスを正確に評価するには、処理にかかる時間を高精度に測定することが重要です。C++では、標準ライブラリのchronoを利用することで、ナノ秒単位という非常に高い精度で実行時間を計測できます。
chronoライブラリの高解像度クロック
chronoライブラリには、高解像度クロック(std::chrono::high_resolution_clock)が用意されています。このクロックはシステムが提供する最も精度の高い時計を使用するため、ナノ秒単位での時間計測が可能です。
基本的な測定の流れは以下のとおりです。
- 処理開始直前に現在時刻を取得する
- 処理終了直後に再度現在時刻を取得する
- 両者の差分を計算して経過時間を求める
ここでは、時間のかかる処理の代わりとして、空のループ(何もしない繰り返し処理)を使用し、意図的に時間を消費させています。
サンプルコード
#include <iostream>
#include <chrono>
typedef std::chrono::high_resolution_clock Clock;
main() {
// 開始時刻を取得
auto start_time = Clock::now();
// 空のループで時間を消費する
for (int i = 0; i < 200000000; i++) {
;
}
// 終了時刻を取得
auto end_time = Clock::now();
// 差分をナノ秒に変換して表示
std::cout << "Time difference: "
<< std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count()
<< " nanoseconds" << std::endl;
}
実行結果
Time difference: 536395307 nanoseconds
コードの解説
Clock::now()
Clock::now()は、呼び出した瞬間の時刻を表すtime_pointオブジェクトを返します。開始時と終了時の2回呼び出すことで、その間の経過時間を求める基準となります。
duration_castによる単位変換
end_time - start_timeの結果はduration型として得られますが、そのままでは内部表現の単位が不明確です。std::chrono::duration_cast<std::chrono::nanoseconds>を使うことで、差分を明示的にナノ秒単位へ変換できます。同様の方法で、microseconds(マイクロ秒)やmilliseconds(ミリ秒)への変換も可能です。
count()メソッド
count()は、durationオブジェクトが保持する数値を整数値として取り出すメソッドです。これにより、経過時間を画面に表示できます。
注意点
- このコードはC++11以降の機能を使用しているため、コンパイル時にC++11以上の規格を指定してください(例:
g++ -std=c++11 sample.cpp)。 main()の戻り値の型は省略せずにint main()と明示するのが現代的な書き方です。- 計測結果は実行環境やマシンの負荷によって変動します。正確な比較を行う場合は、複数回測定して平均を取ることをおすすめします。
このようにchronoライブラリを使えば、短時間の処理でもミリ秒単位では捉えきれない細かい差を正確に測定でき、ボトルネックの特定や最適化の効果検証に役立ちます。
-
C/C++で実装するバークレーアルゴリズム――分散システムの時刻同期を徹底解説
バークレーアルゴリズムとは バークレーアルゴリズム(Berkeleys Algorithm)は、分散システムにおいて各ノードの時計を同期させるために用いられるアルゴリズムです。特に、以下のような状況にあるシステムで有効とされています。 マシンに正確な時刻源が存在しない場合 ネットワークやマシンにUTCサーバーが用意されていない場合 分散システムとは、物理的に離れた場所に配置された複数のノードが、ネットワークを介して相互に接続されたシステムのことを指します。各ノードの時計は独立して動作しているため、誤差が生じやすく、何らかの同期機構が必要になります。 バークレーアルゴリズムの仕組み このア
-
C++で解く「3nスライスのピザ」問題 ― 動的計画法でスライスの合計を最大化する方法
問題の概要 大きさがまちまちの 3n 個のスライスからなるピザがあるとします。私と友人2人は、次のルールに従ってピザを取っていきます。 私が任意のスライスを1枚選びます。 友人のAmalは、私が選んだスライスの反時計回り方向に隣接するスライスを取ります。 友人のBimalは、私が選んだスライスの時計回り方向に隣接するスライスを取ります。 ピザのスライスがなくなるまで、この手順を繰り返します。 各スライスの大きさは、時計回りの順に並べた環状配列 slices として与えられます。求めるのは、私が手にできるスライスの大きさの合計の最大値です。 入出力例 入力が [9, 8, 6, 1, 1,