Select-en von Zahlen vs Strings
Übersicht

FlorianBetreff: Select-en von Zahlen vs Strings |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hier ein beispiel einer VM Stackmaschine.
Geschrieben mit PowerBasic Code: [AUSKLAPPEN] %True = -1 %False = Not %True %Debug = %False %Push = 1 %Pop = 2 %dbl = 3 %Swap = 4 %Mul = 5 %Div = 6 %Add = 7 %Sub = 8 %Neg = 9 %Incr = 10 %Decr = 11 %Not = 12 %And = 13 %Or = 14 %Xor = 15 %Call = 16 %Ret = 17 %Jmp = 18 %Jle = 19 %Stor = 20 %Load = 21 %In = 22 %Out = 23 %MaxCode = 4096 %MaxData = 4096 %MaxStack = 4096 %MaxReturnStack = 1024 DIM CS(%MaxCode) AS SHARED INTEGER DIM DS(%MaxData) AS SHARED INTEGER DIM SS(%MaxStack) AS SHARED INTEGER DIM RS(%MaxReturnStack) AS SHARED INTEGER DIM IP AS SHARED INTEGER DIM SP AS SHARED INTEGER DIM RP AS SHARED INTEGER 'CS(0)=%PUSH 'CS(1)=10 'CS(2)=%PUSH 'CS(3)=12 'CS(4)=%Add 'CS(5)=%Out 'CS(6)=%In 'CALL SAVEVM("VM.DAT") 'CALL DecodeMEM ("VM.TXT") CALL LOADVMBIN("VM.BIN") CALL RUNVM FUNCTION LOADVM(Dateiname AS STRING) DIM Dateizusatz AS STRING Dateizusatz$=UCASE$(MID$(Dateiname$,Instr(Dateiname$,".")+1)) SELECT CASE Dateizusatz$ CASE "BIN","" LOADVMBIN Dateiname$ CASE ELSE LOADVMASC Dateiname$ END SELECT END FUNCTION FUNCTION SAVEVM(Dateiname AS STRING) DIM Dateizusatz AS STRING Dateizusatz$=UCASE$(MID$(Dateiname$,Instr(Dateiname$,".")+1)) SELECT CASE Dateizusatz$ CASE "BIN","" SAVEVMBIN Dateiname$ CASE ELSE SAVEVMASC Dateiname$ END SELECT END FUNCTION FUNCTION BefehlName$(BefehlNr AS INTEGER) SELECT CASE BefehlNr CASE %Push FUNCTION= "Push" CASE %Pop FUNCTION= "Pop" CASE %dbl FUNCTION= "dbl" CASE %Swap FUNCTION= "Swap" CASE %Mul FUNCTION= "Mul" CASE %Div FUNCTION= "Div" CASE %Add FUNCTION= "Add" CASE %Sub FUNCTION= "Sub" CASE %Neg FUNCTION= "Neg" CASE %Incr FUNCTION= "Incr" CASE %Decr FUNCTION= "Decr" CASE %Not FUNCTION= "Not" CASE %And FUNCTION= "And" CASE %Or FUNCTION= "Or" CASE %Xor FUNCTION= "Xor" CASE %Call FUNCTION= "Call" CASE %Ret FUNCTION= "Ret" CASE %Jmp FUNCTION= "Jmp" CASE %Jle FUNCTION= "Jle" CASE %Stor FUNCTION="Stor" CASE %Load FUNCTION="Load" CASE %In FUNCTION="In" CASE %Out FUNCTION="Out" END SELECT END FUNCTION FUNCTION DecodeMEM(Dateiname AS STRING) DIM DateiNr AS INTEGER DIM Zeiger AS INTEGER DIM Befehl AS STRING DateiNr=FREEFILE OPEN Dateiname$ FOR OUTPUT AS DateiNr FOR Zeiger=0 TO %MaxCode SELECT CASE CS(Zeiger) CASE %Push INCR Zeiger Befehl$= "Push"+STR$(CS(Zeiger)) CASE %Pop Befehl$= "Pop" CASE %dbl Befehl$= "dbl" CASE %Swap Befehl$= "Swap" CASE %Mul Befehl$= "Mul" CASE %Div Befehl$= "Div" CASE %Add Befehl$= "Add" CASE %Sub Befehl$= "Sub" CASE %Neg Befehl$= "Neg" CASE %Incr Befehl$= "Incr" CASE %Decr Befehl$= "Decr" CASE %Not Befehl$= "Not" CASE %And Befehl$= "And" CASE %Or Befehl$= "Or" CASE %Xor Befehl$= "Xor" CASE %Call INCR Zeiger Befehl$= "Call"+STR$(CS(Zeiger)) CASE %Ret Befehl$= "Ret" CASE %Jmp INCR Zeiger Befehl$= "Jmp"+STR$(CS(Zeiger)) CASE %Jle INCR Zeiger Befehl$= "Jle"+STR$(CS(Zeiger)) CASE %Stor INCR Zeiger Befehl$="Stor"+STR$(CS(Zeiger)) CASE %Load INCR Zeiger Befehl$="Load"+STR$(CS(Zeiger)) CASE %In Befehl$="In" CASE %Out Befehl$="Out" CASE ELSE Befehl$="Nop" END SELECT PRINT #DateiNr,Befehl$ NEXT CLOSE DateiNr END FUNCTION SUB SAVEVMBIN(Dateiname AS STRING) DIM DateiNr AS INTEGER DIM Zeiger AS INTEGER DateiNr=FREEFILE OPEN Dateiname$ FOR BINARY AS DateiNr PUT$ #DateiNr, MKI$(%MaxCode) PUT$ #DateiNr, MKI$(%MaxData) PUT$ #DateiNr, MKI$(%MaxStack) PUT$ #DateiNr, MKI$(%MaxReturnStack) PUT$ #DateiNr, MKI$(IP) PUT$ #DateiNr, MKI$(SP) PUT$ #DateiNr, MKI$(RP) 'Code speichern FOR Zeiger% = 0 TO %MaxCode PUT$ #DateiNr,MKI$(CS(Zeiger%)) NEXT 'Daten speichern FOR Zeiger% = 0 TO %MaxData PUT$ #DateiNr,MKI$(DS(Zeiger%)) NEXT 'Stack speichern FOR Zeiger% = 0 TO %MaxStack PUT$ #DateiNr,MKI$(SS(Zeiger%)) NEXT 'MaxReturnStack speichern FOR Zeiger% = 0 TO %MaxReturnStack PUT$ #DateiNr,MKI$(RS(Zeiger%)) NEXT CLOSE DateiNr END SUB SUB LOADVMBIN(Dateiname AS STRING) DIM DateiNr AS INTEGER DIM MinCodeS AS STRING DIM MinDataS As STRING DIM MinStackS AS STRING DIM MinReturnStackS AS STRING DIM MinCode AS INTEGER DIM MinData As INTEGER DIM MinStack AS INTEGER DIM MinReturnStack AS INTEGER DIM IPS AS STRING DIM SPS AS STRING DIM RPS AS STRING DIM Zeiger AS INTEGER DIM CodeS AS STRING DIM DataS AS STRING DIM StackS AS STRING DIM ReturnStackS AS STRING DateiNr=FREEFILE OPEN Dateiname$ FOR BINARY AS DateiNr GET$ #DateiNr,2,MinCodeS$ GET$ #DateiNr,2,MinDataS$ GET$ #DateiNr,2,MinStackS$ GET$ #DateiNr,2,MinReturnStackS$ MinCode%=CVI(MinCodeS$) MinData%=CVI(MinDataS$) MinStack%=CVI(MinStackS$) MinReturnStack%=CVI(MinReturnStackS$) IF MinCode%>%MaxCode OR MinData%>%MaxData OR _ MinStack%>%MaxStack OR MinReturnStack%>%MaxReturnStack THEN CLOSE DateiNr END IF GET$ #DateiNr, 2, IPS$ GET$ #DateiNr, 2, SPS$ GET$ #DateiNr, 2, RPS$ IP=CVI(IPS$) SP=CVI(SPS$) RP=CVI(RPS$) 'Code einlesen FOR Zeiger=0 TO MinCode% GET$ #DateiNr, 2, CodeS$ CS(Zeiger)=CVI(CodeS$) NEXT 'Daten einlesen FOR Zeiger=0 TO MinData% GET$ #DateiNr, 2, DataS$ DS(Zeiger)=CVI(DataS$) NEXT 'Stack einlesen FOR Zeiger=0 TO MinStack% GET$ #DateiNr, 2, StackS$ SS(Zeiger)=CVI(StackS$) NEXT 'Returnstack einlesen FOR Zeiger=0 TO MinReturnStack% GET$ #DateiNr, 2, ReturnStackS$ RS(Zeiger)=CVI(ReturnStackS$) NEXT Close DateiNr END SUB SUB SAVEVMASC(Dateiname AS STRING) DIM DateiNr AS INTEGER DIM Zeiger AS INTEGER DateiNr=FREEFILE OPEN Dateiname$ FOR OUTPUT AS DateiNr 'Informatioen ?ber sie Segmente der VM speichern PRINT #DateiNr, %MaxCode PRINT #DateiNr, %MaxData PRINT #DateiNr, %MaxStack PRINT #DateiNr, %MaxReturnStack 'Position der Zeiger speichern PRINT #DateiNr, IP PRINT #DateiNr, SP PRINT #DateiNr, RP 'Code speichern FOR Zeiger% = 0 TO %MaxCode PRINT #DateiNr,CS(Zeiger%) NEXT 'Daten speichern FOR Zeiger% = 0 TO %MaxData PRINT #DateiNr,DS(Zeiger%) NEXT 'Stack speichern FOR Zeiger% = 0 TO %MaxStack PRINT #DateiNr,SS(Zeiger%) NEXT 'MaxReturnStack speichern FOR Zeiger% = 0 TO %MaxReturnStack PRINT #DateiNr,RS(Zeiger%) NEXT CLOSE DateiNr END SUB SUB INSTVM() DIM ZEIGER AS INTEGER IP=0 SP=0 RP=0 FOR Zeiger=0 TO %MaxCode CS(Zeiger)=0 NEXT FOR Zeiger=0 TO %MaxData DS(Zeiger)=0 NEXT FOR Zeiger=0 TO %MaxStack SS(Zeiger)=0 NEXT FOR Zeiger=0 TO %MaxReturnStack RS(Zeiger)=0 NEXT END SUB SUB LOADVMASC(Dateiname AS STRING) DIM DateiNr AS INTEGER DIM MinCodeS AS STRING DIM MinDataS As STRING DIM MinStackS AS STRING DIM MinReturnStackS AS STRING DIM MinCode AS INTEGER DIM MinData As INTEGER DIM MinStack AS INTEGER DIM MinReturnStack AS INTEGER DIM IPS AS STRING DIM SPS AS STRING DIM RPS AS STRING DIM Zeiger AS INTEGER DIM CodeS AS STRING DIM DataS AS STRING DIM StackS AS STRING DIM ReturnStackS AS STRING DateiNr=FREEFILE OPEN Dateiname$ FOR INPUT AS DateiNr LINE INPUT# DateiNr,MinCodeS$ LINE INPUT# DateiNr,MinDataS$ LINE INPUT# DateiNr,MinStackS$ LINE INPUT# DateiNr,MinReturnStackS$ MinCode%=VAL(MinCodeS$) MinData%=VAL(MinDataS$) MinStack%=VAL(MinStackS$) MinReturnStack%=VAL(MinReturnStackS$) IF MinCode%>%MaxCode OR MinData%>%MaxData OR _ MinStack%>%MaxStack OR MinReturnStack%>%MaxReturnStack THEN CLOSE DateiNr END IF LINE INPUT #DateiNr, IPS$ LINE INPUT #DateiNr, SPS$ LINE INPUT #DateiNr, RPS$ IP=VAL(IPS$) SP=VAL(SPS$) RP=VAL(RPS$) 'Code einlesen FOR Zeiger=0 TO MinCode% LINE INPUT #DateiNr, CodeS$ CS(Zeiger)=VAL(CodeS$) NEXT 'Daten einlesen FOR Zeiger=0 TO MinData% LINE INPUT #DateiNr, DataS$ DS(Zeiger)=VAL(DataS$) NEXT 'Stack einlesen FOR Zeiger=0 TO MinStack% LINE INPUT #DateiNr, StackS$ SS(Zeiger)=VAL(StackS$) NEXT 'Returnstack einlesen FOR Zeiger=0 TO MinReturnStack% LINE INPUT #DateiNr, ReturnStackS$ RS(Zeiger)=VAL(ReturnStackS$) NEXT CLOSE DateiNr END SUB SUB RUNVM() CLS DO $IF %DEBUG PRINT BefehlName$(CS(IP)) $ENDIF SELECT CASE CS(IP) CASE %Push SS(SP)=CS(IP+1) INCR SP INCR IP,2 CASE %Pop DECR SP INCR IP CASE %dbl SS(SP)=SS(SP-1) INCR SP INCR IP CASE %Swap SWAP SS(SP-1),SS(SP-2) INCR IP CASE %Mul SS(SP-2)=SS(SP-1)*SS(SP-2) DECR SP INCR IP CASE %Div SS(SP-2)=SS(SP-1)/SS(SP-2) DECR SP INCR IP CASE %Add INCR SS(SP-2),SS(SP-1) DECR SP INCR IP CASE %Sub DECR SS(SP-2),SS(SP-1) DECR SP INCR IP CASE %NEG SS(SP-1)= -SS(SP-1) INCR IP CASE %Not SS(SP-1)=NOT SS(SP-1) INCR IP CASE %And SS(SP-2)=SS(SP-1) AND SS(SP-2) DECR SP INCR IP CASE %Or SS(SP-2)=SS(SP-1) OR SS(SP-2) DECR SP INCR IP CASE %Xor SS(SP-2)=SS(SP-1) XOR SS(SP-2) DECR SP INCR IP CASE %Incr INCR SS(SP-1) INCR IP CASE %Decr DECR SS(SP-1) INCR IP CASE %Call RS(RP)=IP+2 INCR RP IP=CS(IP+1) CASE %Ret DECR RP IP=RS(RP) CASE %Jmp IP=CS(IP+1) CASE %Jle IF SS(SP-1)=<0 THEN IP=CS(IP+1) ELSE INCR IP,2 END IF CASE %Stor DS(CS(IP+1))=SS(SP-1) DECR SP INCR IP,2 CASE %Load INCR SP SS(SP)=DS(CS(IP+1)) INCR IP,2 CASE %In END CASE %Out PRINT SS(SP-1) INCR IP CASE ELSE INCR IP END SELECT LOOP END SUB |
||
Das große BlitzBasic Community Tutorial
Stackmaschine 2.0 |
ke^kx |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ist es so viel schneller das ganze mit IntegerVars zu machen als mit Strings? Ich Schreib nämlich selbst gerade an einem Interpreter (oder wie auch immer man das richtig nennt ![]() Jiriki |
||
http://i3u8.blogspot.com
Asus Striker II Intel Core2Quad Q9300 @ 2,5 GHz (aber nur zwei Kerne aktiv aufgrund der Instabilität -.-) Geforce 9800 GTX 2GB RAM |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Strings sind nicht umbedingt langsam, das hängt von ihrer Länge ab. Ein Int ist halt immer 4 Byte lang, während Strings keine feste Länge haben, weswegen dort entsprechende Tests länger oder kürzer werden können. Auch können sie nicht so hoch optimiert werden, wie mit Zahlen, eben wegen diesem variablen Verhalten. | ||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
ke^kx |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das heißt wenn ich statt der Zahlen von 1 - 255 für 255 verschiedene Befehle immer 5 Zeichen lange Strings (machmal auch länger) benutze ist es deutlich langsamer? Oder bleibt der Unterschied trotzdem gering, obwohl die Strings 5 mal so lang sind?
Jiriki [Edit] Ok, ich hab es gerade mal ausprobiert: Code: [AUSKLAPPEN] timer = MilliSecs ()
a = "Hallo" Select a Case "Hallo" Print "1" Case "Tschüss" Print "2" End Select Print MilliSecs () - timer Beim einen Versuch habe ich es so ausgeführt -> braucht 21 Millisekunden Beim anderen Versuch war a = 1 und die Select-Case Abfrage war 1 oder 2. -> 16 Millisekunden Also macht es schon einen gewaltigen Unterschied. Oh, noch mal schnell testen wie groß der Unterschied ist, der durch das Umwandeln entsteht. [Edit³] Ok, es lohnt sich trotzdem: 18 Millisekunden trotz vorherigen Umwandeln -> 3 Millisekunden unterschied pro bearbeiteten String, wobei dies nur bei einem Schleifendurchlauf ist, mit jeder weitern Prüfung vergrößert sich der Abstand... |
||
http://i3u8.blogspot.com
Asus Striker II Intel Core2Quad Q9300 @ 2,5 GHz (aber nur zwei Kerne aktiv aufgrund der Instabilität -.-) Geforce 9800 GTX 2GB RAM |
Florian |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Jiriki hat Folgendes geschrieben: Ist es so viel schneller das ganze mit IntegerVars zu machen als mit Strings?
Jiriki Test IntegerVars und StringsVars Code: [AUSKLAPPEN] Zeit=MilliSecs() For Z=1 To 20000 S$=S$+1 Next Print "Stringvariabeln: "+Str$(MilliSecs()-Zeit) Zeit=MilliSecs() For Z=1 To 20000 Zahl=Zahl+1 Next Zeit=MilliSecs() Print "Integervariabeln: "+Str$(MilliSecs()-Zeit) WaitKey Jiriki hat Folgendes geschrieben: Ich Schreib nämlich selbst gerade an einem Interpreter (oder wie auch immer man das richtig nennt :wink: ) und mir wurde gesagt, dass das bei 1000 durchgegangenen Befehlen nur ca. 0.1 Millisekunde ausmacht. In der OH heißt es aber das String die langsamsten Variablen seinen (was ja auch logisch ist). Wie groß ist denn nun der Unterschied? Leiber ist dem nicht so. Ich hatte mal einen Code Opimirer geschrieben bei den 1000 Befehlen ca. 200 Millisekunden dauern. |
||
Das große BlitzBasic Community Tutorial
Stackmaschine 2.0 |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
~AUFSPALTUNG~ Hatte nicht mehr wirklich was mit dem Updater zu tun Dreamora |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
ke^kx |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Huiuiu, bei dir ist der Unterschied ja noch größer... Ich seh schon, dass es sich wirklich lohnt, auch wenn es aufwendiger ist.
@Dreamora: Dankeschön ![]() Jiriki |
||
http://i3u8.blogspot.com
Asus Striker II Intel Core2Quad Q9300 @ 2,5 GHz (aber nur zwei Kerne aktiv aufgrund der Instabilität -.-) Geforce 9800 GTX 2GB RAM |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Aufwendiger ist es eigentlich nicht. Einfach Konstanten speichern mit den entsprechenden Namen und das wars ![]() |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
ke^kx |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Naja, man kann halt die Parameter nicht mehr in Klammern hinter den Befehl schreiben, sondern muss einen Befehl festsetzen, der angiebt, wie viele Parameter dem Befehl folgen. Außerdem ist es ein Problem dass man ja häufig auch größere Zahlen als Integer-Werte angeben muss, dafür braucht man dann auch immer extra Befehle... Also ist schon etwas aufwendiger. Aber es lohnt sich ja ![]() Jiriki |
||
http://i3u8.blogspot.com
Asus Striker II Intel Core2Quad Q9300 @ 2,5 GHz (aber nur zwei Kerne aktiv aufgrund der Instabilität -.-) Geforce 9800 GTX 2GB RAM |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group