Frage

Genauigkeit Vs. Präzision

Was ich möchte wissen, ob ich verwenden sollte System.currentTimeMillis () oder System.nanoTime () , wenn mein Objekt der Positionen in meinem Spiel zu aktualisieren? Ihre Bewegungsänderung ist direkt proportional zu der verstrichenen Zeit seit dem letzten Aufruf und ich möchte so präzise wie möglich sein.

Ich habe gelesen, dass es einige ernsthafte Zeitauflösungsprobleme zwischen verschiedenen Betriebssystemen (nämlich, dass Mac / Linux haben eine fast 1 ms Auflösung, während Windows eine 50 ms Auflösung ?? hat). Ich meine apps auf Windows und 50ms Auflösung scheint ziemlich ungenau primarly ausgeführt wird.

Gibt es bessere Möglichkeiten als die beiden, die ich aufgelistet?

Anregungen / Kommentare?

War es hilfreich?

Lösung

Wenn Sie gerade für äußerst präzise Messungen von verstrichene Zeit , sondern System.nanoTime() suchen. System.currentTimeMillis() werden Sie die möglichst genaue verstrichene Zeit in Millisekunden seit Beginn der Epoche, aber System.nanoTime() gibt Ihnen eine Nanosekunde-genaue Zeit, relativ zu einem beliebigen Punkt.

Von der Java Dokumentation:

public static long nanoTime()
     

Gibt den aktuellen Wert der präziseste verfügbaren System-Timer, in Nanosekunden.

     

Diese Methode kann nur verwendet werden,   verstrichene Zeit messen und ist nicht   zu jedem anderen Begriff der systembezogenen   oder Wandtaktzeit. Der zurückgegebene Wert   stellt ns, da einige   feste aber beliebige Zeit (vielleicht in   die Zukunft kann so Wert sein   Negativ). Dieses Verfahren liefert   Nanosekunde Präzision, aber nicht   notwendigerweise Genauigkeit Nanosekunden. Nein   Garantien werden gemacht, wie   häufig Werte ändern. Unterschiede   in aufeinanderfolgenden Aufrufen, die größer umspannen   als etwa 292 Jahre (2 63   ns) nicht genau   verstrichene Zeit durch numerische Berechnung   Überlauf.

Zum Beispiel, zu messen, wie lange einige Code auszuführen nehmen:

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

Siehe auch: JavaDoc-System. Nanotime () und JavaDoc System.currentTimeMillis () für weitere Informationen.

Andere Tipps

Da sonst niemand hat dies erwähnt ...

Es ist nicht sicher, die Ergebnisse System.nanoTime() Anrufe zwischen verschiedenen Threads zu vergleichen. Auch wenn die Ereignisse der Fäden in einer vorhersagbaren Reihenfolge geschehen, kann die Differenz in ns positiv oder negativ sein.

System.currentTimeMillis() ist sicher für den Einsatz zwischen Threads.

Update von Arkadiy : Ich habe mehr das richtige Verhalten von System.currentTimeMillis() auf Windows 7 in Oracle Java beobachtet 8. Die Zeit wurde mit 1 Millisekunden-Genauigkeit zurückgegeben. Der Quellcode in OpenJDK hat sich nicht geändert, so weiß ich nicht, was das bessere Verhalten führt.


David Holmes von Sun schrieb einen Blog-Artikel vor ein paar Jahren, die an dem Java-Timing-APIs (insbesondere System.currentTimeMillis() und System.nanoTime()) einen sehr detaillierten Blick hat, wenn Sie wissen wollen, welche verwenden und wie sie funktionieren intern.

Innerhalb der Hotspot VM: Uhren, Timer und Scheduling Events - Teil I - Windows-

Ein sehr interessanter Aspekt des Timers von Java unter Windows für APIs verwendet, die eine zeitlich Warte Parameter haben, ist, dass die Auflösung des Timers kann in Abhängigkeit von ändern, was andere API-Aufrufe vorgenommen wurden - systemweit (und nicht nur in der insbesondere Prozess). Er zeigt ein Beispiel, wo Thread.sleep() verwendet, wird diese Auflösung Änderung führen.

System.nanoTime() nicht in älterer JVMs unterstützt. Wenn das ein Anliegen ist, bleibt currentTimeMillis

In Bezug auf Genauigkeit, sind Sie fast richtig. Auf einigen Windows-Maschinen, hat currentTimeMillis() eine Auflösung von etwa 10 ms (nicht 50ms). Ich bin mir nicht sicher, warum, aber einige Windows-Maschinen sind nur so genau wie Linux-Maschinen.

Ich habe verwendet GAGETimer in der Vergangenheit mit mäßigem Erfolg.

Wie andere gesagt haben, currentTimeMillis Taktzeit ist, die Sommerzeit aufgrund ändert, Benutzer die Zeiteinstellungen zu ändern, Schaltsekunden und Internet-Zeit synchronisiert. Wenn Ihre Anwendung abhängt monoton verstrichene Zeit Werte zu erhöhen, könnten es vorziehen, Sie Nanotime statt.

