2009-09-18 22 views
22

¿Cómo sello dos veces t1 y t2 y obtengo la diferencia en milisegundos en C?Marca de tiempo en el lenguaje de programación C

+5

No puede hacer eso solo con el estándar C. Las posibles soluciones que tendrá serán diferentes para Linux, Windows, teléfonos móviles, cajas registradoras, ..., hornos de microondas, ... – pmg

+0

@Christoph: tanto el tiempo() como el reloj() pueden devolver -1 (emitidos al tipo apropiado) para indicar que la función no está disponible en esa implementación ... y time(), cuando está disponible, tiene una resolución de 1 segundo o peor. Analicé el estándar pero no encontré ningún límite para la función clock() – pmg

+1

En la página del manual de Linux: "Tenga en cuenta que el tiempo puede ajustarse. En un sistema de 32 bits donde CLOCKS_PER_SEC es igual a 1000000, esta función devolverá el mismo valor aproximadamente cada 72 minutos ". Para obtener tiempo de CPU getrusage() es mejor, aunque el reloj es parte de ANSI C, pero getrusage/gettimeofday() no. – user172818

Respuesta

28

Esto le dará el tiempo en segundos + microsegundos

#include <sys/time.h> 
struct timeval tv; 
gettimeofday(&tv,NULL); 
tv.tv_sec // seconds 
tv.tv_usec // microseconds 
0

U puede probar rutinas de biblioteca de tiempo de c (time.h). Además, eche un vistazo al clock() en la misma lib. Da los tics de reloj desde que el programa ha comenzado. Pero puede guardar su valor antes de la operación en la que desea concentrarse, y luego de esa operación capturar las marcas cliock nuevamente y encontrar la diferencia entre ellas para obtener la diferencia de tiempo. código

3

Uso @Arkaitz de Jiménez para obtener dos timevals: Código

#include <sys/time.h> 
//... 
struct timeval tv1, tv2, diff; 

// get the first time: 
gettimeofday(&tv1, NULL); 

// do whatever it is you want to time 
// ... 

// get the second time: 
gettimeofday(&tv2, NULL); 

// get the difference: 

int result = timeval_subtract(&diff, &tv1, &tv2); 

// the difference is storid in diff now. 

muestra para timeval_subtract se puede encontrar en this web site:

/* Subtract the `struct timeval' values X and Y, 
    storing the result in RESULT. 
    Return 1 if the difference is negative, otherwise 0. */ 

int 
timeval_subtract (result, x, y) 
     struct timeval *result, *x, *y; 
{ 
    /* Perform the carry for the later subtraction by updating y. */ 
    if (x->tv_usec < y->tv_usec) { 
    int nsec = (y->tv_usec - x->tv_usec)/1000000 + 1; 
    y->tv_usec -= 1000000 * nsec; 
    y->tv_sec += nsec; 
    } 
    if (x->tv_usec - y->tv_usec > 1000000) { 
    int nsec = (x->tv_usec - y->tv_usec)/1000000; 
    y->tv_usec += 1000000 * nsec; 
    y->tv_sec -= nsec; 
    } 

    /* Compute the time remaining to wait. 
     tv_usec is certainly positive. */ 
    result->tv_sec = x->tv_sec - y->tv_sec; 
    result->tv_usec = x->tv_usec - y->tv_usec; 

    /* Return 1 if result is negative. */ 
    return x->tv_sec < y->tv_sec; 
} 
+0

El código en timeval_subtract es malo porque modifica el valor de entrada y. No sería malo si las entradas fueran dos valores struct timeval, a diferencia de los punteros. Pero cuando evalúa 'x - y', normalmente no espera que el cálculo altere el valor almacenado en 'y'. –

+0

@Jonathan, cierto. Aunque simplemente cambiarlo a una implementación de paso a paso resolvería ese problema – Glen

+0

Estoy de acuerdo. Lo arreglaría, pero no puedo volver a verificar que mis cambios se compilarían en este momento, así que pensé que lo dejaría como está. – Bill

6

Si usted quiere encontrar el tiempo transcurrido, este método funcionará siempre y cuando no reinicies la computadora entre el inicio y el final.

En Windows, use GetTickCount(). Así es como:

DWORD dwStart = GetTickCount(); 
... 
... process you want to measure elapsed time for 
... 
DWORD dwElapsed = GetTickCount() - dwStart; 

dwElapsed es ahora el número de milisegundos transcurridos.

