2009-04-08 29 views
67

¿Cuál es la mejor manera de calcular una diferencia de tiempo en C++? Estoy sincronizando la velocidad de ejecución de un programa, por lo que estoy interesado en milisegundos. Mejor aún, seconds.milliseconds ..Cómo calcular una diferencia de tiempo en C++

La respuesta aceptada funciona, pero debe incluir ctime o time.h como se indica en los comentarios.

+0

Dupe, pero no se puede vincular en este momento –

+1

La votación para cerrar fue demasiado poco, demasiado tarde. Tengo una respuesta funcional. Buen intento sin embargo. Por cierto, tampoco pude encontrar un enlace. –

+0

¿Es para ventanas? entonces intente GetTickCount (API de Windows) –

Respuesta

97

Véase la función std::clock().

const clock_t begin_time = clock(); 
// do something 
std::cout << float(clock() - begin_time)/CLOCKS_PER_SEC; 

Si desea calcular el tiempo de ejecución para el auto (no para el usuario), es mejor hacer esto en ciclos de reloj (no segundos).

EDIT:
archivos de cabecera responsables - <ctime> o <time.h>

+0

Cuando ejecuto este código, obtengo un número enorme, no tengo idea de lo que significa. Me gustaría algo que diga "9.334 segundos". –

+0

No se olvide de #include o apropiadamente para que clock() obtenga un prototipo apropiado y clock_t esté definido. – RBerteig

+3

Tenga en cuenta que aunque clock() devuelve un número de milisegundos, la precisión de clock() puede ser mucho peor que eso. Instancia Fir en Windows la precisión de la función clock() es algo así como 40 ms. –

5

Sólo una nota: si se está ejecutando en Windows, y que realmente realmente necesita precisión, puede utilizar QueryPerformanceCounter. Le da tiempo en (potencialmente) nano segundos.

3

Obtenga la hora del sistema en milisegundos al principio, otra vez al final y reste.

para obtener el número de milisegundos desde 1970 en POSIX podría escribir:

struct timeval tv; 

gettimeofday(&tv, NULL); 
return ((((unsigned long long)tv.tv_sec) * 1000) + 
     (((unsigned long long)tv.tv_usec)/1000)); 

Para obtener el número de milisegundos desde 1601 en Windows que iba a escribir:

SYSTEMTIME systime; 
FILETIME filetime; 

GetSystemTime(&systime); 
if (!SystemTimeToFileTime(&systime, &filetime)) 
    return 0; 

unsigned long long ns_since_1601; 
ULARGE_INTEGER* ptr = (ULARGE_INTEGER*)&ns_since_1601; 

// copy the result into the ULARGE_INTEGER; this is actually 
// copying the result into the ns_since_1601 unsigned long long. 
ptr->u.LowPart = filetime.dwLowDateTime; 
ptr->u.HighPart = filetime.dwHighDateTime; 

// Compute the number of milliseconds since 1601; we have to 
// divide by 10,000, since the current value is the number of 100ns 
// intervals since 1601, not ms. 
return (ns_since_1601/10000); 

Si te importaba a normalice la respuesta de Windows para que también devuelva la cantidad de milisegundos desde 1970, luego tendría que ajustar su respuesta en 11644473600000 milisegundos. Pero eso no es necesario si todo lo que te importa es el tiempo transcurrido.

28

