Seite 2 von 3
Verfasst: 19.03.2005 18:28
von Danilo
remi_meier hat geschrieben:Aber ich bin mir mit dem InlineAsm nicht mehr so sicher..
Du machst ein "CMP EAX,0", d.h. der Pointer wird auf 0 geprüft,
aber nicht das Byte auf den der Pointer zeigt, also das Ende des
Strings.
Wenn nichts gefunden wurde, sollte die Prozedur auch 0 zurückgeben,
und nicht irgendwas.
Verfasst: 19.03.2005 18:40
von remi_meier
OK danke!
Habs geändert, nur jetzt bin ich sicher, dass mans besser machen könnte, ich komm nur grad nicht drauf
cu
Remi
Edit: Lol, hab das Gröbste grad mal rausgenommen! Ich sollte nicht mehr so schnell posten... Ich habs nun auch mit Kommentaren versehen
Verfasst: 20.03.2005 01:02
von Helle
Wie wär´s damit:
Code: Alles auswählen
Procedure FindChar(*string.BYTE, asc.l)
;start = *string
MOV eax, *string ;Pointer auf String in eax
MOV ebx, asc ;Ascii-code von Zeichen in ebx, genauer bl
startpunkt:
CMP byte[eax], 0 ;überprüfen, ob Stringende
JZ l_notfound ;wenn ja, return 0!
CMP byte[eax], bl ;überprüfen, ob gefunden
JE l_jump ;wenn ja, dann aus schleife raus
INC eax ;Stringpointer erhöhen
JMP l_startpunkt ;zum Schleifenstart springen
jump: ;Ende der Schleife
SUB eax, *string ;Pointer subtrahieren, um Pos. zu bekommen
INC eax ;Position von _1_ bis x
ProcedureReturn
notfound: ;wenn nicht gefunden
ProcedureReturn 0
; While *string\b
; If *string\b = asc
; ProcedureReturn *string - start + 1
; EndIf
; *string + 1
; Wend
EndProcedure
Procedure FindChar1(*string.l, asc.l, laenge.l)
CLD
MOV edi,*string
MOV eax,asc
MOV ecx,laenge
REPNZ scasb
JNZ l_notfound1
SUB edi,*string
MOV eax,edi ;Rückgabewert
ProcedureReturn
notfound1: ;wenn nicht gefunden
ProcedureReturn 0
EndProcedure
#N = 900000
String.s = "searchinmeeeeeeee3123456123cb1g2348cbnq0webftrqc0n9qwbet691bt4 qböoäöa-asbe0rß1bv634r660qlbdf-asubdpfz10735646vrzpawbwöehbf76v6r9b3807b1p9sbaösejhbfquiowebz7r81bvg5340brqpweöfjkqböwev qöwjerh 1092346r18 4rpuqwzefqhw7e1 34nr7q0 w8 eh7r0q whe7qf0 wnejöasdjfh0q93478zbr1093br4höaowuez f0q7wez0fr13j4u rhqw7e rfqwe7rq0w9e rqh3 er13 4rqpweör v#"
tofind.s = "#"
asctofind.l = Asc(tofind)
ptr.l = @String
laenge.l=Len(String)
Delay(1000)
Time1 = GetTickCount_()
For I = 0 To #N
FindChar(ptr, asctofind)
Next
Time1 = GetTickCount_() - Time1
Time2 = GetTickCount_()
For I = 0 To #N
FindString(String, tofind, 0)
Next
Time2 = GetTickCount_() - Time2
Time3 = GetTickCount_()
For I = 0 To #N
Stelle.l = FindChar1(ptr, asctofind, laenge)
Next
Time3 = GetTickCount_() - Time3
strOut.s = "FindChar: " + Str(Time1) + #CRLF$
strOut.s = strOut.s + "FindString: " + Str(Time2) + #CRLF$
strOut.s = strOut.s + "FindChar1: " + Str(Time3) + " " + Str(Stelle)
MessageRequester("Ergebnis", strOut)
Neu: FindChar1; benötigt Stringlänge bei Aufruf, es sei denn man ist sich
sicher, dass das Zeichen auf jeden Fall vorhanden ist. Zur Kontrolle wurde
Stelle mit angegeben.
Bringt hier aber nur bei längeren Strings Punkte; kann aber an der Art des
Aufrufes liegen.
Gruss
Helle
Verfasst: 20.03.2005 01:16
von remi_meier
Es geht (fast) immer kürzer

(wobei der kleine Geschwindigkeitsunterschied wohl aus der CISC-Architektur (wenn ich mich nicht irre..) folgt, die z.T. langsamer ist).
cu
Remi
PS: Helle, ich glaub du bist es, der meine Frage im Optimizer-Thread beantworten könnte (die ist ja schon ne Zeit lang offen, und mir is langweilig)
Verfasst: 20.03.2005 08:35
von Helle
Hier wird doch wohl keiner auf einer RISC-Kiste testen und mich ins Grübeln kommen lassen wollen

