416 Stimmen

System.currentTimeMillis vs. System.nanoTime

Genauigkeit vs. Präzision

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

Ich habe gelesen, dass es einige ernsthafte Probleme mit der Zeitauflösung zwischen verschiedenen Betriebssystemen gibt (nämlich dass Mac/Linux eine Auflösung von fast 1 ms hat, während Windows eine Auflösung von 50 ms hat). Ich bin in erster Linie läuft meine Anwendungen auf Windows und 50ms Auflösung scheint ziemlich ungenau.

Gibt es bessere Möglichkeiten als die beiden von mir genannten?

Irgendwelche Vorschläge/Kommentare?

5voto

Lawrence Dol Punkte 61053

Ja, wenn eine solche Genauigkeit erforderlich ist, verwenden Sie System.nanoTime() aber beachten Sie, dass Sie dann eine Java 5+ JVM benötigen.

Auf meinen XP-Systemen wird die Systemzeit auf mindestens 100 Mikrosekunden 278 Nanosekunden unter Verwendung des folgenden Codes:

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)); }
    }

4voto

Thomas W Punkte 13662

Für Spielgrafiken und reibungslose Positionsaktualisierungen, verwenden Sie System.nanoTime() statt System.currentTimeMillis() . Ich habe in einem Spiel von currentTimeMillis() zu nanoTime() gewechselt und eine wesentliche visuelle Verbesserung der Glattheit der Bewegung erzielt.

Eine Millisekunde mag zwar so aussehen, als ob sie bereits präzise sein müsste, aber das ist sie nicht. Die Faktoren nanoTime() verbessern können, sind:

  • genaue Pixelpositionierung unterhalb der Wandtaktauflösung
  • die Möglichkeit, zwischen Pixeln Anti-Alias zu verwenden, wenn Sie dies wünschen
  • Ungenauigkeit der Windows-Wanduhr
  • Clock Jitter (Unstimmigkeit, wann die Wanduhr tatsächlich vorwärts tickt)

Wie andere Antworten andeuten, hat nanoTime einen Leistungsverlust, wenn es wiederholt aufgerufen wird - es wäre am besten, es nur einmal pro Frame aufzurufen und denselben Wert zur Berechnung des gesamten Frames zu verwenden.

2voto

Ricardo Gasca Punkte 1297

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

Über die nanoTime-Methode:

.. Diese Methode bietet eine Genauigkeit im Nanosekundenbereich, aber nicht unbedingt Nanosekunden-Auflösung (d. h. wie häufig sich der Wert ändert) - keine Garantien werden gegeben, außer dass die Auflösung mindestens so gut ist wie die von currentTimeMillis().

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

1voto

Jon Bright Punkte 13050

Ich habe gute Erfahrungen gemacht mit nanotime . Es liefert die Wanduhrzeit in zwei Längen (Sekunden seit der Epoche und Nanosekunden innerhalb dieser Sekunde) und verwendet eine JNI-Bibliothek. Es ist mit dem JNI-Teil vorkompiliert für Windows und Linux verfügbar.

-3voto

sarvesh Punkte 31

Eine Sache ist hier die Inkonsistenz der nanoTime-Methode. Sie liefert keine sehr konsistenten Werte für die gleiche Eingabe. currentTimeMillis schneidet in Bezug auf Leistung und Konsistenz viel besser ab und hat auch, obwohl nicht so präzise wie nanoTime, eine geringere Fehlerspanne und daher mehr Genauigkeit in seinem Wert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X