
ahmet alp balcánico
Tengo que calcular el tiempo de ejecución de un fragmento de código C++ en segundos. Debe estar funcionando en máquinas Windows o Unix.
Utilizo el siguiente código para hacer esto. (importar antes)
clock_t startTime = clock();
// some code here
// to compute its execution duration in runtime
cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " seconds." << endl;
Sin embargo, para entradas pequeñas o declaraciones cortas como a = a + 1, obtengo un resultado de “0 segundos”. Creo que debe ser algo así como 0.0000001 segundos o algo así.
yo recuerdo eso System.nanoTime()
en Java funciona bastante bien en este caso. Sin embargo, no puedo obtener la misma funcionalidad exacta de clock()
función de C++.
tienes una solución?

Tomás Bonini
Puedes usar esta función que escribí. Llama GetTimeMs64()
y devuelve la cantidad de milisegundos transcurridos desde la época de Unix usando el reloj del sistema, al igual que time(NULL)
excepto en milisegundos.
Funciona tanto en Windows como en Linux; es seguro para subprocesos.
Tenga en cuenta que la granularidad es de 15 ms en Windows; en linux depende de la implementación, pero también suele ser de 15 ms.
#ifdef _WIN32
#include <Windows.h>
#else
#include <sys/time.h>
#include <ctime>
#endif
/* Remove if already defined */
typedef long long int64; typedef unsigned long long uint64;
/* Returns the amount of milliseconds elapsed since the UNIX epoch. Works on both
* windows and linux. */
uint64 GetTimeMs64()
{
#ifdef _WIN32
/* Windows */
FILETIME ft;
LARGE_INTEGER li;
/* Get the amount of 100 nano seconds intervals elapsed since January 1, 1601 (UTC) and copy it
* to a LARGE_INTEGER structure. */
GetSystemTimeAsFileTime(&ft);
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
uint64 ret = li.QuadPart;
ret -= 116444736000000000LL; /* Convert from file time to UNIX epoch time. */
ret /= 10000; /* From 100 nano seconds (10^-7) to 1 millisecond (10^-3) intervals */
return ret;
#else
/* Linux */
struct timeval tv;
gettimeofday(&tv, NULL);
uint64 ret = tv.tv_usec;
/* Convert from micro seconds (10^-6) to milliseconds (10^-3) */
ret /= 1000;
/* Adds the seconds (10^0) after converting them to milliseconds (10^-3) */
ret += (tv.tv_sec * 1000);
return ret;
#endif
}

arhuaco
Tengo otro ejemplo de trabajo que usa microsegundos (UNIX, POSIX, etc.).
#include <sys/time.h>
typedef unsigned long long timestamp_t;
static timestamp_t
get_timestamp ()
{
struct timeval now;
gettimeofday (&now, NULL);
return now.tv_usec + (timestamp_t)now.tv_sec * 1000000;
}
...
timestamp_t t0 = get_timestamp();
// Process
timestamp_t t1 = get_timestamp();
double secs = (t1 - t0) / 1000000.0L;
Aquí está el archivo donde codificamos esto:
https://github.com/arhuaco/junkcode/blob/master/emqbit-bench/bench.c

gongzhitaao
Aquí hay una solución simple en C ++ 11 que le brinda una resolución satisfactoria.
#include <iostream>
#include <chrono>
class Timer
{
public:
Timer() : beg_(clock_::now()) {}
void reset() { beg_ = clock_::now(); }
double elapsed() const {
return std::chrono::duration_cast<second_>
(clock_::now() - beg_).count(); }
private:
typedef std::chrono::high_resolution_clock clock_;
typedef std::chrono::duration<double, std::ratio<1> > second_;
std::chrono::time_point<clock_> beg_;
};
O en *nix, para c++03
#include <iostream>
#include <ctime>
class Timer
{
public:
Timer() { clock_gettime(CLOCK_REALTIME, &beg_); }
double elapsed() {
clock_gettime(CLOCK_REALTIME, &end_);
return end_.tv_sec - beg_.tv_sec +
(end_.tv_nsec - beg_.tv_nsec) / 1000000000.;
}
void reset() { clock_gettime(CLOCK_REALTIME, &beg_); }
private:
timespec beg_, end_;
};
Aquí está el ejemplo de uso:
int main()
{
Timer tmr;
double t = tmr.elapsed();
std::cout << t << std::endl;
tmr.reset();
t = tmr.elapsed();
std::cout << t << std::endl;
return 0;
}
Desde https://gist.github.com/gongzhitaao/7062087

