Click here to Skip to main content
Click here to Skip to main content

The CPerfTimer timer class

By , 27 Apr 2000
 
  • Download source files - 3 Kb
  • Updated: the class is now thread safe.

    High resolution timing is supported in Win32 by the QueryPerformanceCounter and QueryPerformanceFrequency API calls. The timer resolution varies with the processor. Today's high speed processors have a timer resolution of less than a microsecond. Of course, this is a much better resolution than the GetTickCount API!

    Using the QueryPerformanceCounter calls directly takes too much typing and the resulting code is usually hard to read. So, I looked all over the net for a timer class but I could not find one that suited me. I wrote a simple and powerful timer class and named it CPerfTimer. I wrote this a long time ago but I still have not had the need to update it. Searching the net I could not find a timer class as simple to use and as useful as CPerfTimer. Several other timer classes are available and they vary as to their simplicity and usefulness. I do not claim that this is the end-all-be-all of timer classes; but, I hope that someone will find it useful enough to refrain from taking the time to write yet another timer class.

    This class is simple to use. Just declare a variable as type CPerfTimer, call Start() to start timing and call Stop() to stop timing. You can pause a timer by calling Stop() and then you can call Start() to resume. Retrieve the elapsed time by calling an Elapsed...() function. Assignment, addition, subtraction and comparison are supported. There are a few information calls available also. All calls except Start and Stop can be performed on a timer without stopping it.

    I have not included separate documentation or example application. The code is fairly well documented and the above paragraph was copied from the CPerfTimer.h file. Methods for adding, subtracting and comparing CPerfTimers and seconds (double) are also included. And, a CPerfTimerT class that should be thread safe (no extensive testing has been done). Please inform me if any bugs are found or you have an idea for an enhancement.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    About the Author

    Dean Wyant
    Web Developer
    United States United States
    Member
    No Biography provided

    Sign Up to vote   Poor Excellent
    Add a reason or comment to your vote: x
    Votes of 3 or less require a comment

    Comments and Discussions

     
    You must Sign In to use this message board.
    Search this forum  
        Spacing  Noise  Layout  Per page   
    GeneralQueryPerformanceCounter fails sometimes, when structmember alignment is set to 1 bytememberhund1200020 Nov '08 - 4:42 
    Sometimes when member struct alignment is set to 1 byte, QueryPerformanceCounter fails. I don't know exactly why, but it's a concern. The call then returns odd values. I discovered this, because i had to set the alignment in VC++ in VS2005 to 1 byte (had to write structs to sockets, sizeof had to be accurate) and a waiting-loop suddenly went to infinity ... Just a heads up.
    GeneralRe: QueryPerformanceCounter fails sometimes, when structmember alignment is set to 1 bytememberDean Wyant20 Nov '08 - 5:39 
    I am not sure why the call is failing within your app / on your test computer.
    Struct alignment of 1 works fine in 6.0. Perhaps it is a VS2005/1 byte alignment compile problem?
    Are you runnning on a dual processor system?
    There has been mention of problems with QueryPerformanceCounter on some machines with dual processors - it seems that in a tight loop the value can decrease. There is no checks in CPerfTimer for this.
    If you post the wating loop timer part, maybe I can find the problem.
    QuestionApplication Error When Calling Start(TRUE)membershizulooi30 Oct '07 - 23:08 
    Hi..
    when I compile this code, it looks ok, no error.. Smile | :)
    but when I try to call the Start(TRUE), it have application error at
     
    inline void CPerfTimer::Start(BOOL bReset)
    { // Start from current value or optionally from 0
    __int64 i;
    QueryPerformanceCounter((LARGE_INTEGER *)&i);
    Lock(); <<<================================== error point at here
    if ((!bReset) && (m_Start < 0))
    m_Start += i; // We are starting with an accumulated time
    else
    m_Start = i; // Starting from 0
    Unlock();
    }
     
    is it anything wrong..??
    pls advise..
     
    regards,
    shizu (^.^)
    AnswerRe: Application Error When Calling Start(TRUE)memberDean Wyant31 Oct '07 - 3:04 
    Sorry, you have not given enough info to determine what the problem may be.
    You have pasted in some CPerfTimer code, but have not included any code
    showing how you are using CPerfTimer.
    For example, you should be able use CPerfTimer like this:
     
    #include "PerfTimer.h"
    CPerfTimer T;
    T.Start(TRUE);
    //... do something...
    TRACE("Elapsed Seconds: %0.4f\n",T.Elapsed());
    //...
     
    The Lock call is simply an empty method in the CPerfTimer class.
    If you are using the CPerfTimerT class, then it it uses a mutex (previous
    comments have pointed out that a critical section would be faster).
     


    Questionproblem compiling CPerfTimer on VC++ Expressmemberabarund27 Aug '06 - 13:08 
    when i try to compile CPerfTimer class on vc++ express I got the following errors:
     
    Error 7 error C2146: syntax error : missing ';' before identifier 'm_hMutex' c:\...\Timer.h 110
    Error 8 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\...\Timer.h 110
    Error 9 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\...\Timer.h 110
    Error 10 error C2065: 'm_hMutex' : undeclared identifier c:\...\Timer.h 82
    Error 11 error C3861: 'CreateMutex': identifier not found c:\...\Timer.h 82
    Error 12 error C3861: 'CreateMutex': identifier not found c:\...\Timer.h 88
    Error 13 error C3861: 'CreateMutex': identifier not found c:\...\Timer.h 94
    Error 14 error C3861: 'CloseHandle': identifier not found c:\...\Timer.h 99
    Error 15 error C3861: 'WaitForSingleObject': identifier not found c:\...\Timer.h 107
    Error 16 error C3861: 'ReleaseMutex': identifier not found c:\...\Timer.h 108
    Error 17 error C3861: 'QueryPerformanceFrequency': identifier not found c:\...\Timer.h 117
    Error 18 error C3861: 'QueryPerformanceCounter': identifier not found c:\...\Timer.h 151
    Error 19 error C3861: 'QueryPerformanceCounter': identifier not found c:\...\Timer.h 169
    Error 23 fatal error C1071: unexpected end of file found in comment c:\...\Timer.h 400
    Error 30 error C2146: syntax error : missing ';' before identifier 'm_hMutex' c:\...\Timer.h 110
    Error 31 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\...\Timer.h 110
    Error 32 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int c:\...\Timer.h 110
    Error 33 error C2065: 'm_hMutex' : undeclared identifier c:\...\Timer.h 82
    Error 34 error C3861: 'CreateMutex': identifier not found c:\...\Timer.h 82
    Error 35 error C3861: 'CreateMutex': identifier not found c:\...\Timer.h 88
    Error 36 error C3861: 'CreateMutex': identifier not found c:\...\Timer.h 94
    Error 37 error C3861: 'CloseHandle': identifier not found c:\...\Timer.h 99
    Error 38 error C3861: 'WaitForSingleObject': identifier not found c:\...\Timer.h 107
    Error 39 error C3861: 'ReleaseMutex': identifier not found c:\...\Timer.h 108
    Error 40 error C3861: 'QueryPerformanceFrequency': identifier not found c:\...\Timer.h 117
    Error 41 error C3861: 'QueryPerformanceCounter': identifier not found c:\...\Timer.h 151
    Error 42 error C3861: 'QueryPerformanceCounter': identifier not found c:\...\Timer.h 169
    Error 46 fatal error C1071: unexpected end of file found in comment c:\...\Timer.h 400

    any help is appriciated.

    AnswerRe: problem compiling CPerfTimer on VC++ ExpressmemberDean Wyant28 Aug '06 - 4:30 
    I do not know about vc++ express. And, I have no idea what kind of project etc. you are trying to compile into. The code does not compile "stand alone" because it uses Win32 calls. You need to include the files in a Win32 project for an application. It looks like the compiler is not compiling for a Win32 app because it does not recognize the Win32 calls (windows.h or others according to project type).
     
    Also, please see the "possible bug" message for a bug fix to a - operator.
    AnswerRe: problem compiling CPerfTimer on VC++ ExpressmemberCoderBruce15 Jul '10 - 8:01 
    Just wrap the empty strings in CreateMutex "" like this _T("") and it will work fine.
    GeneralPossible bugmembermetimmee7 May '06 - 12:39 
    Hi Mr Wyant,
     
    I’ve been using your CPerfTimer class for some-time now for home projects. Whilst undertaking an inspection activity at work, I noticed that: CPerfTimer::operator-(const double Secs) const calculates the result by employing the +=(double) operator, rather than the -=(double) operator.
     
    This is my test-case:
     
    void test_timer_math_operator6()
    {
     
    //testing CPerfTimer CPerfTimer::operator-(const double Secs) const
    CPerfTimer TestTime1(true);
    Sleep(10);//wait a time
    TestTime1.Stop();
     
    CPerfTimer TestTime2(true);
    Sleep(30);//wait a longer time
    TestTime2.Stop();
     
    CPerfTimer TestTimeResult(false);//create a temporary timer object to hold the result
    TestTimeResult = TestTime2 - TestTime1.Elapsed();//TEST SUBJECT
     
    assert( DOUBLE_EQ( TestTimeResult.Elapsed() , (TestTime2.Elapsed() - TestTime1.Elapsed() ) ) );
     
    }

     
    I believe that the operator should be thus:
     
    inline CPerfTimer CPerfTimer::operator-(const double Secs) const
    {
    CPerfTimer Result(*this);
    Result -= Secs; //was +=
    return Result;
    }

     
    Its late, so forgive me if my eyes have deceived me!
    Regards
     
    Tim

    GeneralRe: Possible bugmemberDean Wyant12 May '06 - 5:08 
    Looking at the code, it seems that you are correct.
    Changing the += to -= is the correct fix. I guess I never used that operator.
    Thanks.
    GeneralLaptopmemberzvivered30 Mar '05 - 7:11 
    I'm using CPerfTimer for a long time. It works great.
    Few days ago I tried it on a laptop with Windows XP.
    I wrote:
     
    Timer.Start (TRUE);
    while (1)
    {
    Timetag=Timer.Elapsed ()
    Sleep (40)
    }

     
    The value of Timetag was set to 0 every few seconds and then grew up.
    The same code worked great on a PC with Windows 2000.
    The value of Timetag was not set to 0.
     
    Can you help ?

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Permalink | Advertise | Privacy | Mobile
    Web04 | 2.6.130523.1 | Last Updated 28 Apr 2000
    Article Copyright 2000 by Dean Wyant
    Everything else Copyright © CodeProject, 1999-2013
    Terms of Use
    Layout: fixed | fluid