web-dev-qa-db-fra.com

Temps de mesure pris par une fonction: clock_gettime

J'essaie de mesurer combien de temps une fonction prend.

J'ai un petit problème: bien que j'essaie d'être précis et d'utiliser des points flottants, chaque fois que j'imprime mon code avec% lf, j'obtiens l'une des deux réponses suivantes: 1 000 ... ou 0 000 ... Cela m'amène à me demander. si mon code est correct:

#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 plupart de ce code n'a pas été faite par moi. Cet exemple de page contenait du code illustrant l'utilisation de clock_gettime: http://www.users.pjwstk.edu.pl/~jms/qnx/help/watcom/clibref/qnx/clock_gettime.html

Quelqu'un pourrait-il me dire s'il vous plaît ce qui est incorrect ou pourquoi je n'obtiens que des valeurs entières, s'il vous plaît?

Merci beaucoup,

Jary

26
Jary

La division d'un entier par un entier donne un entier. Essaye ça:

#define BILLION 1E9

Et n'utilisez pas de point-virgule à la fin de la ligne. #define est une directive de préprocesseur, pas une instruction. L'inclusion du point-virgule a pour résultat que BILLION est défini en tant que 1000000000L;, ce qui se briserait si vous tentiez de l'utiliser dans la plupart des contextes. Vous avez eu de la chance parce que vous l'avez utilisé à la fin d'une expression et en dehors des parenthèses.

24
Marcelo Cantos

( requestEnd.tv_nsec - requestStart.tv_nsec ) est de type entier et est toujours inférieur à BILLION; le résultat de la division en arithmétique entière sera donc toujours 0. Vous devez convertir le résultat de la soustraction en exemple, par exemple. double avant de diviser.

9

Je sais que la question a été postée il y a longtemps, mais je ne vois toujours pas la réponse qui vous suggère de "convertir" le temps écoulé en nanosecondes (ou millisecondes) et non en secondes, comme dans votre exemple de code.

Le fragment de code exemple pour illustrer l'idée:

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

De cette façon, vous évitez les calculs arithmétiques en virgule flottante, qui peuvent être lourds pour certaines plates-formes ...

1
AntonK

Notez que (requestEnd.tv_nsec - requestStart.tv_nsec) peut être négatif, auquel cas vous devez soustraire 1 seconde de la différence tv_sec et ajouter un MILLIARD à la différence tv_nsec.

0
Wayfarer