?
Ich dachte mehr an den Aufruf einer Prozedur und den damit notwendigen (???) Einsatzes der Inline-ASM-Unterstützung. Folgende Variante
Code: Alles auswählen
#N = 900000
String.s = "searchinmeeeeeeee3123456123cb1g2348cbnq0webftrqc0n9qwbet691bt4 qböoäöa-asbe0rß1bv634r660qlbdf-asubdpfz10735646vrzpawbwöehbf76v6r9b3807b1p9sbaösejhbfquiowebz7r81bvg5340brqpweöfjkqböwev qöwjerh 1092346r18 4rpuqwzefqhw7e1 34nr7q0 w8 eh7r0q whe7qf0 wnejöasdjfh0q93478zbr1093br4höaowuez f0q7wez0fr13j4u rhqw7e rfqwe7rq0w9e rqh3 er13 4rqpweör v#"
tofind.s = "#"
asctofind.l = Asc(tofind)
ptr.l = @String
laenge.l=Len(String)
Delay(1000)
Time = GetTickCount_()
For I = 0 To #N
!CLD
!MOV ecx,[v_laenge]
!MOV edi,[v_ptr]
!MOV eax,[v_asctofind]
!REPNZ scasb
!JNZ l_notfound
!SUB edi,[v_ptr]
!JMP l_found
notfound: ;wenn nicht gefunden
!XOR edi,edi
found:
!MOV [v_Stelle],edi
Next
Time = GetTickCount_() - Time
strOut.s = "FindChar: " + Str(Time) + " " + Str(Stelle)
MessageRequester("Ergebnis", strOut)
ohne Inline-ASM ist über 3-mal schneller als FindString, und zwar ist es jetzt völlig egal, an welcher Stelle das zu suchende Zeichen steht!
Zur Ehrenrettung von FindString muss aber unbedingt gesagt werden, dass es universieller arbeitet und auch String-Teile (nicht nur 1 Zeichen)
finden muss. Wenn obiger Code auch in einer Prozedur (viel) schneller
wäre als Findstring könnte man überlegen, eben eine Funktion "FindChar"
einzusetzen. Mal sehen...
Mein heißgeliebtes ALIGN brachte übrigens in keiner Variante hier Punkte... Wird wohl inzwischen von den zwischengeschalteten Progs bzw.
BS selbst erledigt.
Gruss
Helle
Verfasst: 20.03.2005 11:19
von Helle
Übrigens, ganz interessant aus den Beispielen mal Exen machen

!!!
Gruss
Helle
Verfasst: 20.03.2005 11:47
von remi_meier
Nene keine RISC Kiste
Also wenn ich EXEn mache, sehe ich keinen Unterschied..
Das ALIGN nützt hier wohl nichts, weil die Schleife-Jumps nicht die meiste Zeit verschlingen! Bei meinem folgenden Beispiel wirkt ALIGN immernoch
Code: Alles auswählen
!ALIGN 4
#N = 9999999999
Delay(1000)
time1 = ElapsedMilliseconds()
For z = 0 To #N
Next
time1 = ElapsedMilliseconds() - time1
time2 = ElapsedMilliseconds()
For z = 0 To #N
Next
time2 = ElapsedMilliseconds() - time2
MessageRequester("",Str(time1)+" "+Str(time2))
cu
Remi
Verfasst: 20.03.2005 19:40
von Helle
@remi: Der Unterschied mit den Exen ist tatsächlich nicht so gross wie bei
meinen Tests. Ursache: Habe meine Kiste in den letzten Tagen neu aufge-
setzt und dabei auf PB3.93 umgestellt. Jetzt werden aber Einstellungen den
Compiler und Debugger betreffend nicht mehr für den nächsten Programmstart abgespeichert; wenn ich nicht aufpasse ist beim Testen der
Debugger aktiv usw.
Habe mir heute deinen Optimizer runtergeladen und werde ihn mir mal zu
Gemüte führen. Dazu ein Wunsch: Aktualisiere doch mal die (eigentliche)
FAsm.exe (bei dir FAsm2.exe)! Du und PB setzen noch die Version 1.56 ein; aktuell ist 1.60 (jetzt mit 64-Bit Unterstützung!). Ich aktualisiere stets von Hand und kann berichten es treten keinerlei Probleme auf, ganz im Gegenteil

!
Gruss
Helle
Verfasst: 09.04.2005 10:20
von Kaeru Gaman
Helle hat geschrieben:Jetzt werden aber Einstellungen den Compiler und Debugger betreffend nicht mehr für den nächsten Programmstart abgespeichert
*seufz* also noch ein FROG, der gefixt werden muss....
Verfasst: 09.04.2005 15:57
von Sylvia
Die Abteilung "Code, Tipps und Tricks" wird ja geradezu mit nützlichen
Beiträgen überflutet
