I want to measure the time of a function execution.
I could use something like this:
using namespace std::chrono;
auto start = steady_clock::now();
// process
auto end = duration<double>(steady_clock::now() - start).count();
but I it seems pretty non-DRY to me. So I created a small function to do it:
template <typename Function, typename... Args>
auto measure_time(Function func, Args&&... args)
{
using namespace std::chrono;
auto start = steady_clock::now();
func(std::forward<Args>(args)...); // handle lvalues and rvalues
return duration<double>(steady_clock::now() - start).count();
}
and I call it as such:
measure_time(func, arg1, arg2, arg3); // for common functions
measure_time([](){func(arg1,arg2, arg3);); // for member or template functions
This works fine for me, but it does come with some drawbacks:
- it is not clear to me how it be conveniently changed to also retrieve the return value of
func
(which, of course, can also bevoid
)? - this clearly contradicts with the one-thing-per-function rule
- the readability of the code is significantly undermined:
important_function(arg1, arg2); // reads well measure_time(important_function, arg1, arg2); // measure_time steals the spotlight
Are there any guidelines to face these issues?
Update:
I forgot to mention that after the execution of the function I need to store the time elapsed to a container.
Update 2:
after @puio 's answer, I ended up with this:
using namespace std::chrono;
template <typename Container>
class Timer{
public:
Timer(Container& _c) : c(_c) {}
~Timer() {
c.push_back(duration<float>(steady_clock::now() - start).count());
}
private:
time_point<steady_clock> start{steady_clock::now()};
Container& c;
};
Usage:
auto mc = MyContainer{};
...
{
auto t = Timer<MyContainer>(mc);
// things to measure
}
// mc.back() is the elapsed time
DRY and clean :)