
ベンチマークソフトを作りたい!と本格的に思わなくとも処理時間を計測したい場面は多々ある。簡易的に測定したのならGetTickCountを利用すると簡単に計測できる。
GetTickCountはPCを起動してからの経過時間をミリ秒単位で返すための関数だ。この関数を計測したい処理の前後に実行して、取得した値の差を取れば処理に要した時間となる。
ただしGetTickCountを利用する上で注意しておきたい点がある。
まず、この関数で返される値は「まれにゼロに戻る」という点だ。具体的には49.7日周期でゼロに戻る。そのため49.7日を超える処理時間は確実に計測できないし、処理時間が仮に数秒の場合でもちょうどゼロに戻るタイミングに当たった場合は処理時間が負の値となりきちんと計測できない。
また、WindowsはマルチタスクOSなため、バックグラウンド処理が重たいと計測時間が長くなるという点だ。これはGetTickCountの欠点ではないが場合によっては問題となり得る。
何はともあれ、「GetTickCountの値がゼロに戻ることがある」という点だけは絶対に頭に入れておかないとダメだ。
#include "atlstr.h"
bool Test()
{
DWORD dwStart;
ULONGLONG dwEnd;
dwStart = ::GetTickCount();
//処理時間を計測したい処理
{
int i;
int j;
for(i = 0; i < 1000; i++)
{
for(j = 0; j < 1000; j++)
{
char pszBuff[256];
::sprintf_s(pszBuff,256 * sizeof(char),"%d %d",i,j);
}
}
}
dwEnd = ::GetTickCount();
//GetTickCountは49.7日に1回ゼロに戻る。
//計測中にゼロに戻っても正常な値になるようにゼロに戻った場合は桁上がりさせる
//※注意:この桁上がり処理をした場合も49.7日を超える時間は計測できない
if(dwStart > dwEnd)
dwEnd += 0x100000000; //桁上がり
CAtlString strMessage;
strMessage.Format(_T("処理にかかった時間は %d ミリ秒です"),dwEnd - dwStart);
::MessageBox(NULL,strMessage,_T(""),MB_OK);
return true;
}
プロジェクトファイルをダウンロード

コメント (2)
初めて書き込みさせていただきます。
GetTickCountよりtimeGetTimeの方がお気に入りなのはおいといて、49.7日以上をはかる方法は無いんでしょうかねぇ。
現在時刻を取得する方法は、ユーザーが時計をいじればアウトな気がします。
投稿者: kcrt | 2007年03月30日 02:28
日時: 2007年03月30日 02:28
GetTickCountよりもtimeGetTimeの方を好む人が多いですね(MSDNライブラリでは"精度が必要な場合はtimeGetTimeを使え"と遠まわしに書かれていることもありますし)。
>49.7日以上をはかる方法は無いんでしょうかねぇ
Windows Vista以降ではGetTickCount64というAPIが追加されています。これは名前からも分かるように64ビットに拡張されたもので、DWORDからULONGLONGになったので現実問題として制限はなくなったと考えて大丈夫でしょう。
Windows Vista以前では一定間隔でGetTickCountがゼロに戻ったかどうかを検出して桁上がりを数えればいいと思います。
ほかにもSetSystemTimeなどの日時変更用のAPIをフックして強制的に無効化してしまったり、日時の変更を検出したら処理時間を計測しなおすというような方法も考えられると思います。
しかし実際問題として「日時の修正」が問題となるケースは少ないように思います。PCの時計はそれ自身精度が悪いので49.7日も経つと数十秒単位で誤差が出るため、むしろ日時の修正を積極的に行って常に正しい日時に修正した方がいいと思います。
長期間の処理をある程度の精度で計測したい場合は、PCに外付けでGPSを接続して、処理の前後にそこから日時を取得するといいと思います(実現困難な方法に感じますが、最近はGPSユニットの価格も安いですからそれほど敷居は高くありません)。同じような方法としてネット上のタイムサーバーから日時を取得する方法もあります。
投稿者: 匿名 | 2007年03月30日 13:34
日時: 2007年03月30日 13:34