0

I'm trying to time my algorithm but the time always shows up as zero. Here is my code:

steady_clock::time_point start = steady_clock::now();
ReverseArray(list1, 1000000);
steady_clock::time_point end = steady_clock::now();
auto totalTime = end - start;
cout << duration_cast<microseconds>(totalTime).count()<< "\n";
  • 1
    What does ReverseArray do, and do you use list1 afterwards? Could it be that the compiler is optimizing the code and removing the call? – MatthiasB Apr 14 '14 at 15:16
  • Have you tried with a measure thiner than microseconds? Could be your algorithm, which is executed fast. Provide the code of that algorithm, just for the case. – Manu343726 Apr 14 '14 at 15:16
  • 1
    For todays CPUs even a microsecond is a long time. Why not use a profiler tool? – Flovdis Apr 14 '14 at 15:17
  • I have tried using nanoseconds also. –  Apr 14 '14 at 15:20
  • possible duplicate of [How to Calculate Execution Time of a Code Snippet in C++](http://stackoverflow.com/questions/1861294/how-to-calculate-execution-time-of-a-code-snippet-in-c) – BenC Apr 14 '14 at 15:23
  • Or even: http://stackoverflow.com/questions/1487695/c-cross-platform-high-resolution-timer – BenC Apr 14 '14 at 15:26
  • 4
    Try running it a few hundred or thousand times in a loop, and divide the total time by the number of iterations. The exec time of a single iteration may be too fast for accurate timing. – 3Dave Apr 14 '14 at 15:27

3 Answers3

2

Just to elaborate on Jack's answer: on Windows, using Visual Studio up to 2013, there is a bug in the standard library which makes chrono clocks unprecise. The high resolution clock is an alias to the steady clock which is ok, but the bug is that it have a very low resolution (around 8 ms last time I checked). Therefore, to this day (04/2014), VS standard library can't be used for measuring time or even for time-sensitive concurrent data sharing mechanisms (like when relying on condition_variable.wait_for() or this_thread::sleep_for() functions). Personally I fixed this problem by using Boost implementation instead until it's fixed. As pointed by STL (the person who is in charge of the standard library in Microsoft) in the bug report this should be fixed for the Visual Studio versions higher than 2013 (not the CTPs as they don't change the standard library).

What I mean is that your code is actually correct and cross-platform (except I would have used high_precision_clock instead), that specific implementation is buggy, but it works well with other implementations (GCC, Clang, Boost version of chrono and thread). For example this works perfectly well on GCC 4.8 (Coliru):

#include <iostream>

#include <chrono>
#include <vector>
#include <algorithm>

auto my_array = []{ 
        std::vector<long long> values( 100000 );
        long long last_value = 0;
        for( auto& value : values )
            value = last_value++;
        return values;
    }();


void some_work()
{
    for( int i = 0; i < 10000; ++i ) // play with this count 
        std::reverse( begin(my_array), end(my_array) );
}


int main()
{
    using namespace std;
    using namespace chrono;

    auto start = high_resolution_clock::now();
    some_work();
    auto end = high_resolution_clock::now();
    auto totalTime = end - start;
    cout << duration_cast<microseconds>(totalTime).count()<< " microsecs \n";

    return 0;
}

Coliru return "95 microsecs" for me when trying with only one cycle in some_work().

Klaim
  • 67,274
  • 36
  • 133
  • 188
1

Maybe you need more resolution:

auto t1 = std::chrono::high_resolution_clock::now();

// Your code to be measured

auto t2 = std::chrono::high_resolution_clock::now();
auto t = std::chrono::duration<double,std::milli>(t2-t1).count();

std::cout << "Time (ms):" << t << std::endl;
masoud
  • 55,379
  • 16
  • 141
  • 208
0

If you're on Windows, use this resource.

It is good for sub-microsecond accuracy. Use this:

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency); 
QueryPerformanceCounter(&StartingTime);
ReverseArray(list1, 1000000);
QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
Jack
  • 585
  • 4
  • 11
  • 1
    He may not be though, in which case he would need `` or the boost library. –  Apr 14 '14 at 15:21
  • @willywonka_dailyblah Yes you're completely correct. In Windows, I've found the best accuracy with QPF, but obviously this will only work on Windows. – Jack Apr 14 '14 at 15:26
  • yeah the QPF could potentially achieve sub-microsecond accuracy (depending on the clock frequency) –  Apr 14 '14 at 15:38