Ressourcenschonendes Programmieren mit PAWN

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Guten Abend, ich möchte euch etwas über Ressourcenschonendes Scripten in Sa-Mp erzählen.


    1. Player-for-Schleifen optimieren


    Für die meisten User sieht eine for-Player-Schleife so aus:


    for (new playerid=0; playerid<MAX_PLAYERS; playerid++)
    {
    //Beispiel aus Yless Server Addon
    SetPlayerGravity(playerid, 0.008);
    }


    Doch sehen wir uns das mal genauer an. MAX_PLAYERS, ist der definierte Wert von Sa-Mp und ist in 0.2.2 als 200 deklariert. Warum sollten wir den eine for Schleife 200 mal auf einem 32 Slot Server laufen lassen. Also helfen wir uns dort mit GetMaxPlayers() ab. Diese Funktion returnt die maximale Anzahl der Player.



    for (new playerid=0; playerid<GetMaxPlayers(); playerid++)
    {
    //Beispiel aus Yless Server Addon
    SetPlayerGravity(playerid, 0.008);
    }


    Doch warum lassen wir die Schleife für jede ID die nicht online ist mitlaufen? Auch wenn Samp vor jedem Absenden selber cheackt ob der Player online ist, sollten wir dies per Pawn regeln. Hier arbeiten wir mit IsPlayerConnected(playerid);


    for (new playerid=0; playerid<GetMaxPlayers(); playerid++)
    {
    if(IsPlayerConnected(playerid))
    {
    //Beispiel aus Yless Server Addon
    SetPlayerGravity(playerid, 0.008);
    }
    }


    2. Die Timer Funktionen


    Ich kann mich noch an SampRL in der ersten Generation erinnern. Für jede Kleinigkeit wurde ein Timer gesettet. Das ist jedoch sinnlos, es sei den der Timer wird nich wiederholt. Für alle sich wiederholenden Timer gilt, ein Timer für alles reicht. Doch dieser sollte möglichst optimiert sein.


    #define MAX_TIMERS 20


    new timertime[MAX_TIMERS];
    new acttimertime[MAX_TIMERS];


    forward GeneralTimer();


    public OnGameModeInit()
    {
    SetTimer("GeneralTimer", 1000, true);
    return 1;
    }

    public GeneralTimer()
    {
    for(new timer=0; timer<MAX_TIMERS; timer++)
    {
    acttimertime[timer]++;
    if(timertime[timer] == acttimertime[timer])
    {
    acttimertime[timer] = 0;
    for(new playerid=0; playerid<GetMaxPlayers(); playerid++)
    {
    //Hier wird Beispielsweise für jedne Player etwas gecheckt
    }
    }
    }
    return 1;
    }


    Dies ist ein Beispiel wie ein General Timer aussehen könnte. Ein bessere und einfachere Methode gibt es hier: ProTimer System


    3. Strings


    Auch hier erinnere ich mich nur an die erste Scriptgeneration von SampRL. Zu jedem String wurden gleich hohe, unbenötigte Werte zugeordnet.


    Beispiel:



    new str[256];
    format(str, 256, "%s.name", /*GetPlayerName()*/);


    Auch hier stellt sich die Frage, warum stellen wir 256 Zeichen zur Verfügung wenn in Samp max. 32 gehen? 32 plus die 5 Zeichen von .name reichen also vollkommen aus. Desweiteren sollten wir hier auch mir sizeof(string) arbeiten, um die Funktion einfacher zu ändern, falls etwas eintritt.



    new str[37];
    format(str, sizeof(str), "%s.name", /*GetPlayerName()*/);


    Schon haben wir den String abgeschlackt. Besonders Multidimensionale Array wie Strings sind in PAWN sehr Ressourcenfressend.



    Ich werde das Tutorial weiter ergänzen sobald ich Lust und Laune habe. Ich hoffe ich konnte euch etwas helfen, ich gehe jetzt Simpsons gucken.

    Mit freundlichen Grüßen


    Einstein

  • Mal so am Rande: GetTickCount versagt unter Linux kläglich! (liefert nur 0)

    Intel Xeon W3690 Hexacore @ 4.5 GHz - 48GB Triple Channel DDR3 - GeForce RTX 2070 Super - Asus P6T Deluxe V1 @ P6T WS Pro BIOS

    Mainboard 12 Jahre, CPU 10 Jahre alt - old but gold!

  • Ich wollte das nur festhalten, da doch eine größere Anzahl von Usern Funktionen die sie aufgeschnappt haben in ihren Gamemode einfügen, ohne den Sinn und die Funktion davon zu hinterfragen und sich hinterher wundern warum es nicht wie erwartet funktioniert.

    Intel Xeon W3690 Hexacore @ 4.5 GHz - 48GB Triple Channel DDR3 - GeForce RTX 2070 Super - Asus P6T Deluxe V1 @ P6T WS Pro BIOS

    Mainboard 12 Jahre, CPU 10 Jahre alt - old but gold!

  • Danke für dieses Tutorial. Dass Schleifen mit GetMaxPlayers ressourcenschonender sind, wusste ich beispielsweise auch noch nicht. Das wird mir sicherlich bei meinem schwachen Server zur Kenntnis machen.
    Teoretisch könnte man doch mit Zeiger noch ressourcenschonender programmieren, beispielsweise um ein Array "zu durchstreifen". Doch warum unterstützt pawn keine Zeiger?

    ICQ Scripting - Support 495961653
    Montags-Freitags ab 15 Uhr

  • Achja, eine for schleife dauert in AMX Code relativ lange (~187µs pro durchlauf).
    Wenns eine kleine Forschleife ist erstellt euch ein define Makro und fügt dieses z.b. 4mal ein, und schwupps maßig Zeit (oder winzig zeit) gespart:
    Makros in PAWN:
    Funktionieren so ähnlich wie die C/++ Define Makros sind aber weniger umfangreich.
    Parameter werden mit einer Fortlaufenden Numme rund einem % angegeben.
    Getrennt durch ein ,

    Eine neue Zeile erhaltet ihr mit \
    #define ausgabe2x(%1) printf(%1); printf(%1);
    ausgabe2x("Hallo\n")
    Spart Zeit:
    Nun eine Forschleife mit wenig tipparbeit für 4 Ausgaben:
    for(new i = 0; i < 2; i++)
    ausgabe2x("Hallo\n")
    Zwar keine sinnige Anwendung, aber wayne.
    edit://
    TheKekes
    Zeiger zeigen auf ihre Speicheradresse.
    Das ist wie eine Hausnummer.
    Sie sind also nicht schneller, sondern genau das was der Computer macht mit variablen.
    Jede Variable ist nur eine Speicheradresse.
    D.h. Zeiger sind genauso schnell.
    Das braucht nur der AMX Interpreter.
    Also der Compilierte AMX Code.
    Der hat allerdings ein eigenen Register aus welchem er nicht heraus zeigen kann.
    Das ist der Grund warum PAWN auch keine Zeiger hat.
    Mehr als auf seine eigenen Variablen zeigen kann es nicht.
    Und dafür gibt es Referenzen.
    Zeiger ist ein Thema für sich, und auch sehr anfällig für Fehler.
    Ressourcenschonender sind sie trotzdem nicht ;).


    Einmal editiert, zuletzt von DMA ()

  • Soweit ich mir das angeeignet habe, zeigen Zeiger auf andere Variablen. Zeigen betrachten also nicht die Zeigervariable selbst, sondern über die Zeigervariable auf den Inhalt einer anderen Variable.
    An sich sind Zeiger nicht ressourcenschonend. Allerdings wollte ich mit dem Array durchstreifen ansprechen, dass Zeiger inkrementieren und dekrementieren können. Dadurch wird ein Zeiger um so viele Bytes weitergesetzt, wie die Größe des Typs ist, auf den er zeigt. Beim zeigen auf den Anfang eines Arrays wird er also auf die nächste Position inkrementiert.
    Ist das nicht ressourcenschonender, oder wenigstens geringfügig?

    ICQ Scripting - Support 495961653
    Montags-Freitags ab 15 Uhr

  • Zeiger sind Zeiger und variablen sidn Variablen.
    Zeiger haben keinen Wert sondern nur eine Adresse.
    Das ist auch alles.
    Und és ist nicht ressource schonend.
    Grund: Was meinst du was im Maschinencode passiert? :>
    variable a = 12;
    So im maschienn code iwrd das zu:

    Code
    addresse 1 mit dem Wert 12


    Zeiger sind also nicht schneller, weil ein Compiler aus einer variable ein Zeiger macht.
    Deswegen kann man auch C++ ganz ohne Zeiger verwenden.
    Nungut ganz verzichten würde ich nicht, aber prinziepjel ist das möglich.

  • Mit dem Thema Maschinencode hättest du teoretisch recht, klingt auch überzeugent.
    (http://de.wikipedia.org/wiki/Zeiger_(Informatik)#Vorteile) Keine Angst, durch Wikipedia habe ich mir nichts von C++ angeeignet, bevorzuge lieber Bücher. Aber da ist doch etwas Wahres dran.
    Demnächst befrage ich mal eine dritte Person, meinen Informatiklehrer, was er dazu wohl sagt.


    Ich hoffe die von mir angefangene Diskusion ist kein Offtopic, ins Thema "ressourcenschonendes Programmieren" passt es doch eigentlich schon.

    ICQ Scripting - Support 495961653
    Montags-Freitags ab 15 Uhr

  • Wenn dein Informatik lehrer gut ist, sagt er das was ich gesagt habe, ansonsten soltle er an seiner Kompetenz als Informatiklehrer zweifeln.
    Zeiger bieten nur Laufzeittechnische Vorteile , aber mit der Geschwindigkeit hat das reihn garnichts zutun.
    Sonst würde ja jeder nurnoch zeiger verwenden ;).

  • Darauf kann ich mich einigen.


    Ob mein Informatiklehrer kompetent ist, bezweifle ich stark, wenn ich schon die Überschrift sehe "HTML Programmierung Kurs 10c" oder "programmiert mit Joomla".. Selbststudium bringt einem da viel mehr.
    Aber auf die laufzeittechnischen Vorteile können wir es drauf beruhen.
    Nochmal Danke für deine Aufklärung.

    ICQ Scripting - Support 495961653
    Montags-Freitags ab 15 Uhr

  • Zitat

    "HTML Programmierung Kurs 10c"


    bin auch 10c xD


    is gutes tut, hilft mir zwar nicht viel weil ich eigentlich bezweifle das das den fehler behebt aba ich versuchs mal

    ________________________________________________________________________________
    Meine Scriptdingenserzeugnisse und hilfen xD:


    [TUT]Variablen [INC]YodasInc