Вы можете абстрагировать механизм измерения времени и измерять время выполнения каждого вызываемого объекта с помощью минимальный дополнительный код , просто вызывая его через структуру таймера. Кроме того, во время компиляции вы можете параметризовать тип синхронизации (миллисекунды, наносекунды и т. Д.).
Благодаря обзору Loki Astari и предложению использовать вариадические шаблоны.
Это , поэтому переадресованный вызов функции.
#include <iostream>
#include <chrono>
template<typename TimeT = std::chrono::milliseconds>
struct measure
{
template<typename F, typename ...Args>
static typename TimeT::rep execution(F&& func, Args&&... args)
{
auto start = std::chrono::steady_clock::now();
std::forward<decltype(func)>(func)(std::forward<Args>(args)...);
auto duration = std::chrono::duration_cast< TimeT>
(std::chrono::steady_clock::now() - start);
return duration.count();
}
};
int main() {
std::cout << measure<>::execution(functor(dummy)) << std::endl;
}
Демо
Согласно комментарию Говарда Хиннанта лучше не выходить из системы хронографа, пока нам не придется. Таким образом, приведенный выше класс может дать пользователю возможность вызвать count
вручную, предоставив дополнительный статический метод (показан в C ++ 14)
template<typename F, typename ...Args>
static auto duration(F&& func, Args&&... args)
{
auto start = std::chrono::steady_clock::now();
std::forward<decltype(func)>(func)(std::forward<Args>(args)...);
return std::chrono::duration_cast<TimeT>(std::chrono::steady_clock::now()-start);
}
// call .count() manually later when needed (eg IO)
auto avg = (measure<>::duration(func) + measure<>::duration(func)) / 2.0;
и быть наиболее полезным для клиентов,
"хотите обработать несколько периодов до ввода / вывода (например, в среднем)"
Полный код можно найти здесь . Моя попытка построить инструмент для бенчмаркинга на основе хронографа записана здесь .
Если C ++ 17 std::invoke
доступен, вызов вызываемого в execution
может быть выполнен следующим образом:
invoke(forward<decltype(func)>(func), forward<Args>(args)...);
для обеспечения вызовов, которые являются указателями на функции-члены.