Расчет времени, прошедшего в C++
Мне нужно рассчитать время, прошедшее от моей функции. Прямо сейчас я использую std::clock и из того, что я понимаю, это измерение времени процессора, которое может отличаться от реального времени.
std::clock_t start;
double duration;
start = std::clock();
someFunctionToMeasure();
duration = (std::clock() - start) / (double)CLOCKS_PER_SEC;
Итак, есть 2 вещи, которые я хотел бы знать
Как работает std::clock? это просто измерение процессора при вычислении этой функции?
Есть ли лучший способ измерить время, затраченное на вычисление моей функции?
3 ответа
С помощью <chrono>
код, который вам нужен, может выглядеть так:
using clock = std::chrono::system_clock;
using ms = std::chrono::milliseconds;
const auto before = clock::now();
someFunctionToMeasure();
const auto duration = std::chrono::duration_cast<ms>(clock::now() - before);
std::cout << "It took " << duration.count()/1000.0 << "ms" << std::endl;
Если вам нужен этот фрагмент несколько раз, и начало / конец приблизительно равны точкам входа и выхода области, в которой вы вызываете someFunctionToMeasure()
может иметь смысл обернуть его в служебный класс, который делает два вызова now()
в конструкторе и деструкторе.
Просто хочу добавить современный подход к выбору времени любого вызываемого <chrono>
и удобный std::invoke
из C++17. Работает над членами, лямбдами или свободными функциями, или любой другой вызываемой.
// Just for convenience
using Seconds = std::chrono::duration<double>;
// Measure how much time the given function takes to execute using chrono
// Pass the function name, then all relevant arguments, including the object as the first if it's a member function
template<typename Function, typename... Args>
Seconds measure(Function&& toTime, Args&&... a)
{
auto start{std::chrono::steady_clock::now()}; // Start timer
std::invoke(std::forward<Function>(toTime), std::forward<Args>(a)...); // Forward and call
auto stop{std::chrono::steady_clock::now()}; // Stop timer
return (stop - start);
}
Это вернет время, которое потребовалось для выполнения функции. Если вам также нужно возвращаемое значение, вы можете сделать std::pair
с Seconds
и возвращаемое значение с std::invoke
будет правильно возвращать то, что возвращает вызываемый.
Тогда вы можете использовать это так:
auto t1 = measure(normalFunction);
auto t2 = measure(&X::memberFunction, obj, 4);
auto t3 = measure(lambda, 2, 3);
На свободную функцию, функцию-член и лямбду соответственно.
Источник: http://en.cppreference.com/w/cpp/chrono/c/clock
Часы отслеживают только то время, которое прошло в процессе, в котором они выполняются. Таким образом, ваш пример кода отслеживает, сколько процессорного времени потребовалось для выполнения вашей функции. Это заметно отличается от отслеживания реального времени, потому что процесс, на котором выполняется ваша функция, может быть прерван, а процессор может выполнить другой код в течение некоторого времени, пока ваша функция ожидает завершения.
Чтобы ответить на ваш второй вопрос, это может помочь уточнить, что вы подразумеваете под "лучше". Похоже, вы хотели отслеживать количество времени, в течение которого выполнялась ваша функция, и, насколько я понимаю, этот код выполняет эту задачу. Если вы хотите отслеживать количество времени в режиме реального времени, другие ответы приводят примеры этого.