Verwirrender Game Loop

BrknDevee

Mitglied
Guten Abend allerseits,
ich sitze momentan an einem etwas größeren Spiel und hänge gerade am Game Loop.
Das while(true) im folgenden Code wird später selbstverständlich durch etwas angemessenes ersetzt. Mir geht es momentan darum, dass wenn ich die vergangene Zeit bei jeder Iteration ausgebe, sinnvolle Werte herauskommen, aber sobald ich die Werte jede Sekunde ausgebe, kommen sehr unterschiedliche und unsinnige Zahlen heraus. (Ausschnitt: 0, 321, 0, 320, 0, 321, 31753, 0, 0, 321, 0- normal wären bei meinem Computer Zahlen um die 2500)

Java:
public static void main(String[] args) {
       
        long lastTime = System.nanoTime();
        long time_now = 0;
        long dt = 0;
       
        long timer = System.currentTimeMillis();
       
        while(true) {
            time_now = System.nanoTime();
            dt = time_now - lastTime;
            lastTime = time_now;
           
            if(System.currentTimeMillis() >= (timer + 1000)) {
                System.out.println("dt: " + dt + "ns");
                timer = System.currentTimeMillis();
            }
        }
    }
 
Java:
public class Hauptprogramm {

    public static void main(String[] args) {

        long lastTime = System.nanoTime();
        long timer = System.currentTimeMillis();

        while (true) {

            if (System.currentTimeMillis() >= (timer + 1000)) {
                System.out.println("dt: " + (System.nanoTime() - lastTime) + "ns");
                timer = System.currentTimeMillis();
            }

            lastTime = System.nanoTime();
        }
    }

}

Ausgabe:
dt: 311127ns
dt: 692861ns
dt: 10195ns
dt: 3020ns
dt: 3398ns
dt: 10195ns
dt: 13971ns
dt: 3398ns
dt: 3399ns
dt: 3776ns
dt: 3775ns
dt: 5664ns
dt: 4531ns
dt: 7930ns
dt: 4909ns
dt: 4909ns
dt: 9062ns
dt: 12083ns
dt: 12083ns
dt: 9062ns
dt: 4531ns
 
Zuletzt bearbeitet:
Hier sind die ausgegebenen Zahlen kleiner:
Java:
public class Hauptprogramm {

    public static void main(String[] args) {

        long lastTime = System.nanoTime();
        long timer = System.nanoTime();

        while (true) {

            if (System.nanoTime() >= (timer + 1000000000)) {
                System.out.println("dt: " + (System.nanoTime() - lastTime) + "ns");
                timer = System.nanoTime();
            }

            lastTime = System.nanoTime();
        }
    }
}

Ausgabe:
dt: 121204ns
dt: 20389ns
dt: 1133ns
dt: 11327ns
dt: 1510ns
dt: 1888ns
dt: 1888ns
dt: 4153ns
dt: 106101ns
dt: 1511ns
dt: 1888ns
 
Zuletzt bearbeitet:
Das while(true) im folgenden Code wird später selbstverständlich durch etwas angemessenes ersetzt. Mir geht es momentan darum, dass wenn ich die vergangene Zeit bei jeder Iteration ausgebe, sinnvolle Werte herauskommen, aber sobald ich die Werte jede Sekunde ausgebe, kommen sehr unterschiedliche und unsinnige Zahlen heraus. (Ausschnitt: 0, 321, 0, 320, 0, 321, 31753, 0, 0, 321, 0- normal wären bei meinem Computer Zahlen um die 2500)
Wie kommst du drauf, dass 2500 bei deinem Computer normal wären?

Was der Code misst ist ein Schleifendurchlauf. In den meisten Fällen ist die if-Bedingung falsch, das was Zeit braucht, ist also nur das Zeit messen und die Bedingung.

Die Zeit, die System.nanoTime(), wird unter Windows afaik alle ca. 300ns aktualisiert.
Liegen die beiden Aufrufe näher zusammen, ergibt das 0, liegen sie weiter auseinander eben die 320.
31753ns dürfte der Schleifendurchlauf mit Ausgabe der Zeit dauern, wenn die Bedingung zutrifft (uU lief in dem Moment aber auch noch was anderes, was viel Zeit brauchte)

[0, 321, 0, 320, 0, 321, 31753, 0, 0, 321, 0] ist also ziemlich genau das Erwartbare.
 
Wie kommst du drauf, dass 2500 bei deinem Computer normal wären?
Naja, wenn ich das hier schreibe:
Java:
public static void main(String[] args) {
     
        long lastTime = System.nanoTime();
        long time_now = 0;
        long dt = 0;
     
        long timer = System.currentTimeMillis();
     
        while(true) {
            time_now = System.nanoTime();
            dt = time_now - lastTime;
            lastTime = time_now;
         
            if(System.currentTimeMillis() >= (timer + 1000)) {
                System.out.println("dt: " + dt + "ns");
                timer = System.currentTimeMillis();
            }
        }
    }
Kommen die genannten Zahlen heraus, bei
Java:
public static void main(String[] args) {
    
        long lastTime = System.nanoTime();
        long time_now = 0;
        long dt = 0;
    
        while(true) {
            time_now = System.nanoTime();
            dt = time_now - lastTime;
            lastTime = time_now;
        
            System.out.println("dt: " + dt + "ns");
        }
    }
aber kommen Zahlen um die 2500 heraus.

Was der Code misst ist ein Schleifendurchlauf. In den meisten Fällen ist die if-Bedingung falsch, das was Zeit braucht, ist also nur das Zeit messen und die Bedingung.

Die Zeit, die System.nanoTime(), wird unter Windows afaik alle ca. 300ns aktualisiert.
Liegen die beiden Aufrufe näher zusammen, ergibt das 0, liegen sie weiter auseinander eben die 320.
31753ns dürfte der Schleifendurchlauf mit Ausgabe der Zeit dauern, wenn die Bedingung zutrifft (uU lief in dem Moment aber auch noch was anderes, was viel Zeit brauchte)

[0, 321, 0, 320, 0, 321, 31753, 0, 0, 321, 0] ist also ziemlich genau das Erwartbare.
Die Erklärung ergibt aber Sinn. Wenn ich also noch rendere, etc. werden die Zahlen dann wohl sinnvoller

Vielen Dank an euch beide auf jeden Fall 🙂
 
In deinen beiden Codes machst du unterschiedliche Dinge:
im einen jedes Mal die Dauer ausgeben und das Ausgaben damit auch mitmessen (und Ausgaben ist ziemlich langsam), im anderen nur selten die Dauer ausgeben, und damit nur die reine Zeitmessung messen, was ziemlich schnell geht.
 
Bei meinem Programmen sind die Zahlen größer, weil ich dt erst innerhalb der if-Abfrage berechne. Der Kopf der If-Abfrage verursacht Rechenaufwand.

Wenn ich also noch rendere, etc. werden die Zahlen dann wohl sinnvoller
Die Zahlen sind sinnvoll. Satt 0 ist halt in Wirklichkeit "Zwischen 0 und 300" gemeint. Es zeigt trotzdem, dass der Computer die Befehle super schnell ausführt.
Mit 321 ist in Wirklichkeit "321 +- 300" gemeint.
Mit 31753 ist in Wirklichkeit "31753 +- 300" gemeint.
 

Neue Themen


Zurück
Oben