アカベコマイリ

HEAR NOTHING SEE NOTHING SAY NOTHING

ネイティブアプリの速度計測

前に書いた.NET アプリの速度計測の補足。

Windows のネイティブ アプリにおける速度計測には Win32 API のパフォーマンスカウンターを使用する。実装としては QueryPerformanceCounter でカウンターの開始・終了値を取得し、その差分を QueryPerformanceFrequency から得た周波数 (更新頻度) で割ることになる。

せっかくなので、この処理を単純なクラスにしてみた。形は意図的に .NET の StopWatch クラスへ似せてある。

/**
 * 処理時間を計測する為のクラスです。
 */
class StopWatch {
public:
    /**
     * インスタンスの初期化を行います。
     */
    StopWatch() : m_isRunning(false), m_time(0) {
        this->Initialize();
    }

    /**
     * 計測を開始します。
     */
    void Start() {
        if (this->m_isRunning) { return; }

        this->m_isRunning = true;
        this->Initialize();
        this->m_time = 0;
        ::QueryPerformanceFrequency(&this->m_frequency);
        ::QueryPerformanceCounter(&this->m_begin);
    }

    /**
     * 計測を停止します。
     */
    void Stop() {
        if( !this->m_isRunning ) { return; }

        this->m_isRunning = false;

        LARGE_INTEGER end;
        ::ZeroMemory(&end, sizeof(LARGE_INTEGER));
        ::QueryPerformanceCounter(&end);

        this->m_time = static_cast<DWORD>((end.QuadPart - this->m_begin.QuadPart) * 1000 / this->m_frequency.QuadPart);
    }

    /**
     * 計測された時間をミリ秒単位で取得します。
     *
     * @return    処理時間。
     */
    DWORD ElapsedTime() {
        return this->m_time;
    }

private:
    /**
     * 処理時間を計測する為の初期化を行います。
     */
    void Initialize() {
        ::ZeroMemory(&this->m_frequency, sizeof(LARGE_INTEGER));
        ::ZeroMemory(&this->m_begin,     sizeof(LARGE_INTEGER));
    }

    bool m_isRunning;          //! 処理時間の計測が実行中である事を示す値。
    DWORD m_time;              //! 処理時間 ( ミリ秒単位 )。
    LARGE_INTEGER m_frequency; //! パフォーマンス カウンタの周波数。
    LARGE_INTEGER m_begin;     //! パフォーマンス カウンタの開始値。
};

このクラスは以下のように使用する。

/**
 * StopWatch クラスのテストを行います。
 */
void StopWatchTest() {
    StopWatch watch;
    watch.Start();
    ::Sleep(1000);
    watch.Stop();

    CString text;
    text.Format(_T( "処理時間 : %u"), watch.ElapsedTime());
    ::OutputDebugString(text);
}

処理時間をざっくりと計りたいだけなら計測の開始と終了地点に OutputDebugString で出力してそれを DebugView から眺める手もある。