Seite 1 von 3
FindChar
Verfasst: 19.03.2005 17:34
von Leo
Ich hab ne Procedure geschrieben um einen
einzigen Buchstaben in einem String zu suchen.
PB's FindString scheint jedoch schneller als
mein FindChar zu sein
Code: Alles auswählen
Procedure FindChar(*string.BYTE,asc.l,lenstr)
start = *string
Repeat
If *string\b = asc
ProcedureReturn *string - start + 1
EndIf
*string + 1
Until *string\b = 0
EndProcedure
#N = 1000000
string.s = "searchinmeeeeeeee3"
tofind.s = "3"
asctofind.l = Asc(tofind)
len.l = Len(string)
ptr.l = @string
Time1 = GetTickCount_()
For I = 0 To #N
FindChar(ptr,asctofind,len)
Next
Time1 = GetTickCount_() - Time1
Time2 = GetTickCount_()
For I = 0 To #N
FindString(string,tofind,0)
Next
Time2 = GetTickCount_() - Time2
strOut.s = "FindChar: "+Str(Time1)+#CRLF$
strOut.s = strOut.s + "FindString: "+Str(Time2)
MessageRequester("Ergebnis",strOut)
Weiß jemand, wie man das noch optimieren könnte?
Verfasst: 19.03.2005 17:46
von NicTheQuick
Ich habe mal deinen 3. Parameter rausgenommen. Den hast du ja sowieso nicht gebraucht. Leider hat das nicht viel geändert. Womöglich ist die Funktion [c]FindString()[/c] aus PureBasic in ASM optimiert oder sowas.
Code: Alles auswählen
Procedure FindChar(*string.BYTE, asc.l)
start = *string
While *string\b
If *string\b = asc
ProcedureReturn *string - start + 1
EndIf
*string + 1
Wend
EndProcedure
#N = 1000000
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)
len.l = Len(String)
ptr.l = @String
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
strOut.s = "FindChar: " + Str(Time1) + #CRLF$
strOut.s = strOut.s + "FindString: " + Str(Time2)
MessageRequester("Ergebnis", strOut)
Verfasst: 19.03.2005 17:51
von Leo
Oops! Hatte das vorher mit einer For/Next Schleife gemacht,
deswegen der 3. Parameter...
Ich probier schon die ganze Zeit, da irgendwas mit ASM
zu machen, komme aber nicht weit..
Ich weiß nämlich nicht, wie ich mit InlineAssembler auf *string
zugreifen kann
[c]!MOV eax,dword[v_*string][/c] scheint ja nicht zu gehen..
Verfasst: 19.03.2005 18:00
von MVXA
ist ja auch n byte...
Verfasst: 19.03.2005 18:00
von DarkDragon
probier mal p_string

geht vielleicht beim inline ASM(ohne das ! am anfang).
Verfasst: 19.03.2005 18:02
von Leo
MVXA hat geschrieben:ist ja auch n byte...
Nein, ist es nicht
Verfasst: 19.03.2005 18:07
von remi_meier
Wie wärs 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
#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
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
strOut.s = "FindChar: " + Str(Time1) + #CRLF$
strOut.s = strOut.s + "FindString: " + Str(Time2)
MessageRequester("Ergebnis", strOut)
Weiss nicht obs am optimalsten ist oder obs vollständig stimmt, aber..
cu
Remi

Verfasst: 19.03.2005 18:08
von MVXA
hab nur auf mov und dword geschaut. ich hab gedacht du fragst dort den string direkt ab. ist ja auch egal.... <_<
Verfasst: 19.03.2005 18:11
von Leo
Cool! Ich versteh sogar fast alles
Nur was sind JZ (Könnte JumpZero heißen, würde sogar passen) und bl?
Verfasst: 19.03.2005 18:13
von remi_meier
JZ = JumpIfZero könnte auch JE sein (JumpIfEqual)
bl = LowByte of Ebx-Register
Aber ich bin mir mit dem InlineAsm nicht mehr so sicher..
Vielleicht verschieb ich da ein bisschen was falsches, ich überprüfs mal
cu
Remi