C++ STL で関数の実行時間を測定する
-
関数の実行時間を測定するには、
std::chrono::high_resolution_clock::now
とstd::chrono::duration_cast<std::chrono::seconds>
を使用する -
関数の実行時間を測定するには、
std::chrono::high_resolution_clock::now
とstd::chrono::duration<double, std::milli>
を使用する
この記事では、C++ で関数の実行時間を測定する方法に関する複数の方法を示します。
関数の実行時間を測定するには、std::chrono::high_resolution_clock::now
と std::chrono::duration_cast<std::chrono::seconds>
を使用する
std::chrono
名前空間は、C++ STL ライブラリによって提供されるすべての日付と時刻のユーティリティを統合します。後者は複数のクロック実装を提供し、そのうちの 1つは最小のティック周期を持つクロックに対応する std::chrono::high_resolution_clock
です。ただし、このクロックはハードウェアプラットフォームに依存し、複数の標準ライブラリの実装も異なるため、コンパイラのドキュメントを読んで、これが問題の要件に適していることを確認することをお勧めします。関数の実行時間を測定するためのアイデアは、指定されたクロックから現在の時刻を関数呼び出しの前と後の 2 回取得し、値の差を計算することです。現在の時刻は、now
組み込みメソッドを使用して取得されます。差が計算されたら、それは特定の時間単位で解釈される必要があります。これは、std::chrono::duration_cast
ユーティリティを使用して行われます。次の例では、結果を std::chrono::seconds
単位でキャストし、count
組み込み関数を使用して値を出力します。コード例の funcSleep
は、プログラムの実行を 3 秒間中断してから、制御を main
関数に戻すことに注意してください。
#include <chrono>
#include <iostream>
#include <thread>
using std::cout;
using std::endl;
void funcSleep() { std::this_thread::sleep_for(std::chrono::seconds(3)); }
int main() {
auto start = std::chrono::high_resolution_clock::now();
funcSleep();
auto end = std::chrono::high_resolution_clock::now();
auto int_s = std::chrono::duration_cast<std::chrono::seconds>(end - start);
std::cout << "funcSleep() elapsed time is " << int_s.count() << " seconds )"
<< std::endl;
return EXIT_SUCCESS;
}
出力:
funcSleep() elapsed time is 3 seconds
関数の実行時間を測定するには、std::chrono::high_resolution_clock::now
と std::chrono::duration<double, std::milli>
を使用する
時間の単位が整数値で保存された前のコードとは対照的に、次の例では、間隔値を浮動小数点数として std::chrono::duration <double、std::milli>に格納します。
オブジェクトを入力します。std::chrono::duration
は、時間間隔を表すための一般的なクラステンプレートです。最後に、間隔値は count
関数を使用して取得され、その時点で cout
ストリームに出力できます。
#include <chrono>
#include <iostream>
#include <thread>
using std::cout;
using std::endl;
void funcSleep() { std::this_thread::sleep_for(std::chrono::seconds(3)); }
int main() {
auto start = std::chrono::high_resolution_clock::now();
funcSleep();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> float_ms = end - start;
std::cout << "funcSleep() elapsed time is " << float_ms.count()
<< " milliseconds" << std::endl;
return EXIT_SUCCESS;
}
出力:
funcSleep() elapsed time is 3000.27 milliseconds
過去 2つの例では、ほとんど一定の時間がかかる関数を測定しましたが、同様のアプローチを使用して、特定のコードブロックの実行時間を計算できます。例として、次のスニペットは、実行にさらに可変間隔を必要とするランダム整数生成関数を示しています。今回は、両方の方法を使用して、ミリ秒の精度と秒で時間を表示していることに注意してください。
#include <chrono>
#include <iostream>
#include <thread>
using std::cout;
using std::endl;
constexpr int WIDTH = 1000000;
void generateNumbers(int arr[]) {
std::srand(std::time(nullptr));
for (size_t i = 0; i < WIDTH; i++) {
arr[i] = std::rand();
}
}
int main() {
int *arr = new int[WIDTH];
auto start = std::chrono::high_resolution_clock::now();
generateNumbers(arr);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> float_ms = end - start;
auto int_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::chrono::duration<long, std::micro> int_usec = int_ms;
std::cout << "generateNumbers() elapsed time is " << float_ms.count()
<< " ms "
<< "( " << int_ms.count() << " milliseconds )" << std::endl;
delete[] arr;
return EXIT_SUCCESS;
}
出力:
generateNumbers() elapsed time is 30.7443 ms ( 30 milliseconds )