Search code examples
c++c++-chrono

Template that measures elapsed time of any function


I want to create a template function that measures the elapsed time of any other function. What I did until now:

using TimeDuration = std::chrono::nanoseconds;

std::tuple<FuncReturnType, TimeDuration> measureTime(Func func, Args&&... args)
{
    auto start = std::chrono::high_resolution_clock::now();
    auto ret = func(std::forward<Args>(args)...);
    auto end = std::chrono::high_resolution_clock::now();

    return {ret, std::chrono::duration_cast<TimeDuration>(end - start)};
}

It can be called using auto [ret, duration] = measureTime<FuncType>(Func, args..) and works.

The problem is that I don't know how to make it work on functions that return void, because auto ret = func(..) does not make sense anymore. Also it would be great if I could drop the FuncReturnType param.

Any ideas? Thanks

P.S. I am using C++17, no boost


Solution

  • You might do something like:

    template <typename Func, typename ...Args>
    auto measureTime(Func func, Args&&... args)
    {
        using FuncReturnType = decltype(func(std::forward<Args>(args)...));
    
        const auto start = std::chrono::high_resolution_clock::now();
        if constexpr (std::is_same_v<void, FuncReturnType>) {
            func(std::forward<Args>(args)...);
            auto end = std::chrono::high_resolution_clock::now();
            return std::chrono::duration_cast<TimeDuration>(end - start);
        } else {
            FuncReturnType ret = func(std::forward<Args>(args)...);
            auto end = std::chrono::high_resolution_clock::now();
            return std::tuple<FuncReturnType , TimeDuration>{
                ret, std::chrono::duration_cast<TimeDuration>(end - start)
            };
        }
    }