Tomás André
#include <boost/progress.hpp>
using namespace boost;
int main (int argc, const char * argv[])
{
progress_timer timer;
// do stuff, preferably in a 100x loop to make it take longer.
return 0;
}
Cuándo progress_timer
sale del alcance, imprimirá el tiempo transcurrido desde su creación.
ACTUALIZAR: Aquí hay una versión que funciona sin Boost (probada en macOS/iOS):
#include <chrono>
#include <string>
#include <iostream>
#include <math.h>
#include <unistd.h>
class NLTimerScoped {
private:
const std::chrono::steady_clock::time_point start;
const std::string name;
public:
NLTimerScoped( const std::string & name ) : name( name ), start( std::chrono::steady_clock::now() ) {
}
~NLTimerScoped() {
const auto end(std::chrono::steady_clock::now());
const auto duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>( end - start ).count();
std::cout << name << " duration: " << duration_ms << "ms" << std::endl;
}
};
int main(int argc, const char * argv[]) {
{
NLTimerScoped timer( "sin sum" );
float a = 0.0f;
for ( int i=0; i < 1000000; i++ ) {
a += sin( (float) i / 100 );
}
std::cout << "sin sum = " << a << std::endl;
}
{
NLTimerScoped timer( "sleep( 4 )" );
sleep( 4 );
}
return 0;
}
Windows proporciona la función QueryPerformanceCounter(), y Unix tiene gettimeofday() Ambas funciones pueden medir al menos 1 microsegundo de diferencia.

carlton henderson
En algunos programas que escribí usé RDTS para tal fin. RDTSC no se trata de tiempo sino de número de ciclos desde el inicio del procesador. Debe calibrarlo en su sistema para obtener un resultado en segundos, pero es realmente útil cuando desea evaluar el rendimiento, es incluso mejor usar el número de ciclos directamente sin intentar volver a cambiarlos a segundos.
(el enlace de arriba es a una página de wikipedia en francés, pero tiene ejemplos de código C++, la versión en inglés es aquí)

Tomas Matthews
Sugiero usar las funciones de biblioteca estándar para obtener información de tiempo del sistema.
Si desea una resolución más fina, realice más iteraciones de ejecución. En lugar de ejecutar el programa una vez y obtener muestras, ejecútelo 1000 veces o más.
Tenga en cuenta que cualquier comparación basada en la diferencia de tiempo puede ser inexacta debido al hecho de que es posible que el sistema operativo no ejecute su hilo de principio a fin. Puede interrumpirlo y ejecutar otros subprocesos entrelazados con el suyo, lo que tendrá un impacto significativo en el tiempo real necesario para completar su operación. Puede ejecutar varias veces y promediar los resultados; puede minimizar el número de otros procesos en ejecución. Pero ninguno de estos eliminará por completo el efecto de suspensión del hilo.
– Mordachai
7 de diciembre de 2009 a las 17:07
Mordachi, ¿por qué querrías eliminarlo? Desea ver cómo se desempeña su función en un entorno del mundo real, no en un reino mágico donde los hilos nunca se interrumpen. Siempre que lo ejecute varias veces y haga un promedio, será muy preciso.
– Tomás Bonini
7 de diciembre de 2009 a las 17:37
Sí, lo ejecuto varias veces y obtengo un promedio de resultados.
– ahmet alp balkan
7 de diciembre de 2009 a las 17:54
Andreas, el comentario de Mordachai es relevante si el OP desea comparar el rendimiento de su código con un algoritmo diferente. Por ejemplo, si ejecuta varias pruebas de reloj esta tarde y luego prueba un algoritmo diferente mañana por la mañana, es posible que su comparación no sea confiable, ya que puede estar compartiendo recursos con muchos más procesos por la tarde que por la mañana. O tal vez un conjunto de código hará que el sistema operativo le dé menos tiempo de procesamiento. Hay numerosas razones por las que este tipo de medición del rendimiento no es fiable si quiere realizar una comparación basada en el tiempo.
– weberc2
30 de agosto de 2012 a las 13:42
@Mordachai Sé que estoy respondiendo a un comentario anterior, pero para cualquiera que tropiece con esto como lo hice yo: para medir el rendimiento de los algoritmos, desea tomar el mínimo de algunas ejecuciones, no el promedio. Este es el que tuvo menos interrupciones por parte del sistema operativo y, por lo tanto, cronometra principalmente su código.
– Baruc
20 de agosto de 2014 a las 7:52