Easily measure elapsed time Easily measure elapsed time linux linux

Easily measure elapsed time


//***C++11 Style:***#include <chrono>std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << "[µs]" << std::endl;std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::nanoseconds> (end - begin).count() << "[ns]" << std::endl;


#include <ctime>void f() {  using namespace std;  clock_t begin = clock();  code_to_time();  clock_t end = clock();  double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;}

The time() function is only accurate to within a second, but there are CLOCKS_PER_SEC "clocks" within a second. This is an easy, portable measurement, even though it's over-simplified.


1 - Timer

Use a timer based on std::chrono:

Timer clock; // Timer<milliseconds, steady_clock>clock.tick();/* code you want to measure */clock.tock();cout << "Run time = " << clock.duration().count() << " ms\n";

Demo

Timer is defined as:

template <class TimeT = std::chrono::milliseconds,          class ClockT = std::chrono::steady_clock>class Timer{    using timep_t = typename ClockT::time_point;    timep_t _start = ClockT::now(), _end = {};public:    void tick() {         _end = timep_t{};         _start = ClockT::now();     }        void tock() { _end = ClockT::now(); }        template <class TT = TimeT>     TT duration() const {         gsl_Expects(_end != timep_t{} && "toc before reporting");         return std::chrono::duration_cast<TT>(_end - _start);     }};

As Howard Hinnant pointed out, we use a duration to remain in the chrono type-system and perform operations like averaging or comparisons (e.g. here this means using std::chrono::milliseconds). When we just do IO, we use the count() or ticks of a duration (e.g. here number of milliseconds).

2 - Instrumentation

Any callable (function, function object, lambda etc.) can be instrumented for benchmarking. Say you have a function F invokable with arguments arg1,arg2, this technique results in:

cout << "F runtime=" << measure<>::duration(F, arg1, arg2).count() << "ms";

Demo

measure is defined as:

template <class TimeT  = std::chrono::milliseconds          class ClockT = std::chrono::steady_clock>struct measure{    template<class F, class ...Args>    static auto duration(F&& func, Args&&... args)    {        auto start = ClockT::now();        std::invoke(std::forward<F>(func), std::forward<Args>(args)...);        return std::chrono::duration_cast<TimeT>(ClockT::now()-start);    }};

As mentioned in (1), using the duration w/o .count() is most useful for clients that want to post-process a bunch of durations prior to I/O, e.g. average:

auto avg = (measure<>::duration(func) + measure<>::duration(func)) / 2;std::cout << "Average run time " << avg.count() << " ms\n";

+This is why the forwarded function call.

+The complete code can be found here

+My attempt to build a benchmarking framework based on chrono is recorded here

+Old demo