Next, my turn.

ロボットエンジニアのブログです.#Robotics #C++ #VBA #Python #Azure #MATLAB #ROS #Vim #RaspberryPi

【c++】処理時間を計測する(ラップタイム機能つき)

導入

画像処理や通信に要する処理時間を計測するサンプルプログラムをご紹介します。

このプログラムを使用すると、処理前後の経過時間や、ラップタイムを計測することができます。

目次

  1. サンプルプログラム
  2. 出力結果
  3. 使い方
  4. 解説

サンプルプログラム

#include <iostream>
#include <vector>
#include <windows.h>
using namespace std;

const static int LAP_BUFF_SIZE = 5;

class StopWatch {
private:
    double         start;      //スタート時のシステム起動からの相対時間
    double         end;        //スタートからストップまでの時間
    vector<double>  lap;        //スタートからラップまでの時間
    bool           is_started; //true: 時間カウント中, false: 時間カウントしていない
    double         Get(void);  //システム起動からの相対時間を取得
public:
    StopWatch();
    ~StopWatch();
    void   Start(void);
    bool   Lap(void);
    bool   Stop(void);
    void   Print(void);
};

StopWatch::StopWatch()
    :start(0.0), 
     end(0.0), 
     is_started(false)
{
}

StopWatch::~StopWatch()
{
}

void StopWatch::Start() {
    //Clear time
    this->end = 0.0;
    this->lap.clear();
    this->lap.shrink_to_fit();

    this->start = this->Get();
    this->is_started = true;
    return;
}

bool StopWatch::Lap() {
    double now; //Relative time from system boot

    if (this->is_started == false) {
        cerr << "Lap() called before SetStart()" << endl;
        return false;
    }

    if (this->lap.size() < LAP_BUFF_SIZE) {
        now = this->Get();
        this->lap.push_back(now - this->start);
    }
    else {
        cerr << "Lap time buffer size exceeded the limit" << endl;
    }
    return true;
}

bool StopWatch::Stop() {
    double now; //Relative time from system boot

    if (is_started == false) {
        cerr << "Stop() called before SetStart()" << endl;
        return false;
    }

    now = this->Get();
    this->end = now - this->start;
    return true;
}

double StopWatch::Get(void) {
    double sys_time;
    static LARGE_INTEGER freq;
    LARGE_INTEGER time;

    if (freq.QuadPart == 0) {
        QueryPerformanceFrequency(&freq);
    }
    QueryPerformanceCounter(&time);
    sys_time = (double)time.QuadPart / (double)freq.QuadPart;
    return sys_time;
}

void StopWatch::Print() {
    for (unsigned int i = 0; i < this->lap.size(); i++) {
        cout << "Lap(" << i + 1 << ") : " << this->lap[i] << " [s]" << endl;
    }
    cout << "Time : " << this->end << " [s]" << endl;
    return;
}

int main() {
    StopWatch sw;

    sw.Start();

    //--------------------------------
    Sleep(500); //0.5s
    //--------------------------------
    sw.Lap();

    //--------------------------------
    Sleep(500); //0.5s
    //--------------------------------

    sw.Stop();
    sw.Print();

    getchar();
    return 0;
}

出力結果

スタートしてから一回目のラップタイムは「0.502758秒」、ストップ時の時間は「1.00516秒」となりました。

PCの性能によっては、異なる秒数が表示されるかもしれません。

Lap(1) : 0.502758 [s]
Time : 1.00516 [s]

使い方

StopWatch::Start()

時間計測を開始します。ストップウォッチのSTARTボタンに該当します。

時間計測を開始すると、過去のラップタイムはすべて初期化されます。

StopWatch::Lap()

ラップタイムを計測します。ストップウォッチのLAPボタンに該当します。

StopWatch::Stop()

時間計測を停止します。ストップウォッチのSTOPボタンに該当します。

StopWatch::Print()

計測した時間情報(STARTボタンが押された時間を基準に、LAPボタン、STOPボタンが押された時間)を表示します。

解説

このプログラムでは、Windows OSのパフォーマンス カウンターAPIを使用して、時間を計算しています。

まとめ

このようなプログラムを使用することによって、処理性能を調査したり、処理のボトルネックを調べたりすることができます。

下記にGitHubのリンクを貼っておりますので、ぜひご活用ください。

最後まで読んでいただき、ありがとうございました!