Time measurement in Windows

Asked

Viewed 869 times

4

I would like to know how best to measure the running time of a programme in C++. I found several solutions on the internet, each with an approach. Suggestions?

3 answers

1


For Windows specifically, the best way (in the sense of having higher resolution) is to use the QueryPerformanceCounter.

An example of usage (use a recent compiler):

#include <windows.h>
#include <iostream>
#include <cstdint>

class Watch
{
    public:
        Watch()
        {
            LARGE_INTEGER li;
            if(!QueryPerformanceFrequency(&li))
            {
                std::cout << "QueryPerformanceFrequency failed!\n";
                return;
            }

            mPCFreq = static_cast<double>(li.QuadPart)/1000.0;

            QueryPerformanceCounter(&li);
            mCounterStart = li.QuadPart;
        }

        // Retorna o tempo em milisegundos desde que o
        // objeto Watch foi criado.
        double getCounter()
        {
            LARGE_INTEGER li;
            QueryPerformanceCounter(&li);
            return static_cast<double>(li.QuadPart - mCounterStart)/mPCFreq;
        }

    private:
        uint64_t mCounterStart;
        double mPCFreq;
};

int main()
{
    Watch counter;
    Sleep(1000);
    std::cout << counter.getCounter() << std::endl;
    return 0;
}

In this case, the code returns the time in milliseconds between the creation of the object Watch and the call counter.getCounter().


Another more portable solution is to use the library boost and use boost::posix_time::time_duration to measure the time on the scale you want (milliseconds, microseconds, seconds).

  • Some recommendations: 1. Whenever possible (that is, if the compiler supports), one should use the types in stdint.h, as int64, instead of __int64. 2. Avoid using global variables for this type of thing. Do CounterStart a local variable and pass it to the main with a return and to the GetCounter as argument would be better.

  • @luiscubal I made some changes to the code. It’s a different approach. What do you think?

  • 1

    Much better, although the cout in the constructor is not ideal (an exception would be preferable). By the way, in case of an error, it is possible to get a more detailed message with GetLastError and FormatMessage with FORMAT_MESSAGE_FROM_SYSTEM.

  • @luiscubal, according to the documentation of functions, Later versions of XP will not cause error when invoking this API function. The code is OK then.

  • @lfelix O QueryPerformanceCounter is called once only in the constructor. The other, which you must have confused, is the QueryPerformanceFrequency, that gets the frequency.

  • That’s right, I ended up editing the comment. I understood the code, solved my problem. Just one piece of information, this value returned is on what time scale, milliseconds? I haven’t implemented it yet...

  • Yes. In milliseconds.

Show 2 more comments

0

  • Using Mingw’s Queryperformancecounter can solve this problem?

  • @lfelix Mingw’s Queryperformancecounter should be the same as Windows native.

0

The text(Optimizing software in C++ - recommend read) shows how we can achieve this.

Translated:

Time measures may require very high resolution if the time intervals are short. In Windows, you can use the functions GetTickCount or QueryPerformanceCounter for millisecond resolution. The much higher resolution can be obtained with the time stamp counter on the CPU, which counts with the clock frequency of the CPU.

There’s a problem that the clock frequency may vary dynamically and measurements are unstable due to interruptions and task switches.


It is interesting to also look at the class StopWatch which is based on two API’s, to QueryPerformanceFrequency and QueryPerformanceCounter.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.