250 votes

iPhone : Comment obtenir les millisecondes actuelles ?

Quelle est la meilleure façon d'obtenir l'heure actuelle du système en millisecondes ?

329voto

Allan Simonsen Points 1929

Si vous envisagez de l'utiliser pour un timing relatif (par exemple pour des jeux ou des animations), je préférerais utiliser

double CurrentTime = CACurrentMediaTime();

Ce qui est la voie recommandée ; NSDate s'appuie sur l'horloge de synchronisation du réseau et peut occasionnellement hoqueter lors de la re-synchronisation avec le réseau.

Allan

8 votes

Mais cela semble prendre le double du temps nécessaire pour [[NSDate date] timeIntervalSince1970]. J'ai mesuré 0.065ms vs. 0.033ms sur 15000 appels.

1 votes

Notez que vous devrez inclure le Framework Quartz et #import <Quartz/CABase.h> pour effectuer cet appel.

9 votes

Oups - c'est importé #import <QuartzCore/CAAnimation.h>

286voto

codelogic Points 22722

[[NSDate date] timeIntervalSince1970];

Elle renvoie le nombre de secondes depuis l'époque sous la forme d'un double. Je suis presque sûr que vous pouvez accéder aux millisecondes à partir de la partie fractionnaire.

5 votes

J'utilise cette méthode depuis un certain temps et je me suis rendu compte qu'elle peut retourner une valeur antérieure lorsque vous l'appelez après quelques millisecondes (par exemple, si vous l'appelez consécutivement, vous risquez de ne pas obtenir une séquence croissante).

5 votes

[NSDate timeIntervalSinceReferenceDate] est moins cher. (Bien qu'elle fasse référence à une "époque" différente - si vous voulez ajouter la constante NSTimeIntervalSince1970 .)

1 votes

TimeIntervalSince1970 est une propriété d'instance et non une méthode statique sur NSDate. Il faudrait donc encore écrire NSTimeInterval myInterval = [NSDate date].timeIntervalSince1970 ! !!

100voto

darrinm Points 2976

J'ai testé toutes les autres réponses sur un iPhone 4S et un iPad 3 (version de base). CACurrentMediaTime a le moins de frais généraux, et de loin. timeIntervalSince1970 est beaucoup plus lent que les autres, probablement à cause de NSDate surcharge d'instanciation, bien que cela puisse ne pas être important pour de nombreux cas d'utilisation.

Je recommande CACurrentMediaTime si vous voulez le moins de frais possible et si vous n'avez pas peur d'ajouter la dépendance du framework Quartz. Ou bien gettimeofday si la portabilité est une priorité pour vous.

iPhone 4S

CACurrentMediaTime: 1.33 us/call
gettimeofday: 1.38 us/call
[NSDate timeIntervalSinceReferenceDate]: 1.45 us/call
CFAbsoluteTimeGetCurrent: 1.48 us/call
[[NSDate date] timeIntervalSince1970]: 4.93 us/call

iPad 3

CACurrentMediaTime: 1.25 us/call
gettimeofday: 1.33 us/call
CFAbsoluteTimeGetCurrent: 1.34 us/call
[NSDate timeIntervalSinceReferenceDate]: 1.37 us/call
[[NSDate date] timeIntervalSince1970]: 3.47 us/call

1 votes

+1, Bien que cela soit évidemment très instructif et utile, je n'appellerais pas exactement cela un grand travail d'ingénierie sans voir le code source ;)

3 votes

Attention toutefois à ce problème : bendodson.com/weblog/2013/01/29/ca-current-media-time Cette horloge s'arrête apparemment lorsque l'appareil se met en veille.

1 votes

Il y a NSTimeIntervalSince1970 la macro qui est la plus rapide.

31voto

Tristan Lorach Points 331

Jusqu'à présent, j'ai trouvé gettimeofday une bonne solution sur iOS (iPad), lorsque vous souhaitez effectuer une évaluation d'intervalle (par exemple, le framerate, le timing d'une image de rendu...) :

#include <sys/time.h>
struct timeval time;
gettimeofday(&time, NULL);
long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000);

2 votes

J'aime bien ça aussi car c'est très portable. Notez que selon le système d'exploitation, vous devrez peut-être utiliser 'long long' au lieu de 'long' et convertir time.tv_sec en 'long long' avant de faire le reste du calcul.

0 votes

Static unsigned long getMStime(void) { struct timeval time ; gettimeofday(&time, NULL) ; return (time.tv_sec * 1000) + (time.tv_usec / 1000) ; }

0 votes

Il est intéressant de noter que cela fonctionne bien sur mon iPhone 5S et mon Mac mais renvoie une valeur erronée sur un iPad 3.

10voto

Tyler Points 16516

Il peut être utile de connaître les CodeTimestamps, qui fournissent une enveloppe autour des fonctions de synchronisation basées sur les machines. Vous obtenez ainsi des données temporelles d'une résolution de l'ordre de la nanoseconde - 1000000x plus précises que les millisecondes. Oui, un million de fois plus précises. (Les préfixes sont milli, micro, nano, chacun 1000x plus précis que le dernier.) Même si vous n'avez pas besoin de CodeTimestamps, jetez un coup d'œil au code (il est open source) pour voir comment ils utilisent mach pour obtenir les données temporelles. Cela pourrait être utile lorsque vous avez besoin de plus de précision et que vous souhaitez un appel de méthode plus rapide que l'approche NSDate.

http://eng.pulse.me/line-by-line-speed-analysis-for-ios-apps/

0 votes

Et vous aurez probablement besoin d'un -fno-objc-arc si vous utilisez l'ARC :)

1 votes

3 votes

Le code source lié à la page est ici : github.com/tylerneylon/moriarty

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X