Précision contre. Précision
Ce que je voudrais savoir, c'est si je dois utiliser System.currentTimeMillis () ou System.nanoTime () lors de la mise à jour des positions de mon objet dans mon jeu? Leur changement de mouvement est directement proportionnel au temps écoulé depuis le dernier appel et je veux être aussi précis que possible.
J'ai lu qu'il existe de sérieux problèmes de résolution temporelle entre différents systèmes d'exploitation (à savoir que Mac / Linux ont une résolution de près de 1 ms tandis que Windows a une résolution de 50 ms ??). J'exécute principalement mes applications sur Windows et la résolution de 50 ms semble assez inexacte.
Y a-t-il de meilleures options que les deux que j'ai énumérées?
Des suggestions / commentaires?
java
timer
time-precision
mmcdole
la source
la source
nanoTime
est généralement plus précis que currentTimeMillis mais c'est aussi un appel relativement cher.currentTimeMillis()
fonctionne sur quelques (5-6) horloges cpu, nanoTime dépend de l'architecture sous-jacente et peut être plus de 100 horloges cpu.System.currentTimeMillis()
: pzemtsov.github.io/2017/07/23/the-slow-currenttimemillis.htmlRéponses:
Si vous recherchez simplement des mesures extrêmement précises du temps écoulé , utilisez
System.nanoTime()
.System.currentTimeMillis()
vous donnera le temps écoulé le plus précis possible en millisecondes depuis l'époque, maisSystem.nanoTime()
vous donne un temps précis en nanosecondes, par rapport à un point arbitraire.De la documentation Java:
Par exemple, pour mesurer la durée d'exécution d'un code:
Voir aussi: JavaDoc System.nanoTime () et JavaDoc System.currentTimeMillis () pour plus d'informations.
la source
currentTimeMillis
changerait-il en raison de l'heure d'été? Le commutateur DST ne change pas le nombre de secondes après l'époque. Il peut s'agir d'une "horloge murale", mais elle est basée sur UTC. Vous devez déterminer en fonction de votre fuseau horaire et des paramètres DST ce que cela signifie pour votre heure locale (ou utiliser d'autres utilitaires Java pour le faire pour vous).Puisque personne d'autre ne l'a mentionné…
Il n'est pas sûr de comparer les résultats des
System.nanoTime()
appels entre différents threads. Même si les événements des threads se produisent 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 les threads.la source
The values returned by this method become meaningful only when the difference between two such values, obtained within the same instance of a Java virtual machine, is computed.
nanoTime()
dit: La même origine est utilisée par toutes les invocations de cette méthode dans une instance d'une machine virtuelle Java; d'autres instances de machine virtuelle sont susceptibles d'utiliser une origine différente. ce qui signifie qu'il ne retourner les mêmes dans les discussions.Mise à jour d' Arkadiy : j'ai observé un comportement plus correct de
System.currentTimeMillis()
Windows 7 dans Oracle Java 8. L'heure a été renvoyée avec une précision d'une milliseconde. Le code source dans OpenJDK n'a pas changé, donc je ne sais pas ce qui cause le meilleur comportement.David Holmes de Sun a publié il y a quelques années un article de blog qui présente de manière très détaillée les API de synchronisation Java (en particulier
System.currentTimeMillis()
etSystem.nanoTime()
), quand vous souhaitez les utiliser et comment elles fonctionnent en interne.À l'intérieur de la machine virtuelle Hotspot: horloges, minuteurs et événements de planification - Partie I - Windows
Un aspect très intéressant du minuteur utilisé par Java sur Windows pour les API qui ont un paramètre d'attente temporisée est que la résolution du minuteur peut changer en fonction des autres appels d'API qui ont été effectués - à l'échelle du système (pas seulement dans le processus particulier) . Il montre un exemple où l'utilisation
Thread.sleep()
entraînera ce changement de résolution.la source
GetSystemTimeAsFileTime
fonctionnement dans XP vs 7. Voir ici pour plus de détails (tl; dr il est devenu plus précis depuis que le système entier a introduit des méthodes de chronométrage plus précises).System.nanoTime()
n'est pas pris en charge dans les anciennes machines virtuelles Java. Si cela vous préoccupe, restez aveccurrentTimeMillis
Concernant la précision, vous avez presque raison. Sur CERTAINES machines Windows,
currentTimeMillis()
a une résolution d'environ 10 ms (et non 50 ms). Je ne sais pas pourquoi, mais certaines machines Windows sont tout aussi précises que les machines Linux.J'ai utilisé GAGETimer dans le passé avec un succès modéré.
la source
Comme d'autres l'ont dit, currentTimeMillis est l'heure de l'horloge, qui change en raison de l'heure d'été, des utilisateurs changeant les paramètres de l'heure, des secondes intercalaires et de la synchronisation de l'heure Internet. Si votre application dépend de l'augmentation monotone des valeurs de temps écoulé, vous préférerez peut-être nanoTime à la place.
Vous pourriez penser que les joueurs ne joueront pas avec les paramètres de temps pendant le jeu, et peut-être auriez-vous raison. Mais ne sous-estimez pas la perturbation due à la synchronisation de l'heure Internet, ou peut-être aux utilisateurs de postes de travail distants. L'API nanoTime est à l'abri de ce type de perturbation.
Si vous souhaitez utiliser l'heure de l'horloge, mais évitez les discontinuités dues à la synchronisation de l'heure sur Internet, vous pouvez envisager un client NTP tel que Meinberg, qui "ajuste" la fréquence d'horloge pour la mettre à zéro, au lieu de simplement réinitialiser l'horloge périodiquement.
Je parle d'expérience personnelle. Dans une application météo que j'ai développée, j'obtenais des pointes de vitesse du vent aléatoires. Il m'a fallu un certain temps pour réaliser que ma base de temps était perturbée par le comportement de l'horloge sur un PC typique. Tous mes problèmes ont disparu lorsque j'ai commencé à utiliser nanoTime. La cohérence (monotonie) était plus importante pour mon application que la précision brute ou la précision absolue.
la source
System.currentTimeMillis()
rapporte le temps écoulé (en millisecondes) depuis l'époque Unix / Posix qui est minuit, le 1er janvier 1970 UTC. Étant donné que l'UTC n'est jamais ajusté pour l'heure d'été, cette valeur ne sera pas compensée lorsque les fuseaux horaires locaux ajoutent ou soumettent des décalages aux heures locales pour l'heure d'été. De plus, l'échelle de temps Java adoucit les secondes intercalaires de sorte que les jours semblent continuer à compter 86 400 secondes.Oui, si une telle précision est requise, utilisez
System.nanoTime()
, sachez que vous avez alors besoin d'une JVM Java 5+.Sur mes systèmes XP, je vois l'heure système signalée à au moins
100 microsecondes278 nanosecondes en utilisant le code suivant:la source
Pour des graphiques de jeu et des mises à jour de position fluides, utilisez
System.nanoTime()
plutôt queSystem.currentTimeMillis()
. Je suis passé de currentTimeMillis () à nanoTime () dans un jeu et j'ai obtenu une amélioration visuelle majeure de la fluidité du mouvement.Alors qu'une milliseconde peut sembler être déjà précise, visuellement ce n'est pas le cas. Les facteurs
nanoTime()
peuvent s'améliorer, notamment:Comme d'autres réponses le suggèrent, nanoTime a un coût de performance s'il est appelé à plusieurs reprises - il serait préférable de l'appeler une seule fois par trame et d'utiliser la même valeur pour calculer la trame entière.
la source
J'ai une bonne expérience avec le nanotime . Il fournit une horloge murale en deux longs (secondes depuis l'époque et nanosecondes dans cette seconde), en utilisant une bibliothèque JNI. Il est disponible avec la partie JNI précompilée pour Windows et Linux.
la source
System.currentTimeMillis()
n'est pas sûr pour le temps écoulé car cette méthode est sensible aux changements d'horloge en temps réel du système. Tu devrais utiliserSystem.nanoTime
. Veuillez consulter l'aide de Java System:À propos de la méthode nanoTime:
Si vous utilisez
System.currentTimeMillis()
votre temps écoulé peut être négatif (Retour <- vers le futur)la source
une chose ici est l'incohérence de la méthode nanoTime.il ne donne pas de valeurs très cohérentes pour la même entrée.currentTimeMillis fait beaucoup mieux en termes de performances et de cohérence, et aussi, bien que pas aussi précis que nanoTime, a une marge d'erreur inférieure , et donc plus de précision dans sa valeur. je vous suggère donc d'utiliser currentTimeMillis
la source