Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

228 lines
4.7 KiB

#ifndef __PERFTIMR_HXX__
#define __PERFTIMR_HXX__
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: perftimr.hxx
//
// Contents: Performance Timer class
//
// Classes: CPerfTimer
//
// History: 31-Jan-94 PeterWi Created.
//
// Notes: -- the timer will assert if you don't call an End()
// for each Start() [except for calling Reset() or the destructor]
//
// -- change DECIMAL_PLACES to the number you want to print.
// Operations will still be done internally with maximum precision.
//
// -- maximum precision on intel seems to be 1/1,193,000
// or 1 millisecond
//
//
// Usage:
//
// Say you want to time operations:
// 1) A
// 2) A and B
// 3) 3 repetitions of (A and B)
//
// ...
// cperftimer totaltimer;
//
// for (3 reps)
// {
// CPerfTimer timer;
//
// timer.Start();
//
// operation A
//
// timer.End().Add();
//
// printf("time for A is %ws\n", timer.FormatElapsedTime());
//
// timer.Start();
//
// operation B
//
// timer.End().Add();
//
// printf("time for A+B is %ws\n", timer.FormatTotalTime());
//
// totalTimer.Add(timer);
// }
//
// printf("time for 3 reps of A+B is %ws\n", totalTimer.FormatTotalTime());
//
// where the last printf() would print something like:
//
// "time for 3 reps of A+B is 3.234s"
//
//--------------------------------------------------------------------------
#define DECIMAL_PLACES 5 // number of decimal places you want
class CPerfTimer
{
private:
LONGLONG
GetLowTickCount(void)
{
_nt = NtQueryPerformanceCounter(&_liConvert1, &_liConvert2);
_liCount = _liConvert1.QuadPart;
_liFreq = _liConvert2.QuadPart;
return _liCount;
}
void
_CheckState(void)
{
if ( _fStarted )
{
ASSERT(!"in middle of timing -- need to stop timer\n");
}
}
WCHAR *
_TimeToString(LONGLONG & liTime)
{
LONGLONG liSeconds;
LONGLONG liRemainder;
LONGLONG liBigRemainder;
LONGLONG liDecimal;
liSeconds = liTime / _liFreq;
liRemainder = liTime % _liFreq;
liBigRemainder = liRemainder * (LONGLONG) _ulMult;
liDecimal = liBigRemainder / _liFreq;
wsprintf(_wszTime, _wszFormat, (LONG)liSeconds, (LONG)liDecimal);
return _wszTime;
}
LONGLONG _liCount;
LONGLONG _liFreq;
LONGLONG _totalTime;
LONGLONG _startTime;
LONGLONG _endTime;
LONGLONG _elapsedTime;
LARGE_INTEGER _liConvert1;
LARGE_INTEGER _liConvert2;
NTSTATUS _nt;
ULONG _ulMult;
BOOLEAN _fStarted;
WCHAR _wszTime[20];// allow max of "time:99999.999s" and NULL
WCHAR _wszFormat[20];
public:
CPerfTimer()
{
_ulMult = 1;
for ( ULONG j = 0; j < DECIMAL_PLACES; j++ )
{
_ulMult *= 10;
}
wsprintf(_wszFormat, L"%ws%dlus", L"%lu.%0", DECIMAL_PLACES);
Reset();
}
CPerfTimer &
Reset(void)
{
_fStarted = FALSE;
_totalTime = 0;
_elapsedTime = 0;
_endTime = _startTime = GetLowTickCount();
return *this;
}
CPerfTimer &
Start(void)
{
_CheckState();
_fStarted = TRUE;
_startTime = GetLowTickCount();
return *this;
}
CPerfTimer &
End(void)
{
_endTime = GetLowTickCount();
if ( !_fStarted )
{
ASSERT(!"end without starting timer\n");
}
_fStarted = FALSE;
_elapsedTime = _endTime - _startTime;
return *this;
}
CPerfTimer &
Add(void)
{
_CheckState();
_totalTime = _totalTime + _elapsedTime;
return *this;
}
CPerfTimer &
Add(const CPerfTimer & timer)
{
_CheckState();
_totalTime = _totalTime + timer.TotalTime();
return *this;
}
LONGLONG
TotalTime(void) const { return _totalTime; }
LONGLONG
ElapsedTime(void) const { return _elapsedTime; }
LONGLONG
TimeUnitsPerSecond(void) const { return _liFreq; }
WCHAR *
FormatTotalTime(void) { return _TimeToString(_totalTime); };
WCHAR *
FormatElapsedTime(void) { return _TimeToString(_elapsedTime); };
}; // CPerfTimer
#endif // __PERFTIMR_HXX__