web-dev-qa-db-fra.com

Horodatage dans le langage de programmation C

Comment tamponner deux fois t1 et t2 et obtenir la différence en millisecondes en C?

23
Chris_45

Cela vous donnera le temps en secondes + microsecondes

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

Norme 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 précision des types est définie par l'implémentation, c'est-à-dire que la différence datetime peut ne renvoyer que des secondes entières.

9
Christoph
/*
 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;

}

Sortie: horodatage: 20110912130940 // 12 septembre 2011 13:09:40

6

Si vous souhaitez trouver le temps écoulé, cette méthode fonctionnera tant que vous ne redémarrez pas l'ordinateur entre le début et la fin.

Sous Windows, utilisez GetTickCount (). Voici comment:

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

dwElapsed est maintenant le nombre de millisecondes écoulées.

Sous Linux, utilisez clock () et CLOCKS_PER_SEC pour faire la même chose.

Si vous avez besoin d'horodatages qui durent pendant les redémarrages ou sur les PC (ce qui nécessiterait en effet une bonne synchronisation), utilisez les autres méthodes (gettimeofday ()).

En outre, sous Windows, vous pouvez obtenir au moins beaucoup mieux que la résolution temporelle standard. Habituellement, si vous appelez GetTickCount () dans une boucle étroite, vous le verriez sauter de 10 à 50 chaque fois qu'il change. Cela est dû au temps quantique utilisé par le planificateur de threads Windows. C'est plus ou moins le temps qu'il faut à chaque thread pour s'exécuter avant de passer à autre chose. Si vous faites:

timeBeginPeriod(1);

au début de votre programme ou processus et:

timeEndPeriod(1);

à la fin, le quantum passera à 1 ms et vous obtiendrez une bien meilleure résolution temporelle lors de l'appel GetTickCount (). Cependant, cela modifie subtilement la façon dont votre ordinateur exécute les processus, alors gardez cela à l'esprit. Cependant, Windows Media Player et bien d'autres choses le font systématiquement de toute façon, donc je ne m'inquiète pas trop à ce sujet.

Je suis sûr qu'il y a probablement un moyen de faire la même chose sous Linux (probablement avec un bien meilleur contrôle, ou peut-être avec des quantums inférieurs à la milliseconde) mais je n'ai pas encore eu besoin de le faire sous Linux.

6
darron

Utilisez le code de @Arkaitz Jimenez pour obtenir deux délais:

#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.

Un exemple de code pour timeval_subtract peut être trouvé sur ce site Web :

 /* 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;
 }
3
Bill

que diriez-vous de cette solution? Je n'ai rien vu de tel dans ma recherche. J'essaie d'éviter la division et de simplifier la solution.

   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);
2
n00pster

Rendre également compte des interactions entre clock () et usleep (). usleep () suspend le programme et clock () ne mesure que la durée d'exécution du programme.

Si vous préférez utiliser gettimeofday () comme mentionné ici

1
Venkat R
0
Nikolai Fetissov

U peut essayer des routines dans la bibliothèque de temps c ( time.h ). De plus, jetez un oeil à clock () dans la même bibliothèque. Il donne le tic-tac de l'horloge depuis le démarrage du prog. Mais vous pouvez enregistrer sa valeur avant l'opération sur laquelle vous souhaitez vous concentrer, puis après cette opération, capturez à nouveau les ticks de cliock et trouvez la différence entre les deux pour obtenir la différence de temps.

0
deostroll