Friday, June 8, 2012

Performance function/scope timers, for Windows

In my last post I showed you have to create an easy-to-use timer for Mac OSX programs that would calculate the time it took a function or scope to execute. Here's the Windows version I promised.

Here's the main.cpp:
// main.cpp
#include <iostream>

#include "PerfTimer.h"

void someFcn()
{
    CreateFcnTimer;
    
    for (unsigned int i = 0; i < 10000000; ++i )
    {
        int j = 5;
        ++j;
    }
}

int main(int argc, const char * argv[])
{
    {
        ScopeTimer("MyCustomScope");
        
        someFcn();
    }
    
    return 0;
}

And here's the timer class itself.
// PerfTimer.h
#pragma once
 
#include <iostream>
#include <windows.h>
 
class PerfTimer
{
public:
    PerfTimer(const char* timerName)
    {
        m_name = std::string(timerName);

 QueryPerformanceFrequency(&m_frequency);
         
        // Start the timer
        QueryPerformanceCounter(&m_startTime);
    }
     
    ~PerfTimer()
    {
        LARGE_INTEGER endTime;
 QueryPerformanceCounter(&endTime);
         
        // Output timer duration in milliseconds
        std::cout << m_name.c_str() << ": " << ((endTime.QuadPart - m_startTime.QuadPart) * 1000.0 / m_frequency.QuadPart) << std::endl;
    }
     
private:
    LARGE_INTEGER m_startTime;
    LARGE_INTEGER m_frequency;
    std::string m_name;
};
 
#ifndef SHIPPING_BUILD
 
    #define CreateFcnTimer PerfTimer __FUNCTION__timer(__FUNCTION__)
 
    // The 'x' in 'xtimer' is replaced by whatever string is passed into the scope timer
    // but the quotations are removed. So if the calling code is ScopeTimer("stuff")
    // then 'xtimer' becomes 'timerstuff'. This makes sure every timer name is unique
    // within the scoe it is used.
    #define ScopeTimer(x) PerfTimer xtimer(x)
 
#else
    // The timers can be shut off in shipping builds by replacing their standard
    // macros with these.
    #define CreateFcnTimer ((void)0)
    #define ScopeTimer(x) ((void)0)
 
#endif

The only difference between this Windows version and the Mac version is that you need to include Windows.h, and you have to query the frequency using QueryPerformanceFrequency, and factor the frequency into your calculations.

No comments:

Post a Comment