Measuring execution time is the first step in any attempt to improve program performance. Standard C++ does provide timing facilities, but they can be awkward to use. I implemented a wrapper that allows easy instrumenting of most functions.
In order to preserve function semantics, I wanted a function object that has the same return type as the original function, and a
getLastCallDuration() method that returns how long the previous run took. The basics were easy. I needed a class parametrized by the type of the function to instrument and the arguments it takes. The object should store the function and allocate some space to store each run’s duration.
The constructor is simple:
operator() takes more thought.
My first instinct was to start a timer, call the functor, save the returned value, determine the execution time, then return the value.
This fails if the function returns
void is a partial type and you can’t create variables of partial type).
Then I tried branching based on whether the return type was
void, which failed because the branch is decided at run-time, but the
auto result variable’s type still needs to be determined at compile-time.
Specializing the template for functions returning
void seemed promising, but a member function can’t be specialized unless the class is also specialized.
This means the class couldn’t be parametrized over all types of functions returning
The solution should have been obvious.
I wanted to initialize an environment, do some work in it, then tear down the environment.
This is a situation that clearly calls for RAII.
I created a helper class that holds a reference to the parent’s
last_call_duration and the timepoint the helper was constructed at.
After the helper is created, the function runs and has its value returned.
operator()‘s stack is cleaned up, the timer’s destructor is called and the timer saves the elapsed time.
Using it is as easy as: