2010-10-15 14 views
24

Estoy tratando de medir cuánto tiempo tarda una función.Tiempo de medición tomado por una función: clock_gettime

Tengo un pequeño problema: aunque trato de ser preciso y uso puntos flotantes, cada vez que imprimo mi código usando% lf obtengo una de dos respuestas: 1.000 ... o 0.000 .... Esto me lleva a preguntarse si el código es correcto:

#define BILLION 1000000000L; 

// Calculate time taken by a request 
struct timespec requestStart, requestEnd; 
clock_gettime(CLOCK_REALTIME, &requestStart); 
function_call(); 
clock_gettime(CLOCK_REALTIME, &requestEnd); 

// Calculate time it took 
double accum = (requestEnd.tv_sec - requestStart.tv_sec) 
    + (requestEnd.tv_nsec - requestStart.tv_nsec) 
/BILLION; 
printf("%lf\n", accum); 

la mayor parte de este código no se ha hecho por mí. Esta página de ejemplo tenía un código que ilustra el uso de clock_gettime: http://www.users.pjwstk.edu.pl/~jms/qnx/help/watcom/clibref/qnx/clock_gettime.html

¿Podría alguien decirme por favor qué es incorrecto, o por qué solo estoy obteniendo valores enteros, por favor?

Muchas gracias,

Jary

+11

No, no, no: Don' t dar nombres a los números. Use la función que sirven en su lugar: '#define CLOCK_PRECISION 1000000000L/* un billón * /' – pmg

+9

@pmg: Pedantry tangent: Yo diría que un nombre como 'CLOCK_PRECISION' solo sería necesario si las unidades no fueran claras desde el nombre de la variable. En el caso anterior, está claro por el nombre 'tv_nsec' que estamos en nanosegundos. Entonces 'NANOSECONDS_PER_SECOND' podría ser apropiado, pero eso no es muy diferente a simplemente' BILLION'. –

Respuesta

22

La división de un entero por un entero rinde un número entero. Pruebe esto:

#define BILLION 1E9 

Y no utilice un punto y coma al final de la línea. #define es una directiva de preprocesador, no una declaración, e incluir el punto y coma resultó en BILLION que se define como 1000000000L;, que se rompería si intentara usarlo en la mayoría de los contextos. Tuviste suerte porque la usaste al final de una expresión y fuera de cualquier paréntesis.

+2

Muchas gracias por su ayuda. Y gracias por informarme sobre el punto y coma, eso es algo que olvidé. ¡Muchas gracias! – Jary

+0

En aras del rendimiento .. #define ONE_OVER_BILLION 1E-9 y use multiply. – linleno

9

(requestEnd.tv_nsec - requestStart.tv_nsec) es de tipo entero, y siempre es menor que BILLION, por lo que el resultado de dividir uno por el otro en aritmética entera siempre será 0. Debe enviar el resultado de la resta a, p. double antes de dividir.

1

Tenga en cuenta que (requestEnd.tv_nsec - requestStart.tv_nsec) puede ser negativo, en cuyo caso debe restar 1 segundo de la diferencia tv_sec y agregar un BILLION a la diferencia tv_nsec.

0

Sé que la pregunta se publicó hace mucho tiempo, pero todavía no veo la respuesta que sugiera que "convierta" el tiempo transcurrido en nanosegundos (o milisegundos) y no en segundos como en el ejemplo del código.

El fragmento de código de ejemplo para ilustrar la idea:

long accum = (requestEnd.tv_nsec - requestStart.tv_nsec) 
+ (requestEnd.tv_sec - requestStart.tv_sec) * BILLION; 

esta manera se puede evitar la aritmética de coma, que puede ser pesado para algunas plataformas flotantes ...

Cuestiones relacionadas