Code Optimierung

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
  • Ärgerlich,da hatte ich den Post schon fast fertig und drück auf "Vorschau", da bin ich nicht mehr angemeldet ... :pinch:


    Bit-Shiften / Bitverschiebung benutzt man, um wie der Name schon sagt Bits zu verschieben.
    Bei Wikipedia ist das ganz gut erklärt, die Bilder sind sehr deutlich wie ich finde.
    http://de.wikipedia.org/wiki/B…r#Bitweise_Verschiebungen

    Zitat

    Symbolik:


    „<<“ Verschieben nach links, um den jeweils dahinter angegeben Wert
    „>>“ Verschieben nach rechts, um den jeweils dahinter angegeben Wert
    „>>>“ ist eine Sonderform von „>>“; linke Seite wird mit Nullen aufgefüllt.


    <<< , so wie du es geschrieben hast, gibt es auch gar nicht.Kannst es mal in PAWN ausprobieren.
    new a = 4 <<< 3;



    Wozu man es braucht,gute Frage.Darauf hab ich leider auch keine Antwort,denn mir fällt keine "gute" Erklärung dafür ein. Es verschiebt nun mal die Bits, wofür du es am Ende konkret benutzt kann sicherlich sehr unterschiedlich sein.Ich weiss nur wofür ich es verwendet habe.
    Man kann damit Daten "komprimieren". Das umfasst aber den kompletten Bit-Operationen Bereich.
    Wie schon erwähnt hat eine Variable 32 Bits in PAWN.Bedeutet also,man könnten theoretisch auch 32 Unterschiedliche Sachverhalte damit darstellen, Vorrausgesetzt jeder Sachverhalt lässt sich durch wahr/falsch darstellen.Ein kleines Beispiel.


    bool:bAdmin
    bool:bDeveloper
    bool:bFuehrerscheinA
    bool:bSpawned
    bool:bLogin


    Wenn ich jetzt weiss,dass das 1. Bit den Sachverhalt Admin abbildet, das 2. Bit den Sachverhalt Developer usw usf, kann ich mit den Bits arbeiten.
    enum e_Sachverhalte ( <<=1 ) // << Verschieb immer 1 Bit nach LINKS
    bAdmin = 1 , 0b00001
    bDeveloper, // 2 , 2.Bit 0b00010
    bFuehrerscheinA, // 4 , 3.Bit 0b00100
    bSpawned, // 8 , 4.Bit 0b01000
    bLogin // 16 , 5.Bit 0b10000
    }
    new Sachverhalt = bAdmin | bSpawned;
    // 0b01001 , für bAdmin und bSpawned
    Jetzt hab zuerst einmal einiges an Platz gespart.Es ist in einigen Fällen auch leichter damit zu arbeiten.
    Der Fuehrerschein lässt sich eigentlich gut damit abbilden.Anstatt extra FüherscheinA - F für jeden Spieler als anzulegen, kann ich auch lediglich einen Führerschein anlegen und über die Bits verwalten, welcher vorhanden ist oder nicht.


    Das komprimieren kommt auch hier vor,hab den Code schon mal gepostet.
    stock Class_CompressWeaponInfo(weaponid,ammo) {
    new
    info;
    info = ( ammo << 7 ) | weaponid;
    return info;
    }
    2 unabhängige Wert in einer Zelle.Natürlich kannst du damit auch einfache Rechenaufgaben machen.
    Rechnungen wie * 2 , * 4 , * 8 , * 16 usw sind damit auch möglich.Sollen auch schneller sein wenn man das
    direkt per Bitverschiebung macht,hab es aber nie getestet.


    Die Möglichkeiten sind wohl letztendlich Umfangreich. Vielleicht hilft dir das ja wenigstens etwas.

  • Ok das ist soweit verständlich, nur was bringt jetzt der <<= operator den du im enum benutzt?

    "Bevor ich mir Informationen aus der "Bild" hole,
    werde ich anfangen, Wahlergebnisse danach vorauszusagen,
    neben welchen Busch unsere Katze gepinkelt hat."

    Margarete Stokowski

  • Es verschiebt die Bits pro Eintrag einen nach Links zum vorherigen.
    Den ersten Eintrag gebe ich die 1. Würde ich dort nichts angeben,wäre es bekanntlich 0 ( Wieso ? Da fehlt wohl die Information was so ein "enum" wirklich macht ) . Würde ich 0 um 1 nach Links verschieben,wäre es immernoch 0.
    Bringt also nichts.


    Falls es mit der Bitverschiebung nicht ganz klar wird,hier mal etwas leichter.
    enum e_Sachverhalte ( +=1 ) // Folgeeintrag ist immer +1
    bAdmin = 1
    bDeveloper, // 2
    bFuehrerscheinA, // 3
    bSpawned, // 4
    bLogin // 5
    }

  • Okey und ich weiß immer noch nicht wozu man <<= benutzt bzw. << ^^
    /e.
    Jetzt hab ichs ^^ sagen wir ich möchte einen Führerschein Klasse M und A


    if(spdaten[playerid][fSchein] <<= 1) Sagen wir das ist Führerschein M und A ist dann <<= 2 , würde das so gehen?


    bzw. so


    spdaten[playerid][fSchein] << 1;

    Einmal editiert, zuletzt von Deuce ()

  • Damit ist gemeint ob man das so machen kann die Variablen so zu setzen, da enum ja immer +1 ist oder?


    spdaten[playerid][fSchein] << 1;


    Und eben für eine andere Klasse
    spdaten[playerid][fSchein] << 2;


    ?

  • Hey,
    Ich hab mal was kleines vorbereitet.
    Es geht um mehrdimensionale Arrays.


    Beispiel: 10 Variablen (in diesem Fall strings)
    Das koennte so aussehen:
    new var[64], var2[64], var3[64], var4[64], var5[64], var6[64], var7[64], var8[64], var9[64], var10[64];


    aber ich sage euch, das geht kuerzer, und zwar so:
    new Var[10][64]


    Auch bei diversen dingen kann dies ganz nuetzlich:
    Warum denn immer dieser stock SpielerName.
    Man kann einfach die Variable Spielername mit einem 2 dimensionalen Array versehen.
    So:
    new SpielerName[MAX_PLAYERS][MAX_PLAYER_NAME]


    dann im callback onplayerconnect den namen auslesen:

    GetPlayerName(playerid,SpielerName[playerid],MAX_PLAYER_NAME);


    Ein weiteres Praktisches Beispiel waere das fuer die verwendung von schleifen.
    Will man z.B die vars von oben (jetzt als integer gesehen, ohne einen array) auf 0 setzen, muss man das bei jeder einzeln tuen.
    So wuerde das mit dem Array gehen, hat zwar jetzt nur noch eine Dimension, aber was solls:



    new i = 0
    for(;i < 10; i++) var[i] = 0;


    das mit den schleifen habe ich von dma, 1te seite code optimierung.


    Ich garantiere nicht fuer die richtigkeit.
    Goldkiller wird mich bestimmt berichtigen muessen ;)

  • oha seitdem ich in meinem script MAX_PLAYERS neu definiert habe ( 32 ) ist es um 2MB geschrumpft. :o Wusste garnicht dass der Script beim compilen jeden befehl durchgeht... ich dachte das passiert erst im eigendlichen server :D

  • Ich muss den Thread mal wieder ausbuddeln.


    Frage 1:
    Ist es klug, eine string[128] - Variable am Anfang des Skriptes zu erstellen, mit dieser gibt man normale Texte aus, sodass man das nicht bei jedem Callback neu erstellen muss, macht das den Gamemode also schneller oder bringt das evtl. Fehler/Schwierigkeiten?


    Frage 2:
    Wie kann ich am besten, einen riesen Text (für ein Dialog) zusammen stellen?


    Danke und freundliche Grüße


  • Aber wenn ich jetzt eine string[128]-Variable hab, kann ich da ebr nicht endlos viel Text einfügen, oder?


    Irgendwann wirst du dich verzählen und plötzlich steht da ein Text, den du garnicht drin haben willst.
    Wenn du aber eine Variable innerhalb einer Funktion erstellst, wird diese nach dem Funktionsaufruf wieder entfernt. Von daher macht es dem Script nicht viel aus.

  • So, ich finde hier sollte auch wieder mal was rein und da ich mal wieder Langeweile habe, schreibe ich hier mal ein paar Sachen rein:


    Booleans:
    Wenn eine Variable nur 2 Werte annehmen brauch, sagen wir 0 und 1, dann sollte man anstatt so:
    //Falsche Variante
    new var;


    //In irgendeinem Callback
    var = 1;


    //Unter einem anderen Callback
    if(var == 1)


    Sollte man es so machen:


    //Richtige Variante
    new bool:var;


    //In irgendeinem Callback
    var = true;


    //Unter einem anderen Callback
    if(var == true)
    Das sorgt dafür, dass von Anfang an weniger Speicherplatz für diese Variable verbraucht wird.


    Char Arrays
    Das ist ein Thema was ich wirklich jedem ans Herz lege !


    Jeder kennt folgendes:


    new var[MAX_PLAYERS];


    if(var[playerid] == 1)
    Nun das ist aber verdammt schlecht !


    Jede Zelle bzw Spalte im Array verbraucht 4 Bytes, da MAX_PLAYERS (ohne das Makro zu verändern) eine größe von 500 hat, würde diese Variable:


    Code
    4Bytes * 500Bytes = 2000 Bytes


    verbrauchen !
    Aus diesem Grund sogenannte char-Arrays verwenden, dass sähe dann so aus:


    new var[MAX_PLAYERS char];


    if(var{playerid} == 1) //Vorsicht: Hier { } verwenden anstatt [ ] !!!
    Hier würde jede Zelle bzw Spalte im Array nur 1nen Byte verbrauchen !
    Sprich wir verbrauchen 500 Bytes anstatt 2000 ! ^^


    Wichtig noch zu beachten, das geht nur bei 1 dimensionalen Arrays und auch nur bei Integern, wenn man das mit strings machen will muss man strpack benutzen (aber das ist eine andere Geschichte)...


    Außerdem ist zu beachten, dass nur Werte von 0-255 möglich sind!
    Sprich:


    new test[MAX_PLAYERS char];
    test{0} = 259; //Ist nicht möglich, da größer 255!


    Strings-returnen
    Viele von euch werden wahrscheinlich diese Funktion kennen:


    stock PlayerName(playerid) {
    new name[MAX_PLAYER_NAME];
    GetPlayerName(playerid,name,MAX_PLAYER_NAME);
    return name;
    }
    Nun, hier returnen wir einen string, das führt zu sog. Memory Leaks und sorgt dafür dass euer Speicher unnötig belegt wird, denn diese Variable "name" wird Lokal erzeugt, aber sie wird durch das return nicht wieder "zerstört", somit bleibt der Speicher vorhanden.
    Aus diesem Grund empfehle ich diese Variante:


    //Oben im Script
    new pName[MAX_PLAYERS][MAX_PLAYER_NAME];


    //Unter OnPlayerConnect
    GetPlayerName(playerid,pName[playerid],MAX_PLAYER_NAME);


    //Nutzung:
    format(string,sizeof(string),"Willkommen lieber %s",pName[playerid]);


    Unnötig große Arrays
    Wie oben schon mal angesprochen verbrauchen große Arrays viel Speicherplatz !
    Ich zeige euch mal einige Beispiele die ihr sicher kennen werdet:


    new string[256], string1[300], string2[499]; /* usw... */
    format(string,sizeof(string),"bla...");


    Also abgesehen davon, dass man das meistens eh mit 1ner Variable lösen kann, zeige ich euch nun das:


    new string[] = "Hier euren Text rein...lieber %s",name[] = "Kaliber";
    format(string,sizeof(string)+sizeof(name),string,name);
    print(string); //würde ausgeben: "Hier euren Text rein...lieber Kaliber"


    So das wars erstmal mit dem gröbsten, werde vielleicht noch einen 2. Part dranhängen, mal sehen ^^


    mfg. :thumbup:


    Spoiler anzeigen
    //Edited: Infos

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

    2 Mal editiert, zuletzt von Kaliber ()

  • So:


    new bool:var;


    var = false; //eig unnötig, da der Wert eh auf false ist ^.^
    switch(var) {
    case false: print("false");
    case true: print("true");
    }


    Das würde in diesem Fall natürlich false printen ;)


    mfg. :thumbup:

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S