C++ でタイマーを使用する
この記事では、C++ でタイマーを使用する方法の複数の方法を示します。
C++ でタイマを実装するには clock()
関数を使用する
関数 clock()
は、プログラムのプロセッサ時間を取得する POSIX 準拠のメソッドです。この関数は整数値を返しますが、これをマクロで定義された CLOCKS_PER_SEC
という定数で除算して数秒に変換する必要があります。
以下のサンプルコードは、int
配列の最大値を求めるための 2つの関数を実装したものです。関数 max_index
は要素のインデックスに基づいて検索を行い、max_value
は値に基づいて検索を行います。目的は、1,000,000
個の乱数整数で埋め尽くされた配列 1,000,000
の中から int
の最大値を求めるのにどれだけの時間を費やしたかを計算することです。
関数 clock()
は max_index
の呼び出しの前と呼び出しの後の 2 回呼び出していることに注意してください。この時間計測スキームは、時間を取得する特定の関数を気にせずに一般的に利用できます。この場合、(ハードウェアシステムにもよりますが)max_value
の方がインデックスベースの検索よりもわずかに高速であることがわかります。しかし、これらの最大検索アルゴリズムは O(N)
の複雑さを持っていることに注意してください。
#include <chrono>
#include <iostream>
using std::cout;
using std::endl;
int max_index(int arr[], int size) {
size_t max = 0;
for (int j = 0; j < size; ++j) {
if (arr[j] > arr[max]) {
max = j;
}
}
return arr[max];
}
int max_value(int arr[], int size) {
int max = arr[0];
for (int j = 0; j < size; ++j) {
if (arr[j] > max) {
max = arr[j];
}
}
return max;
}
constexpr int WIDTH = 1000000;
int main() {
clock_t start, end;
int max;
int *arr = new int[WIDTH];
std::srand(std::time(nullptr));
for (size_t i = 0; i < WIDTH; i++) {
arr[i] = std::rand();
}
start = clock();
max = max_index(arr, WIDTH);
end = clock();
printf("max_index: %0.8f sec, max = %d\n",
((float)end - start) / CLOCKS_PER_SEC, max);
start = clock();
max = max_value(arr, WIDTH);
end = clock();
printf("max_value: %0.8f sec, max = %d\n",
((float)end - start) / CLOCKS_PER_SEC, max);
exit(EXIT_SUCCESS);
}
出力:
max_value: 0.00131400 sec, max = 2147480499
max_value: 0.00089800 sec, max = 2147480499
C++ でタイマーを実装するために gettimeofday
関数を使用する
gettimeofday
は Linux ベースのシステムにおける精度の高い時刻検索関数であり、C++ のソースコードからも呼び出すことができます。この関数は時刻とタイムゾーンのデータを取得するために設計されたものであるが、後者はいつの間にか陳腐化しており、第 2 引数には有効なタイムゾーンの struct
の代わりに nullptr
を指定する必要があります。gettimeofday
は、秒を表す tv_sec
とマイクロ秒を表す tv_usec
の 2つのデータメンバを含む timeval
という特別な構造体
にタイミングデータを格納します。
原則として、関数 gettimeofday
を呼び出す前に、2つの timeval
構造体を宣言して初期化します。関数が呼ばれると、gettimeofday
の戻り値が 0
であれば、データは対応する struct
に正常に格納されるはずです。それ以外の場合は、-1
の値を返すことで失敗を示します。構造体にデータを格納した後は、時間の共通単位値に変換する必要があることに注意してください。このサンプルコードでは、時間を秒単位で返す関数 time_diff
を実装しており、必要に応じてコンソールに出力することができます。
#include <sys/time.h>
#include <ctime>
#include <iostream>
using std::cout;
using std::endl;
int max_index(int arr[], int size) {
size_t max = 0;
for (int j = 0; j < size; ++j) {
if (arr[j] > arr[max]) {
max = j;
}
}
return arr[max];
}
int max_value(int arr[], int size) {
int max = arr[0];
for (int j = 0; j < size; ++j) {
if (arr[j] > max) {
max = arr[j];
}
}
return max;
}
float time_diff(struct timeval *start, struct timeval *end) {
return (end->tv_sec - start->tv_sec) + 1e-6 * (end->tv_usec - start->tv_usec);
}
constexpr int WIDTH = 1000000;
int main() {
struct timeval start {};
struct timeval end {};
int max;
int *arr = new int[WIDTH];
std::srand(std::time(nullptr));
for (size_t i = 0; i < WIDTH; i++) {
arr[i] = std::rand();
}
gettimeofday(&start, nullptr);
max = max_index(arr, WIDTH);
gettimeofday(&end, nullptr);
printf("max_index: %0.8f sec, max = %d\n", time_diff(&start, &end), max);
gettimeofday(&start, nullptr);
max = max_value(arr, WIDTH);
gettimeofday(&end, nullptr);
printf("max_value: %0.8f sec, max = %d\n", time_diff(&start, &end), max);
exit(EXIT_SUCCESS);
}
出力:
max_value: 0.00126000 sec, max = 2147474877
max_value: 0.00093900 sec, max = 2147474877