En Linux, utilice reloj() y CLOCKS_PER_SEC hacer de la misma cosa.

Si necesita marcas de tiempo que duren por medio de reinicios o en PC (que en realidad necesitarían una sincronización bastante buena), utilice los otros métodos (gettimeofday()).

Además, en Windows al menos se puede conseguir mucho mejor que el tiempo de resolución estándar. Normalmente, si llamabas a GetTickCount() en un bucle cerrado, lo veías saltando 10-50 cada vez que cambiaba. Eso se debe al quantum de tiempo utilizado por el programador de subprocesos de Windows. Esta es más o menos la cantidad de tiempo que le da a cada hilo ejecutar antes de cambiar a otra cosa. Si lo hace un:

timeBeginPeriod(1); 

al comienzo de su programa o proceso y a:

timeEndPeriod(1); 

al final, entonces la cuántica cambiará a 1 ms, y obtendrá mucho mejor tiempo resolución en la llamada GetTickCount(). Sin embargo, esto crea un sutil cambio de la forma de todo el equipo ejecuta los procesos, así que tenlo en cuenta. Sin embargo, Windows Media Player y muchas otras cosas hacen de manera rutinaria de todos modos, así que no se preocupe demasiado acerca de él.

Estoy seguro de que hay alguna forma de hacer lo mismo en Linux (probablemente con mucho mejor control, o quizás con quantums de menos de milisegundos) pero no he necesitado hacerlo todavía en Linux.

8

estándar C99:

#include <time.h> 

time_t t0 = time(0); 
// ... 
time_t t1 = time(0); 
double datetime_diff_ms = difftime(t1, t0) * 1000.; 

clock_t c0 = clock(); 
// ... 
clock_t c1 = clock(); 
double runtime_diff_ms = (c1 - c0) * 1000./CLOCKS_PER_SEC; 

La precisión de los tipos es definido por la implementación, es decir, la diferencia de fecha y hora sólo se puede devolver segundos completos.

+0

La diferencia de fecha y hora devuelve, en el mejor de los casos, segundos completos. Si interpreté el estándar correctamente, time(), cuando no devuelve (time_t) -1, no garantiza devolver nuevos valores cada segundo: puede tener una resolución de 5 segundos o 1 minuto, por ejemplo. – pmg

+2

@pmg: la precisión está definida por implementaciones, por ejemplo, en mi sistema 'time()' tiene una resolución '1s'; la precisión de 'clock()' es normalmente lo más alta posible, pero mide el tiempo de ejecución y no el datetime – Christoph

1

También tomando conciencia de las interacciones entre clock() y usleep(). usleep() suspende el programa y clock() solo mide el tiempo de ejecución del programa.

Si pudiera estar mejor utilizar gettimeofday() como se ha mencionado here

5
/* 
Returns the current time. 
*/ 

char *time_stamp(){ 

char *timestamp = (char *)malloc(sizeof(char) * 16); 
time_t ltime; 
ltime=time(NULL); 
struct tm *tm; 
tm=localtime(&ltime); 

sprintf(timestamp,"%04d%02d%02d%02d%02d%02d", tm->tm_year+1900, tm->tm_mon, 
    tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); 
return timestamp; 
} 


int main(){ 

printf(" Timestamp: %s\n",time_stamp()); 
return 0; 

} 

de salida: Hora: 20110912130940 // 2011 Sep 12 13:09:40

+0

En vez de formatear los datos, puede usar asctime (tm) que devuelve una cadena. –

2

¿qué hay de esta solución? No vi nada como esto en mi búsqueda. Estoy tratando de evitar la división y simplificar la solución.

struct timeval cur_time1, cur_time2, tdiff; 

    gettimeofday(&cur_time1,NULL); 
    sleep(1); 
    gettimeofday(&cur_time2,NULL); 

    tdiff.tv_sec = cur_time2.tv_sec - cur_time1.tv_sec; 
    tdiff.tv_usec = cur_time2.tv_usec + (1000000 - cur_time1.tv_usec); 

    while(tdiff.tv_usec > 1000000) 
    { 
     tdiff.tv_sec++; 
     tdiff.tv_usec -= 1000000; 
     printf("updated tdiff tv_sec:%ld tv_usec:%ld\n",tdiff.tv_sec, tdiff.tv_usec); 
    } 

    printf("end tdiff tv_sec:%ld tv_usec:%ld\n",tdiff.tv_sec, tdiff.tv_usec); 
Cuestiones relacionadas