/*
You write a great code! But it is still wise that you keep measuring how it performs, You shall write test case to keep measuring time taken by API in high precision.
In this blog, I will explain how to use Query performance counter windows API to measure the time taken by your API with high precision.
The QueryPerformanceCounter and QueryPerformanceFrequency API
This API is backed by a virtual counter running at a "fixed" frequency started at boot time.
The following two basic calls are used to explore the microsecond regime : QueryPerformanceCounter() and QueryPerformanceFrequency().The counter values are derived from some hardware counter, which is platform dependent.However, the Windows version also influences the results by handling the counter in a version specific manner.Windows 7, particular has introduced a new way of supplying performance counter values.
QueryPerformanceCounter
The call to BOOL QueryPerformanceCounter(OUT LARGE_INTEGER *lpPerformanceCount); will update the content of the LARGE_INTEGER structure PerformanceCount with a count value. The count value is initialized to zero at boot time.
QueryPerformanceFrequency
The call to BOOL QueryPerformanceFrequency(OUT LARGE_INTEGER *lpFrequency); will update the content of the LARGE_INTEGER structure PerformanceFrequency with a frequency value.
*/
#include <Windows.h>
#include <iostream>
#include <vector>
#include <list>
class QueryPerformanceCounterC
{
public:
QueryPerformanceCounterC() :PCFreq(0.0), CounterStart(0){}
void start()
{
LARGE_INTEGER li;
/*
Retrieves the frequency of the performance counter. The frequency of the performance counter is fixed at system boot and is consistent across all processors. Therefore, the frequency need only be queried upon application initialization, and the result can be cached.
*/
if (!QueryPerformanceFrequency(&li))
throw "QueryPerformanceFrequency failed!\n";
PCFreq = double(li.QuadPart) / 1000.0;
/*
Retrieves the current value of the performance counter,
which is a high resolution (<1us) time stamp that can be used for time-interval measurements.
*/
QueryPerformanceCounter(&li);
CounterStart = li.QuadPart;
}
double stop()
{
LARGE_INTEGER li;
/*
Retrieves the current value of the performance counter, which is a high resolution (<1us) time stamp that can be used for time-interval measurements.
*/
QueryPerformanceCounter(&li);
return double(li.QuadPart - CounterStart) / PCFreq;
}
private:
double PCFreq;
__int64 CounterStart = 0;
};
int main()
{
// A simple example, You have values in List, You API need it in Vector
// There are two version of coping
std::list<int> from;
from.resize(1000); // Input list
std::vector<int> one; // Destination one
std::vector<int> two; // Destination two
QueryPerformanceCounterC counter;
counter.start();
for (auto const& a : from) // Case 1: Push Back one by one
one.push_back(a);
std::cout << counter.stop() << std::endl;
QueryPerformanceCounterC counter2;
counter2.start();
two.resize(from.size()); // <- This single line will improve performance
for (auto const& a : from) // Case 2: Same as Case 1, But you allocate memory in advance
two.push_back(a);
std::cout << counter2.stop() << std::endl;
}