Reputation: 2278
How can i measure something in C++ as accurately as in C#?
This is my C# code
var elapsedMilliseconds = (double)(sw.ElapsedTicks * 1000L) / Stopwatch.Frequency;
I'm using visual studio 2010.
Upvotes: 4
Views: 4838
Reputation: 2278
I needed a more specific measurement and found one. Thx for the other answers. They are all good. with this answer I can easily switch to Microseconds if needed.
Of course I will accept James Johnston answer as the right one because of the great explanation und the feedback of the people.
Thx all
int main(int argc, char ** argv)
{
unsigned long long nFreq = GetPerformanceTicksInSecond();
unsigned long long nBefore = GetPerformanceTicks();
timer start1 = timer::start();
CallSomeFunction();
unsigned long long nAfter = GetPerformanceTicks();
const unsigned long long nDiff = nAfter - nBefore;
const unsigned long long nMicroseconds = GetTickMicroseconds(nDiff,nFreq);
cout << "CallSomeFunction() took " << nMicroseconds << " " << time << endl;
return 0;
}
unsigned long long GetPerformanceTicks()
{
LARGE_INTEGER nValue;
::QueryPerformanceCounter(&nValue);
return nValue.QuadPart;
}
unsigned long long GetPerformanceTicksInSecond()
{
LARGE_INTEGER nFreq;
::QueryPerformanceFrequency(&nFreq);
return nFreq.QuadPart;
}
double GetTickSeconds(unsigned long long nTicks,unsigned long long nFreq)
{
return static_cast<double>(nTicks) / static_cast<double>(nFreq);
}
unsigned long long GetTickMilliseconds(unsigned long long nTicks,unsigned long long nFreq)
{
unsigned long long nTicksInMillisecond = nFreq / 1000;
return nTicks / nTicksInMillisecond;
}
unsigned long long GetTickMicroseconds(unsigned long long nTicks,unsigned long long nFreq)
{
unsigned long long nTicksInMicrosecond = nFreq / 1000000;
return nTicks / nTicksInMicrosecond;
}
Upvotes: 1
Reputation: 9492
The Stopwatch class in C# is based on these two Win32 API calls, which you can call from C/C++:
Call the first function and divide it by the second function to get a value in seconds.
Example:
LARGE_INTEGER freq, start, end;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&start);
// do some long operation here
Sleep(5000);
QueryPerformanceCounter(&end);
// subtract before dividing to improve precision
double durationInSeconds = static_cast<double>(end.QuadPart - start.QuadPart) / freq.QuadPart;
Note that the following comment in the documentation is real, and should be considered. I'm personally observed this behavior in a VirtualBox virtual machine. Differences of dozens of milliseconds can exist between different processors, leading to unexpected results such as negative durations and longer-than-expected durations:
On a multiprocessor computer, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL). To specify processor affinity for a thread, use the SetThreadAffinityMask function.
You might be interested in this for more: System.Diagnostics.Stopwatch returns negative numbers in Elapsed... properties
Note that the Stopwatch class falls back on GetTickCount if the above two APIs aren't available or return failure codes. This is likely just to retain compatibility with Windows 9x; I've not encountered any issues myself with these APIs on modern PCs. GetTickCount won't have the precision you want, however.
Upvotes: 14
Reputation: 2603
The Stopwatch-class is a wrapper around QueryPerformanceCounter:
uint64_t startTime, endTime;
uint64_t frequency;
QueryPerformanceFrequency((LARGE_INTEGER*)&frequency);
QueryPerformanceCounter((LARGE_INTEGER*)&startTime);
//DoStuff
QueryPerformanceCounter((LARGE_INTEGER*)&endTime);
double seconds = (endTime-startTime)/(double) frequency;
Upvotes: 0
Reputation: 1407
Use QueryPerformanceFrequency and QueryPerformanceCounter API functions.
LARGE_INTEGER freq;
::QueryPerformanceFrequency(&freq);
LARGE_INTEGER start, end;
::QueryPerformanceCounter(&start);
// do some work
::QueryPerformanceCounter(&end);
double const t = double(end.QuadPart - start.QuadPart) / double(freq.QuadPart);
To improve accuracy you may want to subtract the time it takes to call QueryPerformanceCounter from the result.
Upvotes: 0
Reputation: 294
check this: How to get system time in C++?
also you can use GetTickCount which: Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days.
Upvotes: 0