Outre la différence de précision, quelles sont les différences entre struct timeval
et struct timespec
? Si j'ai besoin de moins de précision que µs (disons, millisecondes), pourquoi devrais-je utiliser l'un sur l'autre?
Sur mon compilateur (gcc pour ARM):
/* POSIX.1b structure for a time value. This is like a `struct timeval' but
has nanoseconds instead of microseconds. */
struct timespec
{
__time_t tv_sec; /* Seconds. */
__syscall_slong_t tv_nsec; /* Nanoseconds. */
};
/* A time value that is accurate to the nearest
microsecond but also has a range of years. */
struct timeval
{
__time_t tv_sec; /* Seconds. */
__suseconds_t tv_usec; /* Microseconds. */
};
Avec __syscall_slong_t
et __suseconds_t
définis comme un "mot long".
Je pense que c'est vraiment juste une question de compatibilité API. Les appels POSIX-y tels que pselect()
et clock_gettime()
utilisent struct timespec
. Divers appels de systèmes de fichiers tels que utimes()
, et certains appels Linux variés tels que gettimeofday()
et select()
, utilisez struct timeval
. Généralement, à partir de quelques pages de manuel, je soupçonne que struct timeval
possède un héritage BSD, alors que struct timespec
correspond à POSIX.
Si vous effectuez des mesures d'intervalle, il n'y a aucune raison de ne pas tirer parti de la précision supplémentaire de clock_gettime()
- sachez que c'est généralement du matériel, pas le fichier d'en-tête, qui limite votre précision de mesure. Diviser par un million à des fins d’affichage n’est ni meilleur ni pire que de diviser par mille. De plus, Mac OS X ne prend pas en charge clock_gettime()
.
Mais si vous faites beaucoup de manipulations de fichiers, il serait peut-être plus judicieux d'utiliser le struct timeval
utilisé dans des API comme utimes()
. struct timeval
possède également des fonctions de comparaison sous Linux, BSD et Mac OS X, par exemple. timercmp()
, timersub()
(à nouveau, voir les pages de manuel).
Je prendrais la décision en fonction des API que vous avez l'intention d'utiliser, plutôt que des structures elles-mêmes. (Ou écrivez une classe wrapper avec des méthodes de conversion si nécessaire.)
Les deux sont AFAIK défini pour POSIX.1-2001, donc du point de vue de la portabilité, peu importe celui que vous utilisez. La réponse la plus simple est: utilisez celui que vous avez besoin pour l'API que vous souhaitez appeler.
Il pourrait y avoir un avantage de taille dépendant de la plate-forme utilisant struct timeval
:
Le type suseconds_t doit être un type entier signé Capable de stocker des valeurs au moins dans la plage [-1, 1000000].
dans struct timespec
, le deuxième membre est de type long
. Un int
suffirait sur une plate-forme 32 bits pour répondre aux exigences de suseconds_t
. Cependant, sur un système 64 bits, time_t
est généralement de 64 bits, forçant ainsi la structure à 16 octets de toute façon. Donc, un avantage de taille est - improbable.
Personnellement, je n'utilise ni l'un ni l'autre. Je préfère exprimer le temps sous la forme d'un simple int64_t
car cela simplifie énormément les calculs de temps. Si vous devez le faire, la reconversion en struct timeval
ou struct timespec
ne pose pas non plus de problème. Même si vous voulez une précision de nanosecondes, int64_t
peut exprimer une durée de presque 585 ans. Si vous avez juste besoin de quelques millisecondes, vous avez une durée de presque 585 millions d'années.