Welcher Code ist schneller?

  • GM 8

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Welcher Code ist schneller?

    Hi! Da ich meinen Code so effektiv es geht schreiben will, wollte ich mal fragen welche der Code-Varienten schneller ist:

    GML-Quellcode

    1. a=irandom_range(1,3)



    1. Variante

    GML-Quellcode

    1. if a=1 {code 1}
    2. if a=2 {code 2}
    3. if a=3 {code 3}



    2. Variante

    GML-Quellcode

    1. switch (true)
    2. case a=1: code 1 break;
    3. case a=2: code 2 break;
    4. case a=3: code 3 break;


    Also quasi ob mehrere if-Abfragen schneller sind oder ein switch. Ich vermute, dass bei vielen verschiedenen Möglichkeiten der switch schneller ist. Trifft das aber auch wie in meinen Beispielen auch bei nur 2 oder 3 Sachen zu?

    Dann würde ich gerne noch wissen ob diese Schreibvarianten gleich schnell sind:

    1. Variante

    GML-Quellcode

    1. if a=1
    2. {
    3. if b=1
    4. {
    5. if c=1
    6. {
    7. code
    8. }
    9. }
    10. }



    2. Variante

    GML-Quellcode

    1. if a=1 && b=1 && c=1
    2. {
    3. code
    4. }



    Falls ihr generell noch Tipps für optimalen Code habt, immer gern :).
  • Bei solch einem Code sollte man lieber auf die Leserlichkeit achten, sonst würden wir noch alle in Assembler programmieren.

    = ist der Zuweisungsoperator, == ist der Vergleichoperator. In anderen Programmiersprachen ist dies so, nur beim GM wird kein Unterschied gemacht.

    GML-Quellcode

    1. switch (a)
    2. case 1: code 1 break;
    3. case 2: code 2 break;
    4. case 3: code 3 break;



    Es gibt eigentlich keinen großen Unterschied, wenn du willst kannst du eine Timer DLL benutzen und das ganze nachmessen.
    wupto.net/ Nicht meine Seite!
    We love Koalas.

    GM-D-Spam-o-Meter: 32%
  • Schreib sauberen, verständlichen und einheitlichen Code. Das ist viel wichtiger. Mach dir lieber Gedanken über wie oft was ausgeführt wird. Halte die Anzahl der Objekte und deren Events auf einem Minimum. Das sind die Sachen, die sichtlich die Performance beeinflussen.

    Alte Experimente von mir haben gezeigt, dass das Parsen einzelnder Zeichen stärker ins Gewicht fällt als die meisten Funktionen. Würdest du also ernsthaft optimieren wollen, müsstest du sämtlichen Code in eine Zeile schreiben, Namen kurz halten und alle Kommentare löschen. Inwieweit sich das mit Studio geändert hat weiß ich nicht - immerhin wird es für diverse Plattformen zuerst in Javascript konvertiert, wobei auch ein klein wenig optimiert wird.

    Kurz: Vergewaltige deinen Code nicht. Es bringt nichts. Für so verschachtelte Ifs bietet sich, wie schon von anderen angemerkt, switch an.


    Edit: Aus deinem Profil schließe ich, dass du übers Programmieren schon mindestens eine Vorlesung gehört hast. Haben die dir da etwa nicht beigebracht, dass Spaghetti-Code eine der größten Sünden überhaupt ist?
  • MewX schrieb:

    Aus deinem Profil schließe ich, dass du übers Programmieren schon mindestens eine Vorlesung gehört hast. Haben die dir da etwa nicht beigebracht, dass Spaghetti-Code eine der größten Sünden überhaupt ist?
    Über Theorie wurde uns leider nicht allzu viel gesagt. Es waren hauptsächlich Übungen in LUA. Eigentlich nutze ich ja keine If-Verschachtelungen. Ich habe mich nur gefragt, ob es nicht langsamer ist, falls ich zu viele && in einer If-Abfrage verwende.

    Eine Frage fällt mir zum Game Maker speziell noch ein: Ist es schneller/optimaler, wenn ich Code im Step-Event lagere oder neue Instanzen zum Ausführen verwende?

    Beispiel Inventar:

    1. :event_step:

    GML-Quellcode

    1. if keyboard_check(ord('I'))
    2. {
    3. //langer Inventory Code
    4. }



    2. :event_step:

    GML-Quellcode

    1. if keyboard_check(ord('I'))
    2. {
    3. instance_create(x,y,o_inventory)
    4. }


    :event_create:

    GML-Quellcode

    1. //inventory code
  • Spielt keine Rolle, da der Create-Code so oder so sofort ausgeführt wird. Der Übersicht halber ist das Auslagern ins Create-Event aber vermutlich schlauer, da du später diese Objekte auch eventuell von woanders her erstellen willst und sonst den Code dorthin kopieren müsstest.

    Im Game Maker wurder das früher zwar vernachlässigt, aber jede schlaue Sprache sollte nach dem ersten false abbrechen, wenn danach ein && kommt. In z.B. Lua kann man dies, glaube ich, sogar selbst bestimmen indem man & bzw. && benutzt.
  • MewX schrieb:

    Spielt keine Rolle, da der Create-Code so oder so sofort ausgeführt wird.
    Ich meinte eigentlich, da man ja lange Codes in Step-Events vermeiden sollte. Oder macht das in diesem Fall keinen Unterschied?

    Bricht der Game Maker nicht nach dem ersten false ab? o.o

    Überspringt der Game Maker überhaupt den Code bei false if's oder geht er den Code dennoch durch?
  • lordvanzed schrieb:

    Ich meinte eigentlich, da man ja lange Codes in Step-Events vermeiden sollte. Oder macht das in diesem Fall keinen Unterschied?

    Das macht keinen Unterschied denn es geht in keiner Weise darum wie viel Code einfach im Event steht sondern wieviel code ausgeführt wird. Also wenn der code aufgrund von if's eben nicht _jeden step_ ausgeführt wird, dann braucht dies auch keine Bearbeitungszeit.

    lordvanzed schrieb:

    Bricht der Game Maker nicht nach dem ersten false ab? o.o
    Überspringt der Game Maker überhaupt den Code bei false if's oder geht er den Code dennoch durch?

    Du hast das falsch verstanden. Was er meinte war wenn du sowas hast:

    GML-Quellcode

    1. if (scripta() = true) && (script2() = true)
    2. {
    3. // code
    4. }


    Wenn scripta falsch ausgibt, dann wird _dennoch_ auch scriptb ausgeführt und im Hintergrund verglichen. Es ist aber egal was script2 ausgibt, der //code wird dennoch nicht ausgeführt!
    Es geht nur darum dass scriptb vieleicht viel Rechenzeit benötigt und man deshalb diese Konstruktion vermeiden sollte wenn es häufig vorkommen kann dass scripta false ausgibt.



    EDIT: Zitat von MewX:
    Alte Experimente von mir haben gezeigt, dass das Parsen einzelnder Zeichen stärker ins Gewicht fällt als die meisten Funktionen. Würdest du also ernsthaft optimieren wollen, müsstest du sämtlichen Code in eine Zeile schreiben, Namen kurz halten und alle Kommentare löschen. Inwieweit sich das mit Studio geändert hat weiß ich nicht - immerhin wird es für diverse Plattformen zuerst in Javascript konvertiert, wobei auch ein klein wenig optimiert wird.

    Mit welcher GM-Version hast du das denn getestet?
    Denn meines Wissens nach wandelt der GM ja beim "kompilieren" den Code in einen bytecode (der ja bei Laufzeit interpretiert wird) um. Dabei werden Komentare, etc automatisch übersprungen. (bzw. es wäre logisch dass dies geschieht).
    So hatte es in meinen Tests auf jeden Fall keine Auswirkungen wie lang der Variablen-Name ist (selbst ein 5 Seiten füllender Name nicht :D ) und es werden scheinbar sogar konstante Ausdrücke berechnet.
    Also sowas wie

    GML-Quellcode

    1. a= 1+(4+2*9)-12/4

    D.h. solche Schönheitsfehler wirken sich nur auf die Kompilierzeit aus, nicht auf die Laufzeit.

    Willst du auf diese Drachen und -eier klicken?
    Sie werden sich freuen ;)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von DragonGamer ()

  • lordvanzed schrieb:

    1. Variante

    GML-Quellcode

    1. if a=1 {code 1}
    2. if a=2 {code 2}
    3. if a=3 {code 3}



    2. Variante

    GML-Quellcode

    1. switch (true)
    2. case a=1: code 1 break;
    3. case a=2: code 2 break;
    4. case a=3: code 3 break;

    Die beiden Varianten sind vom Ergebnis nicht gleich. Falls code 1 a verändert (zum Beispiel auf 2) stellt, kann auch eine weitere Anweisung (code 2) noch im selben Step ausgeführt werden. Die Richtige Variante 1 wäre also:

    GML-Quellcode

    1. if a=1 {code 1}
    2. else if a=2 {code 2}
    3. else if a=3 {code 3}

    Ich hebe das deshalb hervor, weil es ein häufig gemachter Fehler ist und auch einer, den man leicht übersieht.
    Die Vorteile und Nachteile von if und switch liegen woanders. Du kannst in einem switch schlecht a<1 abfragen und in viele if-Abfragen können schnell unübersichtlich werden und sehen eventuell in mit switch-case übersichtlicher aus.
    Einige meiner Spiele:
  • Siehe Dragongamer.

    Durch die Scripts wandern muss er immer. Entscheidend ist, was ausgewertet wird. Tatsächlich solltest du ihn aber wenn nur wegen meiner Begründung weiter oben auslagern. Ansonsten bietet sich immer noch an, große Codeblöcke in eigene Scripts auszulagern, aber auch hier mehr der Übersicht halber.
    Ich bezweifle ganz stark, dass dir ein Codeblock, der nur gelesen aber nicht ausgeführt wird, irgendwann mal das Genick bricht.

    Ich habe mal kurz das hier getestet:

    GML-Quellcode

    1. if (false && game_end()) {}

    Und siehe da, das Spiel beendet sich. Peinlich, peinlich. Für komplexere Abfragen solltest du also tatsächlich verschachteln.


    Edit:
    @Dragongamer GM5 oder 6, glaub ich. Studio sollte aber in Bytecode übersetzen, ja, aber es würde mich nicht wundern, wenn er darauf auf Win/Mac immer noch verzichtet.
  • DragonGamer schrieb:

    GML-Quellcode

    1. if (scripta() = true) && (script2() = true)
    2. {
    3. // code
    4. }


    Wenn scripta falsch ausgibt, dann wird _dennoch_ auch scriptb ausgeführt und im Hintergrund verglichen.

    Das habe ich gar nicht (mehr) gewusst. In anderen Programmiersprachen, C(++) und ich glaube auch Java zum Beispiel, wird der zweite Ausdruck gar nicht mehr ausgewertet. Wozu auch?
    Gibt häufig im Code Abfragen, bei denen man das gerne verknüpfen können würde:

    GML-Quellcode

    1. if (instance_exits(obj) && obj.x > 1) doSomething();
    Das geht dann wohl nur verschachtelt:

    GML-Quellcode

    1. if (instance_exits(obj)) if(obj.x > 1) doSomething();
    Einige meiner Spiele:
  • Stimmt, das ist eine doofe Eigenheit des GM's. Mit if's kann man das aber ja leicht umgehen.. problematisch ist's nur wenn man ein else benutzen will welches sich auf beide Ausdrücke bezieht. Das geht dann nur mit einer Zwischenvariablen..

    Willst du auf diese Drachen und -eier klicken?
    Sie werden sich freuen ;)
  • Danke für eure ganzen Antworten. Ich versuch mir das alles gut einzuprägen :D.

    interceptor schrieb:

    Du kannst in einem switch schlecht a<1 abfragen
    Aber geht das nicht mit einem true switch?

    GML-Quellcode

    1. switch (true)
    2. {
    3. case rarity>869 && rarity<970: //
    4. }



    Funktioniert für mich zB. Damit lasse ich die Seltenheit eines Drops bestimmen.
  • Dass ich das noch nie gesehen habe liegt wohl daran, dass es unter Java nicht funktionieren würde und ich in Java bisher am meisten geschrieben habe. Java will da ints oder enums haben.
    Der eigentliche Witz ist, dass ich es bei deinem ersten Post (den ich zitiert habe) komplett übersehen habe und sofort im Kopf durch henrik1235s Variante ersetzt habe... :whistling:
    Einige meiner Spiele:
  • Benutzer online 13

    13 Besucher