moyen portable d’obtenir du temps

Étant donné que Mac OS X ne prend pas en charge l’obtention du temps, j’ai trouvé cet élément essentiel qui permettait d’utiliser le fonds clock_gettime de manière portable ici:

void current_utc_time(struct timespec *ts) { #ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time clock_serv_t cclock; mach_timespec_t mts; host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); clock_get_time(cclock, &mts); mach_port_deallocate(mach_task_self(), cclock); ts->tv_sec = mts.tv_sec; ts->tv_nsec = mts.tv_nsec; #else clock_gettime(CLOCK_REALTIME, ts); #endif } 

l’utiliser comme ça

 struct timespec requestStart; current_utc_time(&requestStart); printf("start: s: %lu\n", requestStart.tv_sec); printf("start: ns: %lu\n", requestStart.tv_nsec); start: s: 1435988139 start: ns: 202015000 

J’essaie d’obtenir les valeurs en secondes et en millisecondes de ce code. Est-ce la bonne façon d’obtenir des millisecondes à partir de la valeur en nanosecondes?

 printf("total: ms: %lu\n", (requestStart.tv_nsec - requestEnd.tv_nsec) / (unsigned long)1000000); 

Si oui, comment puis-je obtenir la valeur en secondes? Si non, comment puis-je obtenir la valeur en millisecondes et en secondes?

edit En réponse au premier commentaire, je recherche principalement un moyen de rendre le code aussi portable que possible.

Si vous voulez la portabilité, utilisez simplement gettimeofday . Cela devrait fonctionner partout. clock_gettime semble être une introduction relativement récente de Posix spécifique à Linux .

Lors de la conversion: struct timeval (utilisé par gettimeofday et d’autres fonctions plus anciennes) utilise des microsecondes. La plus récente struct timespec utilise des nanosecondes. Donc, pour convertir en arrière, vous multipliez ou divisez par 1000.

Lorsque vous calculez les différences, vous devez vous préoccuper des reports / débordements. Votre expression

 (requestStart.tv_nsec - requestEnd.tv_nsec) / (unsigned long)1000000 

est incorrect pour deux raisons: la différence peut être négative (c’est-à-dire si le temps passe de 123,456 à 124,321), et vous la redimensionnant trop.

Lorsque je chronomètre une opération, je le fais habituellement comme ceci:

 struct timeval before, after, elapsed; gettimeofday(&before, NULL); sleep(1); gettimeofday(&after, NULL); elapsed.tv_sec = after.tv_sec - before.tv_sec; if(after.tv_usec >= before.tv_usec) elapsed.tv_usec = after.tv_usec - before.tv_usec; else { elapsed.tv_sec--; elapsed.tv_usec = 1000000 + after.tv_usec - before.tv_usec; } printf("elapsed: %d.%06ld\n", (int)elapsed.tv_sec, (long)elapsed.tv_usec); 

Si je voulais ensuite une struct timespec (en nanosecondes), je multiplierais par 1000:

 struct timespec elapsed2; elapsed2.tv_sec = elapsed.tv_sec; elapsed2.tv_nsec = elapsed.tv_usec * 1000; printf("elapsed: %d.%09ld\n", (int)elapsed2.tv_sec, (long)elapsed2.tv_nsec); 

Pour reconvertir une struct timespec en une struct timeval , je struct timeval par 1000:

 struct timeval elapsed3; elapsed3.tv_sec = elapsed2.tv_sec; elapsed3.tv_usec = elapsed2.tv_nsec / 1000; 

Une autre chose utile est d’extraire les secondes et les sous-secondes en virgule flottante:

 double e = (double)elapsed.tv_sec + elapsed.tv_usec / 1e6; double e2 = (double)elapsed2.tv_sec + elapsed2.tv_nsec / 1e9; printf("float: %f %f\n", e, e2); 

(Il s’avère qu’il peut y avoir des subtilités lors de l’écriture de ce type de code, en fonction des types réels de tv_sec et tv_usec ou tv_nsec , et des avertissements “utiles” que votre compilateur peut choisir de vous donner. Voir cette question .)

 #import  #import  struct timeb timebCurrentTime; ftime(&timebCurrentTime); double y = (double)timebCurrentTime.time + (double)timebCurrentTime.millitm / 1000;//current time in sec since 1970-01-01 00:00:00 +0000 (UTC)