Medir el tiempo de ejecución de una función en C++ STL
-
Usa
std::chrono::high_resolution_clock::now
ystd::chrono::duration_cast<std::chrono::seconds>
para medir el tiempo de ejecución de una función -
Usar
std::chrono::high_resolution_clock::now
ystd::chrono::duration<double, std::milli>
para medir el tiempo de ejecución de una función
Este artículo mostrará varios métodos sobre cómo medir el tiempo de ejecución de una función en C++.
Usa std::chrono::high_resolution_clock::now
y std::chrono::duration_cast<std::chrono::seconds>
para medir el tiempo de ejecución de una función
El espacio de nombres std::chrono
consolida todas las utilidades de fecha y hora proporcionadas por la biblioteca STL de C++. Este último ofrece múltiples implementaciones de reloj, una de las cuales es std::chrono::high_resolution_clock
que corresponde al reloj con el período de tic más pequeño. Sin embargo, tenga en cuenta que este reloj depende de la plataforma de hardware e incluso difieren varias implementaciones de bibliotecas estándar, por lo que es mejor leer la documentación del compilador y asegurarse de que esta sea adecuada para los requisitos del problema. La idea para medir el tiempo de ejecución de una función es recuperar la hora actual del reloj dado dos veces: antes de la llamada a la función y después, y calcular la diferencia entre los valores. La hora actual se recupera utilizando el método incorporado now
. Una vez calculada la diferencia, debe interpretarse en una determinada unidad de tiempo, lo cual se hace usando la utilidad std::chrono::duration_cast
. En el siguiente ejemplo, convertimos el resultado en unidades de std::chrono::segundos
y mostramos el valor con la función incorporada count
. Observe que el funcSleep
en el ejemplo de código suspende la ejecución del programa durante 3 segundos y luego devuelve el control a la función main
.
#include <chrono>
#include <iostream>
#include <thread>
using std::cout;
using std::endl;
void funcSleep() { std::this_thread::sleep_for(std::chrono::seconds(3)); }
int main() {
auto start = std::chrono::high_resolution_clock::now();
funcSleep();
auto end = std::chrono::high_resolution_clock::now();
auto int_s = std::chrono::duration_cast<std::chrono::seconds>(end - start);
std::cout << "funcSleep() elapsed time is " << int_s.count() << " seconds )"
<< std::endl;
return EXIT_SUCCESS;
}
Producción :
funcSleep() elapsed time is 3 seconds
Usar std::chrono::high_resolution_clock::now
y std::chrono::duration<double, std::milli>
para medir el tiempo de ejecución de una función
A diferencia del código anterior, donde la unidad de tiempo se guardó en un valor entero, el siguiente ejemplo almacena el valor del intervalo como un número de punto flotante en el std::chrono::duration<double, std::milli>
Tipo de objeto. std::chrono::duration
es una plantilla de clase general para representar el intervalo de tiempo. Finalmente, el valor del intervalo se recupera usando la función count
, momento en el que se puede imprimir en el flujo cout
.
#include <chrono>
#include <iostream>
#include <thread>
using std::cout;
using std::endl;
void funcSleep() { std::this_thread::sleep_for(std::chrono::seconds(3)); }
int main() {
auto start = std::chrono::high_resolution_clock::now();
funcSleep();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> float_ms = end - start;
std::cout << "funcSleep() elapsed time is " << float_ms.count()
<< " milliseconds" << std::endl;
return EXIT_SUCCESS;
}
Producción :
funcSleep() elapsed time is 3000.27 milliseconds
Los dos últimos ejemplos midieron una función que en su mayoría toma un tiempo constante, pero se puede usar un enfoque similar para calcular el tiempo de ejecución del bloque de código dado. Como ejemplo, el siguiente fragmento demuestra la función de generación de enteros aleatorios que necesita más intervalos variables para ejecutarse. Observe que, esta vez, usamos ambos métodos para mostrar el tiempo con precisión de milisegundos y segundos.
#include <chrono>
#include <iostream>
#include <thread>
using std::cout;
using std::endl;
constexpr int WIDTH = 1000000;
void generateNumbers(int arr[]) {
std::srand(std::time(nullptr));
for (size_t i = 0; i < WIDTH; i++) {
arr[i] = std::rand();
}
}
int main() {
int *arr = new int[WIDTH];
auto start = std::chrono::high_resolution_clock::now();
generateNumbers(arr);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> float_ms = end - start;
auto int_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::chrono::duration<long, std::micro> int_usec = int_ms;
std::cout << "generateNumbers() elapsed time is " << float_ms.count()
<< " ms "
<< "( " << int_ms.count() << " milliseconds )" << std::endl;
delete[] arr;
return EXIT_SUCCESS;
}
Producción :
generateNumbers() elapsed time is 30.7443 ms ( 30 milliseconds )
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook