Beiträge von DMA

    Vorwort:


    Man sieht ja die Performence von SII.
    Viele denken, schneller geht's garnicht mehr.
    Doch das ist falsch.
    Deshalb möchte ich nun einigen zeigen, wie schnell eine Dateiverarbeitung sein kann.


    Wie funktioniert dies?


    Es werden die Daten nicht mehr als für den Menschen lesbaren ASCII Code gespeichert, sondern nur ihre Bits.
    Das ist erheblich schneller auszulesen und zu schreiben.
    Man muss sich allerdings im klaren sein, das man die Daten mit es nurnoch per Script oder Hexeditor/Programm bearbeiten kann.


    Erläuterung des Systems


    In PAWN ist jede Variable 4 Byte groß.
    Somit verbraucht der Buchstabe a genauso viel Speicher wie die Zahl 26367343.


    Speicher wir diese Zahl nun als ASCII String, verbrauchen wir viele Byte.
    Und zwar für jede Ziffer 1 Byte.


    Dies wieder auszulesen dauert "zulange" für manche.
    Deswegen speichern wir die Zahl als 4 Byte ab.


    Grobe Funktion:


    Wichtig: io_readwrite ist verbugt und sollte NICHT verwendet werden.
    main()
    {
    new File:FileStream = fopen("test.txt", io_write);
    if(!FileStream) // prüfen ob die Handle/Stream okay ist
    {
    printf("Error");
    return;
    }

    new test[32], pos = 0; // Test Array + position (Hier 32, werden zwar nicht alle benötigt, aber es werden eh nur die benötigten geschrieben. ;)
    test[pos++] = 13534; // Stellen wir uns vor das ist das Spielergeld
    add_str("DMA", pos, test); // und das der Spielername

    fwrite(FileStream, test); // schreiben unserer "Userdaten"

    fclose(FileStream); // schließen da io_readwrite verbugt ist und wir jetzt io_read nutzen müßen.

    FileStream = fopen("test.txt", io_read);

    if(!FileStream) // selbe Prozedur wie oben
    {
    printf("Error");
    return;
    }

    fread(FileStream, test); // Wir lesen aus.

    printf("%d", test[0]); // Wir erhalten unser Geld ausgegeben.
    // schließen
    fclose(FileStream);
    }


    add_str(string[], &pos, write[], size_w = sizeof write)
    {
    for(new i = 0; i < strlen(string); i++, pos++)
    {
    if(pos < size_w)
    {
    write[pos] = string[i];
    }
    }
    }


    Bis zu 30 Nanosekunden schneller wäre strins, aber die 30NS merkt man eh nicht. ;)


    Schaut euch ruhig die test.txt nun an.
    Wie ihr seht, ist DMA noch vorhanden.
    Das hat damit zutun, das der String ja nur ein Array ist und jeder Buchstabe ein Array Feld ist.
    Außerdem seht ihr ein "Merkwürdiges" Zeichen vor DMA.
    Dies ist unsere Zahl. ;)


    Speichern eines Users:


    Hier ein Beispiel für ein sehr effektives Userdaten System:
    main()
    {
    new p_money = 6372, p_wantedlevel = 352323, p_houseid = 255;
    SaveUser("DMA", p_money, p_wantedlevel, p_houseid);
    p_money = 0, p_wantedlevel = 0, p_houseid = 0;
    // Nun müßen wir wieder die Daten holen
    ReadUser("DMA", p_money, p_wantedlevel, p_houseid);
    // Testen ob's geklappt hat:
    printf("Money: %d WantedLevel: %d HouseID: %d", p_money, p_wantedlevel, p_houseid);
    }


    SaveUser(name[], money, wantedlevel, houseid)
    {
    new msg[64], File:FileStream, pos = 0;
    format(msg, sizeof msg, "/userdata/%s.user", name);
    FileStream = fopen(msg, io_write);
    if(!FileStream)
    return 0; // Nicht beschreibbar
    // User Datei offen
    msg = "";
    msg[pos++] = money; // pos++ erhöht die Position
    msg[pos++] = wantedlevel; // wantedlevel
    msg[pos++] = houseid; // und die Haus Identifikation
    fwrite(FileStream, msg); // schreiben
    fclose(FileStream); // UserDatei geschlossen
    return 1; // beschrieben
    }


    ReadUser(name[], &money, &wantedlevel, &houseid)
    {
    new msg[64], File:FileStream;
    format(msg, sizeof msg, "/userdata/%s.user", name);
    FileStream = fopen(msg, io_read);
    if(!FileStream)
    return 0; // Nicht lesbar
    // User Datei offen
    fread(FileStream, msg); // lesen
    money = msg[0];
    wantedlevel = msg[1];
    houseid = msg[2];
    fclose(FileStream); // UserDatei geschlossen
    return 1; // lesbar
    }


    Abschluß


    Und wieder habt ihr was von DMA gelernt.
    Bei Problemen oder Fragen, einfach in den Thread schreiben.

    Rofl, ah doch da steht die GPU.


    Nein, bestimmt nicht.
    Der 8100 Chip ist langsamer als eine GeForce 6800 Ultra (die überholt sogar heute noch eine 94/500)


    Damit wirst du nichtmal auf "Low" ordentlich spielen können.

    Da wird eher der Compiler streiken (oder eher gesagt, abstürzen).


    Die kombination do while ist so fatal wie auf der Autobahn spielen.
    Wenn müßte das heißen:
    while(...)
    {
    ...
    }


    Außerdem braucht man "Kopfgesteuerte" (Check and do (cad)) viel öfter.


    z.B. beim zeilen auslesen:
    while(fread(FileHandle, StringHandle, sizeof StringHandle))
    {
    }


    Würde so garnicht mit do while laufen. ;)

    Wichtig dabei:
    Der "do" Block wird vor der Überprüfung ausgeführt.
    new i = 30;
    do
    {
    printf("before: %d after: %d", i, --i);
    }
    while(i != 30); (Achtung: Produziert eine Unendlicheschleife).

    Für alle die ihren AMX Code per DisAMX (nicht zu verwechseln mit DeAMX) optimieren wollen:


    Addition
    Beispiel: a = b + 2
    load.pri %[b] // primary register
    const.alt 2 // alternate
    add // primary = primary + alternate
    stor.pri %[a]


    Läßt sich optimieren durch:
    load.pri %[b]
    add.c 2
    stor.pri %[a]


    Vergleich: 8 Calls gegen 6 Calls.
    Die zweite Register-Variante ist um einiges schneller. (Nachzulesen Pawn Impl.)


    Auch Dec (In jeglicher Form) ist schneller als Sub (In jeglicher Form)
    Wobei dieses Defiziet zumindest auf Intel Prozessoren weniger gewichtig ist.


    Außerdem, wenn genug Dynamic Memory noch frei ist, ruhig diesen niedriger setzen.
    #pragma dynamic 4096
    Genügt für viele Filterscripte vollkommen.

    Nicht nur für Publics.
    Auch die "ohne" bräuchten ein forward.


    Würde dann so aussehen:


    Float:x(Float:a, Float:b);


    Float:x(Float:a, Float:b)
    {
    return a-b;
    }


    Würde bei stock nicht gebraucht werden. ;)

    Das ist ganz einfach.


    Eine Funktion ohne Zugehörigkeit (public,static,..) benötigt eine deklaration wenn sie einen anderen Tag wiedergeben soll.


    Bei stock wird die Funktion auf Vorrat gespeichert und bei Gebrauch erst ins Script compiled.
    Deswegen erscheint bei diesen auch nicht: "Function x is never used".


    Static sind nur in der Sektion sichtbar. (Sektion = Datei oder Pragma Sektion)


    Public sind Funktionen die nur einen Cell zurückgeben und durch AMX auch außerhalb ihrer Laufzeit aufgerufen werden können.
    (D.h. der SA:MP Server kann auf die Funktion zugreifen)


    Einfach, oder? ;)

    WochenTag(ParamJahr) //
    {
    new MyTag = ((floatround(ParamJahr * 365.25) - 620628) % 7), MyResult[12];
    switch(MyTag)
    {
    case 0: MyResult = "Sonntag";
    case 1: MyResult = "Montag";
    case 2: MyResult = "Dienstag";
    case 3: MyResult = "Mittwoch";
    case 4: MyResult = "Donnerstag";
    case 5: MyResult = "Freitag";
    case 6: MyResult = "Samstag";
    default: MyResult = "Error";
    }
    return MyResult;
    }


    Nicht getestet, müßte aber klappen. ;)