Stimmt, das ist dann nicht ganz gerecht.
Da In-Place ersetzt wird, ist es jetzt schwierig da einen Praxistauglichen Test draus zu machen. In der Praxis wird man auch nicht 1 Mio. mal den selben String ersetzen. Man könnte für den Test 1 Million gleiche Strings erstellen und dann nacheinander von der Funktion abfrühstücken lassen. Denn das Kopieren des Ursprungsstrings macht viel Zeit aus.
///Edit:
Also eine neue Version: (Vorsicht! Das zieht bei Unicode fast 700 MB Arbeitsspeicher)
Code: Alles auswählen
Procedure ErsetzeString4(*input, pos.i, length.i, *replacement)
Protected *c.Character, *d.Character
*c = *input + (pos - 1) * SizeOf(Character)
*d = *replacement
While (*d\c And length >= 0)
*c\c = *d\c
*c + SizeOf(Character)
*d + SizeOf(Character)
length - 1
Wend
If (*d\c = 0)
*d + *input + (pos + length - 1) * SizeOf(Character) - *replacement
While (*d\c)
*c\c = *d\c
*c + SizeOf(Character)
*d + SizeOf(Character)
Wend
While (*c\c)
*c\c = 0
*c + SizeOf(Character)
Wend
Else
;length < len(*replacement)
EndIf
EndProcedure
Procedure ErsetzeString3(*input, pos.i, length.i, replacement.s)
Protected replaceLength.i = Len(replacement)
Protected *c.Character, *d.Character
If (replaceLength <= length)
CopyMemory(@replacement, *input + (pos - 1) * SizeOf(Character), replaceLength * SizeOf(Character))
If (replaceLength < length)
;MoveMemory(*input + (pos + replaceLength - 1) * SizeOf(Character), *input + (pos + length) * SizeOf(Character), )
*c = *input + (pos + length - 1) * SizeOf(Character)
*d = *input + (pos + replaceLength - 1) * SizeOf(Character)
While (*c\c)
*d\c = *c\c
*c + SizeOf(Character)
*d + SizeOf(Character)
Wend
While (*d\c)
*d\c = 0
*d + SizeOf(Character)
Wend
EndIf
Else
;fehlt noch
EndIf
EndProcedure
; a.s = "abcdefghijklmn"
; b.s = "xxx"
; ErsetzeString4(@a, 3, 3, @b)
; Debug a
;
; End
Macro ErsetzeString1(String, pos, laenge, ersatz)
Left(String, pos - 1) + ersatz + Mid(String, pos + laenge)
EndMacro
Macro ErsetzeString2(String , pos , laenge , Ersatz)
len_original = Len(PeekS(@String)) * SizeOf(Character)
l1 = pos + laenge - 1
len_rest = len_original - l1
b$ = PeekS(@String, pos - 1) + Ersatz + PeekS(@String + l1, len_rest)
EndMacro
; --------------------
#n = 10000000
time.s = ""
; Der Originalsatz
a$="Das war einmal der Satz"
Debug a$
Debug ""
; Das hier, weil ich zu faul zum selber Zaehlen bin
; und weil Änderungen ja später vom Prg. generiert werden könnten
lmax = Len(a$)
alt$ = "war einmal"
neu$ = "ist nun"
pos = FindString(a$,alt$)
laenge = Len(alt$)
; Ein Füllzeichen, wenn der Str. seine Länge behalten soll.
fuell$="."
; Nun der neue Satz 1, es ist laut Ausgabe der Schnellere
zeit = ElapsedMilliseconds()
For i=1 To #n
b$=ErsetzeString1(a$,pos,laenge,neu$)
Next
time + "Zeit 1 = " + Str(ElapsedMilliseconds() - zeit) + " ms" + #CRLF$
; Nun der neue Satz 2
zeit = ElapsedMilliseconds()
For i=1 To #n
ErsetzeString2(a$,pos,laenge,neu$)
Next
time + "Zeit 2 = " + Str(ElapsedMilliseconds() - zeit) + " ms" + #CRLF$
; Nun der neue Satz 3
Dim input_s.s(#n)
For i = 1 To #n
input_s(i) = a$
Next
zeit = ElapsedMilliseconds()
For i=1 To #n
ErsetzeString3(@input_s(i), pos, laenge, neu$)
Next
time + "Zeit 3 = " + Str(ElapsedMilliseconds() - zeit) + " ms" + #CRLF$
; Nun der neue Satz 4
For i = 1 To #n
input_s(i) = a$
Next
zeit = ElapsedMilliseconds()
For i=1 To #n
ErsetzeString4(@input_s(i), pos, laenge, @neu$)
Next
time + "Zeit 4 = " + Str(ElapsedMilliseconds() - zeit) + " ms" + #CRLF$
MessageRequester("Zeiten", time)
Mit Unicode:
Zeit 1 = 3125 ms
Zeit 2= 2675 ms
Zeit 3= 2102 ms
Zeit 4= 1472 ms
Ohne Unicode:
Zeit 1 = 1525 ms
Zeit 2 = 1557 ms
Zeit 3 = 1696 ms
Zeit 4 = 1431 ms