Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Leo
Beiträge: 420 Registriert: 26.10.2004 18:26
Beitrag
von Leo » 19.03.2005 17:34
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?
NicTheQuick
Ein Admin
Beiträge: 8809 Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200 Ubuntu 24.04.2 LTS GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Beitrag
von NicTheQuick » 19.03.2005 17:46
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)
Leo
Beiträge: 420 Registriert: 26.10.2004 18:26
Beitrag
von Leo » 19.03.2005 17:51
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..
MVXA
Beiträge: 3823 Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:
Beitrag
von MVXA » 19.03.2005 18:00
ist ja auch n byte...
DarkDragon
Beiträge: 6291 Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:
Beitrag
von DarkDragon » 19.03.2005 18:00
probier mal p_string
geht vielleicht beim inline ASM(ohne das ! am anfang).
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Leo
Beiträge: 420 Registriert: 26.10.2004 18:26
Beitrag
von Leo » 19.03.2005 18:02
MVXA hat geschrieben: ist ja auch n byte...
Nein, ist es nicht
remi_meier
Beiträge: 1078 Registriert: 29.08.2004 20:11
Wohnort: Schweiz
Beitrag
von remi_meier » 19.03.2005 18:07
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
Zuletzt geändert von
remi_meier am 19.03.2005 18:47, insgesamt 4-mal geändert.
MVXA
Beiträge: 3823 Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:
Beitrag
von MVXA » 19.03.2005 18:08
hab nur auf mov und dword geschaut. ich hab gedacht du fragst dort den string direkt ab. ist ja auch egal.... <_<
Leo
Beiträge: 420 Registriert: 26.10.2004 18:26
Beitrag
von Leo » 19.03.2005 18:11
Cool! Ich versteh sogar fast alles
Nur was sind JZ (Könnte JumpZero heißen, würde sogar passen) und bl?
remi_meier
Beiträge: 1078 Registriert: 29.08.2004 20:11
Wohnort: Schweiz
Beitrag
von remi_meier » 19.03.2005 18:13
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