Wo hast du eigentlich die Funktion IntQ() her? Und wozu brauchst du die?
Deine StringField_RemoveField()-Procedure funktioniert nicht richtig:
Code: Alles auswählen
Procedure.s StringField_RemoveField(String$, Index, Separator$=" ") ; by AND51
Protected n.l=CountString(String$, Separator$), Position.q
If Index > n
Index=n
EndIf
For n=1 To Index
Position=FindString(String$, Separator$, Position+1)
Next
ProcedureReturn Left(String$, Position)+Right(String$, Len(String$)-(Position+Len(StringField(String$, Index+1, Separator$)))-Len(Separator$))
EndProcedure
String.s = "Das ist ein Teststring"
Debug "'" + StringField_RemoveField(String, 0) + "'"
Debug "'" + StringField_RemoveField(String, 3) + "'"
Zu dem Geschwindigkeitsvergleich:
Meine sind tatsächlich langsamer, allerdings kommt es mir so vor als ob
du den Test mit Debugger gemacht hast. Dann sind meine ganz klar viel
langsamer.
Das sind meine Testergebnisse auf einem Pentium 4 Mobile 1.8 GHz:
NicTheQuick:
- Insert: 2213 ms
- Remove: 1623 ms
- Swap: 2203 ms
AND51:
- Insert: 541 ms
- Remove: 290 ms
- Swap: 531 ms
Mit folgendem
Code: Alles auswählen
Procedure.s StringField2_InsertString(String$, InsertString$, Index=1, Separator$=" ") ; by AND51
Protected n.l, Position.q
If Index > CountString(String$, Separator$) And Not Right(String$, Len(Separator$)) = Separator$
String$+Separator$
EndIf
If FindString(String$, Separator$, 1)
For n=1 To Index
Position=FindString(String$, Separator$, Position+1)
Next
ProcedureReturn Left(String$, Position)+InsertString$+Separator$+Right(String$, Len(String$)-Position)
Else
ProcedureReturn String$
EndIf
EndProcedure
Procedure.s StringField2_SwapFields(String$, FieldA, FieldB, Separator$=" ") ; by AND51
If FieldA <> FieldB
String$+Separator$
If FieldA > FieldB
Swap FieldA, FieldB
EndIf
Protected FieldA$=StringField(String$, FieldA+1, Separator$), FieldB$=StringField(String$, FieldB+1, Separator$)
FieldA=FindString(String$, FieldA$, 1)
FieldB=FindString(String$, FieldB$, 1)
ProcedureReturn Left(Left(String$, FieldA-1)+FieldB$+Mid(String$, FieldA+Len(FieldA$), FieldB-FieldA-Len(FieldA$))+FieldA$+Right(String$, Len(String$)-(FieldB+Len(FieldB$))+1), Len(String$)-Len(Separator$))
Else
ProcedureReturn String$
EndIf
EndProcedure
Procedure.s StringField2_RemoveField(String$, Index, Separator$=" ") ; by AND51
Protected n.l=CountString(String$, Separator$), Position.q
If Index > n
Index=n
EndIf
For n=1 To Index
Position=FindString(String$, Separator$, Position+1)
Next
ProcedureReturn Left(String$, Position)+Right(String$, Len(String$)-(Position+Len(StringField(String$, Index+1, Separator$)))-Len(Separator$))
EndProcedure
Procedure.s StringField_InsertString(String.s, InsertString.s, Index.l, Seperator.s = " ")
Protected result.s, *c.Character, *sep.Character, a.l = 0, Char.l = 1, ok = #False
*c = @String
*sep = @Seperator
While *c\c
If a = Index
If Char = 1
result + InsertString + Chr(*sep\c)
ok = #True
ElseIf PeekC(*c - SizeOf(Character)) = *sep\c
result + InsertString + Chr(*sep\c)
ok = #True
EndIf
EndIf
result + Chr(*c\c)
If *c\c = *sep\c : a + 1 : EndIf
*c + SizeOf(Character)
Char + 1
Wend
If Index > a : result + Chr(*sep\c) : EndIf
If Index => a And ok = #False : result + InsertString : EndIf
ProcedureReturn result
EndProcedure
Procedure.s StringField_SwapFields(String.s, Index1.l, Index2.l, Seperator.s = " ")
Protected *c.Character, *sep.Character, l1.l, l2.l, a.l = 1, *f1.Character, *f2.Character, result.s
If Index1 = Index2 : ProcedureReturn String : EndIf
If Index1 > Index2 : Swap Index1, Index2 : EndIf
If Index1 < 1 Or Index2 < 1 : ProcedureReturn String : EndIf
*c = @String
*sep = @Seperator
*f1 = *c
While *c\c
If *c\c = *sep\c
a + 1
If a = Index1 : *f1 = *c + SizeOf(Character) : EndIf
If a = Index2 : *f2 = *c + SizeOf(Character) : EndIf
Else
If a = Index1 : l1 + 1 : EndIf
If a = Index2 : l2 + 1 : EndIf
EndIf
*c + SizeOf(Character)
Wend
*c = @String
While *c\c
If *c = *f1
a = l2
While a
result + Chr(*f2\c)
*f2 + SizeOf(Character)
a - 1
Wend
*f2 - SizeOf(Character) * l2
*c + SizeOf(Character) * l1
ElseIf *c = *f2
While l1
result + Chr(*f1\c)
*f1 + SizeOf(Character)
l1 - 1
Wend
*c + SizeOf(Character) * l2
Else
result + Chr(*c\c)
*c + SizeOf(Character)
EndIf
Wend
ProcedureReturn result
EndProcedure
Procedure.s StringField_RemoveField(String.s, Index.l, Seperator.s = " ")
Protected result.s, a.l = 1, *c.Character, *sep.Character, ok = #False
*c = @String
*sep = @Seperator
While *c\c
If *c\c = *sep\c : a + 1 : EndIf
If a <> Index
If a <> 2 Or *c\c <> *sep\c Or Index <> 1
result + Chr(*c\c)
EndIf
EndIf
*c + SizeOf(Character)
Wend
ProcedureReturn result
EndProcedure
#Max = 100000
#CRLF = Chr(13) + Chr(10)
String.s = "Franz jagt im komplett verwahrlosten Taxi quer durch Bayern."
res.s
Times.s
time_ntq_1.l = ElapsedMilliseconds()
For a = 1 To #Max
res = StringField_InsertString(String, "ganz", 8)
Next
time_ntq_1 = ElapsedMilliseconds() - time_ntq_1
time_ntq_2.l = ElapsedMilliseconds()
For a = 1 To #Max
res = StringField_RemoveField(String, 4)
Next
time_ntq_2 = ElapsedMilliseconds() - time_ntq_2
time_ntq_3.l = ElapsedMilliseconds()
For a = 1 To #Max
res = StringField_SwapFields(String, 7, 8)
Next
time_ntq_3 = ElapsedMilliseconds() - time_ntq_3
time_and_1.l = ElapsedMilliseconds()
For a = 1 To #Max
res = StringField2_InsertString(String, "ganz", 8)
Next
time_and_1 = ElapsedMilliseconds() - time_and_1
time_and_2.l = ElapsedMilliseconds()
For a = 1 To #Max
res = StringField2_RemoveField(String, 3)
Next
time_and_2 = ElapsedMilliseconds() - time_and_2
time_and_3.l = ElapsedMilliseconds()
For a = 1 To #Max
res = StringField2_SwapFields(String, 6, 7)
Next
time_and_3 = ElapsedMilliseconds() - time_and_3
Times = "NicTheQuick:" + #CRLF + "- Insert: " + Str(time_ntq_1) + " ms" + #CRLF + "- Remove: " + Str(time_ntq_2) + " ms" + #CRLF + "- Swap: " + Str(time_ntq_3) + " ms" + #CRLF + #CRLF
Times + "AND51:" + #CRLF + "- Insert: " + Str(time_and_1) + " ms" + #CRLF + "- Remove: " + Str(time_and_2) + " ms" + #CRLF + "- Swap: " + Str(time_and_3) + " ms" + #CRLF
MessageRequester("Zeiten: ", Times)
; SetClipboardText(Times)
Ist aber interessant zu sehen, was die Stringfunktionen von PB alles so
rausholen. Aber ich denke mit ASM kann man die Funktionen noch einiges
optimieren.