Man könnte denken, dass die Spieler nicht mit den Zeiteinstellungen während des Spiels werden Hantieren, und vielleicht haben Sie Recht. Aber unterschätzen Sie nicht die Unterbrechung wegen Internet-Zeitsynchronisation, oder vielleicht Remote-Desktop-Benutzer. Die Nanotime API ist auf diese Art von Störungen immun.

Wenn Sie Taktzeit verwenden möchten, aber aufgrund der Internet-Zeitsynchronisations Diskontinuitäten vermeiden, könnten Sie einen NTP-Client wie Meinberg betrachten, die „Melodien“ die Taktrate in auf Null, anstatt nur die Uhr regelmäßig zurückgesetzt wird.

Ich spreche aus eigener Erfahrung. In einer Wetter-Anwendung, die ich entwickeln, war ich immer zufällig Windgeschwindigkeit Spitzen auftreten. Es dauerte eine Weile für mich zu erkennen, dass mein Zeitbasis durch das Verhalten der Uhrzeit auf einem typischen PC gestört wurde. Alle meine Probleme verschwunden, als ich mit Nanotime gestartet. Konsistenz (Monotonie) wichtiger war meine Anwendung als rohe Präzision oder absolute Genauigkeit.

Ja, wenn eine solche Präzision Verwendung System.nanoTime() erforderlich, aber beachten Sie, dass Sie dann eine Java 5+ JVM erforderlich ist.

Auf meinen XP-Systemen, wie ich sehe Systemzeit zumindest berichtet 100 Mikrosekunden 278 ns mit dem folgenden Code:

private void test() {
    System.out.println("currentTimeMillis: "+System.currentTimeMillis());
    System.out.println("nanoTime         : "+System.nanoTime());
    System.out.println();

    testNano(false);                                                            // to sync with currentTimeMillis() timer tick
    for(int xa=0; xa<10; xa++) {
        testNano(true);
        }
    }

private void testNano(boolean shw) {
    long strMS=System.currentTimeMillis();
    long strNS=System.nanoTime();
    long curMS;
    while((curMS=System.currentTimeMillis()) == strMS) {
        if(shw) { System.out.println("Nano: "+(System.nanoTime()-strNS)); }
        }
    if(shw) { System.out.println("Nano: "+(System.nanoTime()-strNS)+", Milli: "+(curMS-strMS)); }
    }

Ich habe gute Erfahrungen gemacht mit Nanotime. Es stellt Wandtaktzeit als zwei longs (Sekunden seit der Epoche und ns innerhalb dieser Sekunde), eine JNI-Bibliothek. Es ist erhältlich mit dem Teil JNI vorkompilierte für Windows und Linux.

Für Spiel Grafiken & smooth Position Updates, Verwendung System.nanoTime() statt System.currentTimeMillis(). Ich wechselte von currentTimeMillis (), um Nanotime () in einem Spiel und bekam eine große visuelle Verbesserung der Glätte der Bewegung.

Während eine Millisekunde zu sein scheint, als ob es schon genau sein soll, visuell ist es nicht. Die Faktoren nanoTime() verbessern können gehören:

  • genaue Pixel Positionierung unter wanduhr Auflösung
  • Fähigkeit, Anti-Aliasing zwischen den Pixeln, wenn Sie wollen
  • Windows-wanduhr Ungenauigkeit
  • Takt-Jitter (Widersprüchlichkeit wenn wanduhr vorwärts tatsächlich Ticks)

Wie andere Antworten vorschlagen, hat Nanotime eine Leistungskosten haben, wenn wiederholt genannt -. Es wäre am besten, es zu nennen nur einmal pro Rahmen, und verwenden Sie den gleichen Wert den gesamten Rahmen zu berechnen

System.currentTimeMillis() ist für die verstrichene Zeit nicht sicher, da diese Methode der System Echtzeituhr Änderungen des Systems empfindlich ist. Sie sollten System.nanoTime verwenden. Bitte beachten Sie Java System-Hilfe:

Über Nanotime-Methode:

  

.. Diese Methode liefert Nanosekunde Präzision, aber nicht unbedingt   Nanosekunde Auflösung (das heißt, wie häufig der Wert ändert) - nein   Garantien werden gemacht, außer dass die Auflösung mindestens so gut wie   dass der currentTimeMillis () ..

Wenn Sie System.currentTimeMillis() Ihre verstrichene Zeit negativ sein kann (Back <- in die Zukunft)

eine Sache hier ist die Widersprüchlichkeit der Nanotime method.it gibt nicht sehr konsistente Werte für die gleiche input.currentTimeMillis nicht viel besser in Bezug auf Leistung und Konsistenz, und auch, wenn auch nicht so präzise wie Nanotime, ein niedrigeren Fehlermarge und damit eine höhere Genauigkeit in seinem Wert. Ich würde daher vorschlagen, dass Sie currentTimeMillis verwenden

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top