C++標準ライブラリで処理時間の計測

通信速度を表示する機能を作るときや、重い処理を実装したときに目安の終了時間を表示する機能を作るときなど、特定の処理にかかった処理時間を計測したいことがあります。

C++標準ライブラリで処理時間を計測するコード例を紹介します。

目次

実装例

C++11で日時に関する機能が多く追加されています。C++標準ライブラリのコードだけでも処理時間を計測できます。

C++標準ライブラリを使って処理時間を計測するには、chronoライブラリを使用します。

次のコードはsomething()関数の処理時間を計測し、ミリ秒単位と秒単位でコンソールに出力するコードです。

#include <iostream>
#include <chrono>
#include <thread>

void something()
{
    // 2.5秒スリープする
    std::this_thread::sleep_for(std::chrono::milliseconds(2500));
}

int main(int argc, const char * argv[])
{
    // 開始日時を取得する
    auto start = std::chrono::system_clock::now();
    
    // 計測したい処理
    something();
    
    // 終了日時を取得する
    auto end = std::chrono::system_clock::now();
    
    // end - start をミリ秒単位で計算する
    std::chrono::duration<double, std::milli> elapsed = end - start;
    
    // end - start を秒単位で計算する
    std::chrono::duration<double> elapsed2 = end - start;
    
    // 結果をコンソールに出力する
    std::cout << elapsed.count() << "ms" << std::endl;
    std::cout << elapsed2.count() << "s" << std::endl;
    
    return 0;
}

私の環境では次のように出力されました。

2504.99ms
2.505s

現在日時の取得

現在日時を取得するにはstd::chrono::system_clock:now()メソッドを使用します。このメソッドを使用するにはchronoファイルをインクルードします。

スリープ

実行中のスレッドをスリープさせるには、std::this_thread::sleep_for()メソッドを使用します。このメソッドは次のように定義されています。また、使用するにはthreadファイルをインクルードします。

template< class Rep, class Period >
void sleep_for( const std::chrono::duration<Rep, Period>& sleep_duration );

引数にスリープ時間を指定します。型はstd::chrono::durationです。コード例を見れば2500ミリ秒を指定しているということが一目で分かります。コード例のように可読性を高めるため、次のような型が定義されています。

  • std::chrono::nanoseconds
  • std::chrono::microseconds
  • std::chrono::milliseconds
  • std::chrono::seconds
  • std::chrono::minutes
  • std::chrono::hours
  • std::chrono::days (C++20以降)
  • std::chrono::weeks (C++20以降)
  • std::chrono::months (C++20以降)
  • std::chrono::years (C++20以降)

スリープ時間として使うのは、先頭4つくらいまででしょう。

処理時間の計算

処理時間は処理の完了まで必要な時間です。つまり、処理を始める直前に開始時間を取得し、終了直後に終了時間を取得し、その2つの時間の差が処理時間です。

std::chrono::system_clock::now()メソッドの戻り値の型はstd::chrono::time_point<std::chrono::system_clock>です。マイナス演算子がテンプレートを使って実装されており、戻り値の型を使って、どのような単位で差を取得したいかを指定できます。

std::chrono::duration<double>を指定すると、秒単位で値を取得できます。実際のスカラー値はcount()メソッドで取得できます。count()メソッドの戻り値の型はテンプレートで指定しているdoubleです。

std::chrono::duration<double, std::milli>を指定すると、ミリ秒単位で取得できます。std::milliというテンプレート引数でミリ秒を指定しています。処理時間で使用する可能性があるのは、次のような型があります。

  • std::nano
  • std::micro
  • std::milli

あまりに短い時間の計測になると、タイマー精度の問題があるので、別の高精度タイマーを使う必要があります。ここで省略します。

著書紹介

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。Appleプラットフォーム向けの開発を専門としているソフトウェアエンジニア。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, Medium, LinkedIn
-
Representative of RK Kaihatsu. Software Engineer Specializing in Development for the Apple Platform. Specializing in contract software development, technical writing, and serving as a tech workshop lecturer. note, Medium, LinkedIn

目次