394 votes

System.currentTimeMillis vs System.nanoTime

L'Exactitude De La Vs. Précision

Ce que je voudrais savoir c'est si je dois utiliser le Système.currentTimeMillis() ou Système.nanoTime() lors de la mise à jour de mon objet de positions dans mon jeu? Leur changement dans le mouvement est directement proportionnelle au temps écoulé depuis le dernier appel et je veux être aussi précis que possible.

J'ai lu qu'il y a quelques temps de résolution des problèmes entre les différents systèmes d'exploitation (Mac / Linux ont presque pas de 1 ms alors que Windows dispose d'un 50ms résolution??). Je suis surtout l'exécution de mes applications sur windows et 50ms résolution semble assez imprécise.

Sont t-il de meilleures options que les deux que j'ai énumérés?

Toutes les suggestions / commentaires?

333voto

dancavallaro Points 5639

Si vous êtes simplement à la recherche pour effectuer des mesures extrêmement précises de temps écoulé, utilisez System.nanoTime(). System.currentTimeMillis() vous donnera le plus de précision possible le temps écoulé en millisecondes écoulées depuis l'époque, mais System.nanoTime() vous donne un ordre de la nanoseconde-temps précis, par rapport à un point arbitraire.

À partir de la Documentation de Java:

public static long nanoTime()

Retourne la valeur courante de la mesure la plus précise disponible système de minuterie, en nanosecondes.

Cette méthode ne peut être utilisée pour mesurer le temps écoulé et n'est pas liés à toute autre notion de système ou l'horloge murale. La valeur retournée représente nanosecondes depuis quelques fixe, mais de temps arbitraire (peut-être dans l'avenir, de sorte que les valeurs peuvent être négatif). Cette méthode permet d' une précision à la nanoseconde, mais pas nécessairement précision de l'ordre de la nanoseconde. Pas de les garanties sont faites sur la façon de souvent les valeurs changent. Les différences dans les appels successifs qui s'étendent sur une plus grande moins d'environ 292 ans (263 nanosecondes) ne sera pas avec précision calculer le temps écoulé en raison de numérique dépassement de capacité.

Par exemple, pour mesurer combien de temps un peu de code nécessaire à l'exécution:

long startTime = System.nanoTime();    
// ... the code being measured ...    
long estimatedTime = System.nanoTime() - startTime;

Voir aussi: JavaDoc Système.nanoTime() et JavaDoc Système.currentTimeMillis() pour plus d'info.

108voto

jgubby Points 1630

Comme aucun autre n'a mentionné cela, il n'est pas sûr de comparer les résultats des appels System.nanoTime () entre différents threads. Même si les événements des Threads se déroulent dans un ordre prévisible, la différence en nanosecondes peut être positive ou négative.

System.currentTimeMillis () est sûr pour une utilisation entre threads.

59voto

Michael Burr Points 181287

David Holmes de Soleil publié un article de blog il y a quelques années qui a une très détaillé oeil à la Java calendrier des Api (en particulier System.currentTimeMillis() et System.nanoTime()), lorsque vous souhaitez utiliser, et comment ils fonctionnent en interne.

À l'intérieur de la zone sensible de la VM: Horloges, Minuteries et la Planification d'Événements - Partie I - Windows

Un aspect très intéressant de la minuterie utilisée par Java sur Windows pour les Api qui ont un temps d'attente paramètre est que la résolution de la minuterie peut changer en fonction de ce que les autres appels de l'API peuvent avoir été réalisés à l'échelle du système (et pas seulement dans le processus particulier). Il montre un exemple où l'utilisation d' Thread.sleep() sera la cause de ce changement de résolution.

13voto

KarlU Points 66

Comme d'autres l'ont dit, currentTimeMillis est le temps de l'horloge, qui change en raison de l'heure d'été, les utilisateurs de changer les réglages de l'heure, les secondes intercalaires, et internet synchronisation de l'heure. Si votre application dépend de plus en plus monotone temps écoulé valeurs, vous pourriez préférer nanoTime à la place.

Vous pourriez penser que les joueurs ne seront pas à jouer avec les paramètres de temps de jeu pendant le jeu, et peut-être que vous avez raison. Mais ne sous-estimez pas la perturbation due à internet synchronisation de l'heure, ou peut-être les utilisateurs du bureau à distance. Le nanoTime API est à l'abri de ce genre de perturbation.

Si vous voulez utiliser le temps de l'horloge, mais éviter les discontinuités en raison de l'internet synchronisation de temps, vous pourriez envisager un client NTP comme Meinberg, "airs" de la fréquence d'horloge à zéro, au lieu de simplement remettre le compteur à zéro périodiquement.

Je parle par expérience personnelle. Dans une application météo que j'ai développé, j'ai été prise en apparaissant au hasard de la vitesse du vent pointes. Il a fallu un certain temps pour me rendre compte que ma base de temps a été perturbé par le comportement de l'horloge de temps sur un ordinateur classique. Tous mes problèmes ont disparu quand j'ai commencé à utiliser nanoTime. La cohérence (monotonie) était plus important de ma demande de crue de la précision ou l'exactitude absolue.

11voto

Paul Morel Points 450

System.nanoTime () n'est pas pris en charge dans les machines JVM plus anciennes. Si cela vous préoccupe, respectez le currentTimeMillis

En ce qui concerne la précision, vous avez presque raison. Sur QUELQUES machines Windows, currentTimeMillis () a une résolution d'environ 10 ms (pas 50 ms). Je ne sais pas pourquoi, mais certaines machines Windows sont aussi précises que les machines Linux.

J'ai utilisé GAGETimer dans le passé avec un succès modéré.

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