C++11 timing code performance
Posted on October 14, 2012 by Sol

Prior to the release of the C++11 standard, there was no standard way in which one could accurately measure the execution time of a piece of code. The programmer was forced to use external libraries like Boost, or routines provided by each operating system.

The C++11 chrono header file provides three standard clocks that could be used for timing one’s code:

  • system_clock - this is the real-time clock used by the system;
  • high_resolution_clock - this is a clock with the shortest tick period possible on the current system;
  • steady_clock - this is a monotonic clock that is guaranteed to never be adjusted.

If you want to measure the time taken by a certain piece of code for execution, you should generally use the steady_clock, which is a monotonic clock that is never adjusted by the system. The other two clocks provided by the chrono header can be occasionally adjusted, so the difference between two consecutive time moments, t0 < t1, is not always positive.

The chrono header file provides us with some functions, to check the clock’s precision and if the particular implementation of a given clock is steady (meaning it is not adjustable). Since the implementation details of a particular clock depends on the compiler and the OS, it is always a good idea to test these properties:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <chrono>

using namespace std;

int main(){
    cout << "system_clock" << endl;
    cout << chrono::system_clock::period::num << endl;
    cout << chrono::system_clock::period::den << endl;
    cout << "steady = " << boolalpha << chrono::system_clock::is_steady << endl << endl;

    cout << "high_resolution_clock" << endl;
    cout << chrono::high_resolution_clock::period::num << endl;
    cout << chrono::high_resolution_clock::period::den << endl;
    cout << "steady = " << boolalpha << chrono::high_resolution_clock::is_steady << endl << endl;

    cout << "steady_clock" << endl;
    cout << chrono::steady_clock::period::num << endl;
    cout << chrono::steady_clock::period::den << endl;
    cout << "steady = " << boolalpha << chrono::steady_clock::is_steady << endl << endl;

    return 0;    
}

This is the output of the above code on Mac OSX, compiled with clang-4.1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
system_clock
1
1000000
steady = false

high_resolution_clock
1
1000000000
steady = true

steady_clock
1
1000000000
steady = true

On this machine, the steady_clock and high_resolution_clock have the same characteristics, both are non-adjustable clocks with nanosecond precision. On the other hand, the system_clock is adjustable and it has only microsecond precision.

For comparison, this is the output of the program, compiled with Visual Studio 2012, on a Windows 7 machine:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
system_clock
1
10000000
steady = false

high_resolution_clock
1
10000000
steady = false

steady_clock
1
10000000
steady = true

In this case, only the steady_clock is non-adjustable, the precision is the same for all three clocks.

For measuring the execution time of a piece of code, we can use the now() function:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  auto start = chrono::steady_clock::now();

  //
  //  Insert the code that will be timed
  //

  auto end = chrono::steady_clock::now();

  // Store the time difference between start and end
  auto diff = end - start;

If you want to print the time difference between start and end in the above code, you could use:

1
  cout << chrono::duration <double, milli> (diff).count() << " ms" << endl;

If you prefer to use nanoseconds, you will use:

1
  cout << chrono::duration <double, nano> (diff).count() << " ns" << endl;

The value of the diff variable can be also truncated to an integer value, for example, if you want the result expressed as:

1
2
  diff_sec = chrono::duration_cast<chrono::nanoseconds>(diff);
  cout << diff_sec.count() << endl;

If you are interested in learning more about the new C++11 syntax, I would recommend reading Professional C++ by M. Gregoire, N. A. Solter, S. J. Kleper 2nd edition:

or The C++ Standard Library: A Tutorial and Reference (2nd Edition) by N. M. Josuttis:

blog comments powered by Disqus