...was heist das ich bei einem einzigen char-Array 1,500 bytes spare.
Naja ich bleibe lieber an dem was ich gewohnt bin
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
-
-
new FALSE = false;
#define SendFormattedMessage(%0,%1,%2) do{new _str[128]; format(_str,128,%2); SendClientMessage(%0,%1,_str);}while(FALSE)
SendFormattedMessage(playerid,color,"Du hast %s SkinID %d zugewiesen",SpielerName[pID],sID);Spart das lästige erstellen von Strings und Formatierungen.
*/Edit: Funktion ist nicht von mir. Stammt, soviel ich weiß aus dem Englischen SA:MP Forum.
-
totaler schwachsinn. so hat jeder string 128 zeichen. egal ob ich 2 oder 500 zeichen brauche...
desweiteren wird jedesmal ne neue variable erstellt.
wenn man 2 texte hinternander sendet, kann man die variable 2mal nutzen -
Was ist daran totaler Schwachsinn? Habe ich irgendwo das Gegenteil behauptet?
-
hier gehts um code optimierungen und nicht um dinge, die scheiße sind.
-
Wie wäre es mal mit einer anderen Tonlage?
Bleib mal höflich, ich habe dich nirgends angegriffen o.Ä.
Wenn dir der Code nicht passt, behalte es einfach für dich. -
ich bin höflich?
hier geht es aber um code optimierungen => kinder die das nicht kennen denken "wooow wie geil voll geil ey, junge" und da kann ich nur eins zu sagen: "leider nein, leider garnicht"
ich zeige nur, dass dein code nicht in code optimierung passt. wenn dus in codeschnippsel gepostet hättest, würd ich ja nix sagen. aber hier ist das dumm
-
/Push
Ich liebe diesen Thread , lasst ihn bitte nicht verstauben. -
new i, l = strlen( string )
for (; i != l; i++ )
{
//Code
}
die schnellste Möglichkeit, die ICH kenne um durch einen String zu "kommen" -
Ist != schneller als <?
-
Denk ich ma, da sonst der Code noch einmal prüfen müsste, ob die Var auch wirklich kleiner ist, also ungleich und kleiner das sind 2 Dinge, und so muss er nur Prüfen ob es ungleich ist
-
Ist es, ich hab gerade mal nen kleinen Speedtest gemacht:
public OnFilterScriptInit()
{
print("\n--Base FS loaded.\n");
new x=0, y=1, time,time2, z=0;
time=GetTickCount();
for(new i=0;i<10000000;i++)
{
if(x<y) z++;
}
time2=GetTickCount();
printf("Dauer KLEINER: %i",time2-time);
for(new i=0;i<10000000;i++)
{
if(x!=y) z++;
}
printf("Dauer Ungleich: %i",GetTickCount()-time2);
return 1;
}Dauer Kleiner: 2150
Dauer Ungleich: 1950Obwohl man den Unterschied bei einem (!) Durchlauf überhaupt nicht bemerken kann, hier waren es 200ms Unterschied bei 10 Millionen Durchläufen.
-
200ms bei 10kk Durchgängen ist wenig. Ein Durchschnittsstring hat 256 Zeichen.
Das wären meiner Rechnung nach 0,0511 Millisekunden Unterschied. -
Ich hab her noch eine kleine Optimierungsmöglichkeit für Schleifen
Meine Theorie:
Eine While Schleife ist schneller als eine For SchleifeDer Grund:
In einer For Schleife muss (zwar nicht zwingend) er die variable erstellt werden, dann wird die Bedingung überprüft und am Ende der Schleife wird die Var erhöht und die Bedingung erneut geprüft.
Die While schleife spart sich die ganzen Schritte von hochzählen und var erstellen,sSie überprüft nur die Bedingung.
Var erstellen ist vorher und die var hochzählen ist mittendrin möglich.Der Beweis:
Ich hab den Test mit 1000000 Wiederholungen gemacht und dieses Ergebnis erhalten
Eine while schleife ist 2x so schnell wie eine for schleife und eine do while schleife etwas langsamer(manchmal auch schneller, wie bei mir gerade der Fall ) als eine while schleife1.Testergebnis
while Loop 10037ms
for Loop 20457ms
do while 10218ms2.Testergebnis
while Loop 10168ms
for Loop 20645ms
do while 9971msCode für den Test hier: http://pastebin.com/iyfBCQG2
Die Optimierung:
Aus
for(new i;i<MAX_PLAYERS;i++)
{
//iwas
}
machen wir ganz einfach
new i;
while(i<MAX_PLAYERS)
{
//iwas
i++; // wichtig ist das hier die var um eins hochgesetzt wird sonst ende die Schleife nie :P
}
oder
new i;
do
{
//iwas
i++; // wichtig ist das hier die var um eins hochgesetzt wird sonst ende die Schleife nie :P
}
while(i<MAX_PLAYERS); // wichtig² hier muss ein ; stehen
und für die geschwindigkeit Junkies unter uns
new i;
while(i!=MAX_PLAYERS)
{
//iwas
i++; // wichtig ist das hier die var um eins hochgesetzt wird sonst ende die Schleife nie :P
}
//und
new i;
do
{
//iwas
i++; // wichtig ist das hier die var um eins hochgesetzt wird sonst ende die Schleife nie :P
}
while(i!=MAX_PLAYERS); // wichtig² hier muss ein ; stehen//Edit: 1.Testergebnis & 2. Testergebnis
-
Leider ist der Test nicht richtig aufgebaut bzw du hast nicht überall die gleichen Vorraussetzungen.
- Lediglich in der for() Schleife erstellst du immer eine neue Variable l , anstatt wie bei while() und do-while() k zu verwenden.
- Bei der for() Schleife werden 2. Variablen inkrementiert, l und k. Dabei hat k wie in Punkt1 genannt nichts mit der for() Schleife zu tun.
Das sind Beides Nachteile für die for() Schleife.Zitat--- Unten 5x Durchläufe ---
Hier mein Code.
http://pastebin.com/AJh01BBj
//Edit:
Pastebin war falsch :-XZitat[14:43:56] while Loop 9104ms
[14:43:56] for Loop 7873ms
[14:43:56] do while 9140ms[14:44:22] while Loop 9071ms
[14:44:22] for Loop 7875ms
[14:44:22] do while 8996ms[14:44:48] while Loop 9145ms
[14:44:48] for Loop 7994ms
[14:44:48] do while 9172ms[14:45:14] while Loop 9021ms
[14:45:14] for Loop 7903ms
[14:45:14] do while 8957ms[14:45:40] while Loop 8947ms
[14:45:40] for Loop 7863ms
[14:45:40] do while 9043ms -
Stimme God zu, die For schleife hatte einen Nachteil ! Gut aufgepasst *Leider existiert kein "Thanks" button shame on breadfish*
-
Ich meine damit sowas wie hier: Link
Wie arbeitet man damit richtig? Wo soll es benutzt werden?
Ist es immer nützlich? Arbeitet das Programm schneller damit?Auf Frage von ioRawr, versuche ich mal den Code zu erklären.
Es ist definitiv nichts für PAWN Anfänger bzw allg. Anfänger im Coding Bereich.Übrigens, in dem Code fehlt eine Zeile. "return model" muss noch eingefügt werden,sonst bringt die Funktion nichts.
stock GetVehicleSeatCount(model)
{
static const
scMaxPassengers[] =
{
0x10331113, 0x11311131, 0x11331313, 0x80133301, 0x1381F110, 0x10311103, 0x10001F10, 0x11113311, 0x13113311,
0x31101100, 0x30001301, 0x11031311, 0x11111331, 0x10013111, 0x01131100, 0x11111110, 0x11100031, 0x11130221,
0x33113311, 0x11111101, 0x33101133, 0x101001F0, 0x03133111, 0xFF11113F, 0x13330111, 0xFF131111, 0x0000FF3F
};
if (400 <= model <= 611)
{
model -= 400;
model = (scMaxPassengers[model >>> 3] >>> ((model & 7) << 2)) & 0xF;
if (model == 15)
{
return -1;
}
return model; // <---
}
else
{
return -1;
}
}
Erstmal die Vorbereitung.Was haben wir eigentlich?
Wir haben 611 - 400 Fahrzeuge.Sind also 211 Fahrzeuge, für die wir Werte speichern müssen.
Es gibt kein Fahrzeug,dass mehr als 8 Sitzplätze hat ( Bus , 8 + Fahrer ). Damit wir die Zahl 8 in Binär darstellen können,
müssen wir 4 bits verwenden.Denn 8 = 0b1000 . Die höchste Zahl die wir daher darstellen könnte wäre theoretisch 15 in diesem Fall.
Ist aber sowieso nicht möglich,denn sonst hätten wir keine 8 als höchsten Wert für Sitzplätze genommen.
Y_Less verwendet aber die 15 als Spezialfall,bedeutet, dass Fahrzeug bietet überhaupt keine Sitzmöglichkeit ( Weder Fahrer,noch
Beifahrer ). Dazu später mehr.
Bisher haben wir also herrausgefunden,dass wir eigentlich nur 4 bits benötigen pro Fahrzeug und das 211 mal. Macht Insgesamt 844 bits,
um alle Informationen darzustellen.Da eine Variable ( Cell ) in PAWN 4 Byte hat ( 32 bits ) , können wir pro Variable also 8 ( 32 bits / 4 bits ) Sitzplätzwerte verwalten.
Daraus resultiert,wir haben 8 Blöcke mit jeweils 4 bits pro Variable. Ich nenne diese einfach mal 4 bit-Block im weiteren Verlauf.Wie wir sehen,Y_Less hat 27 Variablen ( Code basiert allerdings auf einen Post von RyDeR` ) bzw ein Array mit einer
Größe von 27.
Genau genommen ist 211 / 8 = 26,375 . Wir können aber keine 0,375 Variablen erstellen, müssen daher aufrunden. Daher auch 27. Kann man
auch überprüfen durch 26 * 32 bit , sind nur 832 bits.Wir vorher errechnet,wir brauchen aber 844 bits.Im ersten Schritt müssen wir herrausfinden, in welcher Variablen ( genau genommen, welcher Index ) der Wert für unser Fahrzeug
steckt.
Das geschiet hier:
model -= 400;
model >>> 3
Da die Fahrzeuge erst bei 400, verschieben wir den Anfang zuerst. Wir verschieben alle ModelIDs um 400 nach unten.
Sonst wären die ersten 400 Werte nutzlos ( 0 - 399 ) , da wir für diese keine Werte benötigen.Es gibt nämlich keine Fahrzeuge
mit diesen ModelIDs.
Gehen wir eine Zeile weiter ( model >>> 3 ).
Ist in diesem Fall nichts Anderes als die Berechnung model / 8. Die 8 kommt von den 8 Sitzplatzwerten pro Variable.Angenommen für die modelid 411.
411 -= 400;
11 >>> 3 = 1
Gut,wir wissen, dass der Wert für ModelID 411 in Index 1 steckt.Zitat400 - 407 ( 0 )
408 - 415 ( 1 )
416 = 423 ( 2 )
424 = 431 ( 3 )
...scMaxPassengers[1] = 0x11311131 = 0b00010001001100010001000100110001 = 0001 0001 0011 0001 0001 0001 0011 0001
Die Farben sind nur zur Verdeutlichung.Ich habe auch einfach mal den Block Fett markiert,den wir später suchen.Als nächstes müssen wir herrausfinden, in welchem der 4 bit-Blöcke der Wert steckt, den wir suchen.Das passiert hier:
((model & 7) // model & 0b111
In unserem Fall würde es so aussehen:
(( 11 & 7 ) // (( 0b1011 & 0b0111 )
Das Ergebnis daraus ist 3 ( 0b1011 & 0b0111 ). Man hätte an dieser Stelle auch den Rest der Rechnung 11 durch 8 nehmen können.Ergibt ebenfalls
3 und steht für "Wieviele 4 bit-Blöcke müssen wir verschieben,um den gesuchten an vorderster Position zu haben".
In PAWN wäre es übrigens 11 % 8 ( = 3 ).Wir haben jetzt also den 4 bit-Block gefunden,den wir benötigen.Er ist in der Variable bei Index 1 und dort der vierte 4 bit-Block.
Um an den vierten 4 bit-Block zu kommen,müssen wir den 4 bit-Block 3 Blöcke nach vorne schieben, bzw nach Rechts ( >> ).Das nennt sich Bit-Shiften.
Denn wir beginnen hier bei den Blöcken bei 0 zu zählen.Der 1 4 bit-Block wird nämlich nicht ( also 0 mal ) geshiftet, ist nämlich schon an Vorderster Stelle.
Der 2 4 bit-Block muss um 1 geshiftet werden,damit er an vorderster stelle steht.
Der 3 " " " 2 geshiftet ","
usw usfJetzt sind wir bei folgendem Teil. Denn wir müssen zuerst Klammern berechnen.
((model & 7) << 2))
Wir wissen ja, dass wir es um 3 4 bit-Blöcke verschieben müssen,damit der Gesuchte 4 bit-Block am Anfang steht. Da ein 4 bit-Block nun mal aus 4 Bits besteht,müssen wir alles um
3 * 4 Bits verschieben. Das * 4 ist in diesem Fall << 2 , ist identisch .( << 1 wäre * 2 )
Das würde Binäir so aussehen:
Ausgang: 0001 0001 0011 0001 -> 0001 <- 0001 0011 0001
Ergebnis: 0001 0011 0001 0001 0001 0011 0001 -> 0001 <- // Achtung , >> ist nicht >>> ! Macht in diesem Fall aber keinen UnterschiedJetzt haben wir den 4 bit-Block den wir benötigen an die vordersten 4 bits der Variablen verschoben. Damit wir auch nur diesen 4 bits bekommen,
müssen wir jetzt & 0b111 machen.Dadurch fallen alle bits weg, die wir nicht benötigen.
Für unseren Fall:
0b0001 & 0b1111 = 0b0001 = 1.
Damit wissen wir jetzt entgültig, dass wir 1 Sitzplatz für Fahrzeug 411 haben,neben dem Fahrersitz. Ein Spezialfall ist 15. Hätten wir jetzt also 15 als Lösung bekommen, wüssten wir, dass es eigentlich gar keine Sitzmöglichkeit für diese ModelID gibt. Es ist ein Sonderfall. 15 ist auch gleichzeitig der höchste Wert den wir mit 4 bits darstellen können ( Vorzeichenfrei ) .
Man könnte auch anstatt die 15 eine eine Andere Zahl nehmen. Es wäre irgendeine Zahl zwischen 9 und 15 möglich,da wir ja wissen,dass kein Fahrzeug einen gültigen Wert über 8 hat.Was haben wir denn jetzt eigentlich davon ? Wir nutzen wenig Speicher, oder für einige Experten ... die AMX wird nicht so groß ( Was sowieso noch nie ein gute Kriterium war ).
Ergebnis:
Die oben gezeigte Variante verbraucht nur 27 * 4 byte , macht also 107 byte ( Technisch werden nur 211 ( Fahrzeuge ) * 4 ( bits ) 844 bits je benutzt).
Würden wir einen Wert pro Variable benutzen, dann hätten 211 byte = 844 byte.
Macht also 107 byte vs 844 byte. Um es mal in Prozent auszudrücken. Die oben gezeigte Variante belegt nur 12.6% von dem Speicher, den die normale Methode verbrauchen würde.Oder auch anders, die normale Methode ist um 788% Größer was den Speicherbedarf betrifft.Puh... so viel geschrieben, dachte das wird kürzer. Vorraussetzung dafür,dass man es versteht, sind Grundzüge des Binärsystems ( & ; << ; >> ). Sonst wird es mit dem verstehen sicherlich nicht auf anhieb klappen. Ich hoffe ich habe da jetzt nicht totalen Blödsinn geschrieben, so viele 0 und 1 ...
//Edit:
Im übrigen verwende ich das ab und zu.Hier mal ein Beispiel, wie man Waffe + Munition in 1 Variable speichern kann.
stock Class_CompressWeaponInfo(weaponid,ammo) {
new
info;
info = ( ammo << 7 ) | weaponid;
return info;
} -
Uhuhu nice erklärt
Ich habe es nur nicht ganz verstanden. Aber naja, da ich mit Sitzplätzen im Moment nicht arbeite, brauch ich das wohl auch nicht so -
So steig ich auch ma ein.
#define DIALOGTEXT "blabla\nblabla\nblalblalba"könnt ihr nun als string benutzen..
ShowPlayerDialog(....."Überschrift",DIALOGTEXT, "Oke","Abbrechen");
Ebenso mit normalem String.
Zahlen kann man auch verwenden.
#define max 32
#define min 1if(max <= 32)
{
Ausführen wenn Max untergleich 32 ist
}zur absicherung
if(max <= 32 && min >= 1)
Das selbe Spiel mit min...
-
Uhuhu nice erklärt
Ich habe es nur nicht ganz verstanden. Aber naja, da ich mit Sitzplätzen im Moment nicht arbeite, brauch ich das wohl auch nicht so
Ich denke es geht auch nicht um den Sinn hinter der Funktion. Ich nehme an,dass ioRawr eher wissen wollte was dort konkret passiert und wieso es so überhaupt funktioniert. Allgemein sind Bit-Operationen sehr praktisch. Beispielsweise bei gPM nutz ich es um den Status von Nachrichten zu verwalten.Mit 1 Variable kann ich 3 Informationen Abfragen.
enum ( <<= 1 ) {
MessageStatus_Read = 1,
MessageStatus_DEL_Sender, // del von sender ( postausgang )
MessageStatus_DEL_Empfaenger // del von empfaenger ( posteingang )
}Genug ausgeführt, schweife sonst zu sehr vom Thema ab. Sollte das vllt eher in ein Tutorual schreiben