Consideraría seriamente el uso de Boost, particularmente boost :: posix_time :: ptime y boost :: posix_time :: time_duration (en http://www.boost.org/doc/libs/1_38_0/doc/html/date_time/posix_time.html).

Es multiplataforma, fácil de usar, y en mi experiencia proporciona el mayor nivel de resolución de tiempo que proporciona un sistema operativo. Posiblemente también muy importante; proporciona algunos muy buenos operadores de IO.

Para utilizarla para calcular la diferencia en la ejecución del programa (a microsegundos; algo excesivo), se vería algo como esto [navegador por escrito, no se ha probado]:

ptime time_start(microsec_clock::local_time()); 
//... execution goes here ... 
ptime time_end(microsec_clock::local_time()); 
time_duration duration(time_end - time_start); 
cout << duration << '\n'; 
+2

boost local_time() es _no_ monotónico, por lo que no debe usarse para medir lapsos de tiempo. No he encontrado una manera de acceder a la hora monotónica de Boost. – gatopeich

6

en caso de que esté en Unix , puede utilizar time para obtener el tiempo de ejecución:

$ g++ myprog.cpp -o myprog 
$ time ./myprog 
11

En Windows: utilizar GetTickCount

//GetTickCount defintition 
#include <windows.h> 
int main() 
{ 

    DWORD dw1 = GetTickCount(); 

    //Do something 

    DWORD dw2 = GetTickCount(); 

    cout<<"Time difference is "<<(dw2-dw1)<<" milliSeconds"<<endl; 

} 
5

También puede usar el clock_gettime.Este método se puede utilizar para medir:

  1. todo el sistema de reloj en tiempo real
  2. sistema de reloj amplia monótona
  3. por proceso el tiempo de CPU
  4. por proceso el tiempo de rosca CPU

Código es de la siguiente manera:

#include <time.h> 
#include <iostream> 
int main(){ 
    timespec ts_beg, ts_end; 
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_beg); 
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts_end); 
    std::cout << (ts_end.tv_sec - ts_beg.tv_sec) + (ts_end.tv_nsec - ts_beg.tv_nsec)/1e9 << " sec"; 
} 

`

13

impulso 1.46.0 y hasta incluye la biblioteca Chrono:

clase thread_clock proporciona acceso a la rosca verdadero reloj de pared, es decir el reloj en tiempo real de la CPU del subproceso de llamada. La relación hora hilo puede ser obtenida llamando thread_clock :: ahora()

#include <boost/chrono/thread_clock.hpp> 
{ 
... 
    using namespace boost::chrono; 
    thread_clock::time_point start = thread_clock::now(); 
    ... 
    thread_clock::time_point stop = thread_clock::now(); 
    std::cout << "duration: " << duration_cast<milliseconds>(stop - start).count() << " ms\n"; 
+7

Además, ** C++ 11 ** tiene el espacio de nombres 'std :: chrono' con casi los mismos contenidos. – ulidtko

+1

@ulidtko easy also http://en.cppreference.com/w/cpp/chrono/duration/duration_cast –

0

Esto parece funcionar bien para Intel Mac 10.7:

#include <time.h> 

time_t start = time(NULL); 


    //Do your work 


time_t end = time(NULL); 
std::cout<<"Execution Time: "<< (double)(end-start)<<" Seconds"<<std::endl; 
+0

en milisegundos ??? –

27

si está utilizando C++ 11, aquí es un simple envoltorio (ver este gist):

#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 para C++ 03 en * nix:

#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_; 
}; 

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; 
} 
+2

Otra opción sería usar boost :: chrono en lugar del espacio de nombres C++ 11 STL std :: chrono. Gracias por tu código –

+2

¡También funciona en Mac OS! Gracias por tu codigo –

+0

Cuidado: Esto no funcionará si el usuario cambia su tiempo entre 'Timer()' y la llamada a 'elapsed()' si '! Std :: chrono :: high_resolution_clock :: is_steady' - que es el caso en Linux ! – jhasse

2

Si está utilizando:

tstart = clock(); 

// ...do something... 

tend = clock(); 

entonces necesitará la siguiente hora de conseguir en segundos:

time = (tend - tstart)/(double) CLOCKS_PER_SEC; 
4

Para yo, la manera más fácil es:

#include <boost/timer.hpp> 

boost::timer t; 
double duration; 

t.restart(); 
/* DO SOMETHING HERE... */ 
duration = t.elapsed(); 

t.restart(); 
/* DO OTHER STUFF HERE... */ 
duration = t.elapsed(); 

usando este código no tiene que hacer el clásico end - start.

Disfrute de su enfoque favorito.

+0

se t.elapuló() en segundos o milisegundos? – mkuse

Cuestiones relacionadas