ネイティブアプリの速度計測
前に書いた.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 から眺める手もある。