C++ でタイマーを使用する

胡金庫 2023年10月12日
  1. C++ でタイマを実装するには clock() 関数を使用する
  2. C++ でタイマーを実装するために gettimeofday 関数を使用する
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
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ Timer