![]() |
Was ist schneller? function oder 3x stringreplace?
Hallo,
ich hab mal wieder eine Frage! was ist schneller - diese Function:
Delphi-Quellcode:
oder diese 3 StringReplace´s:
function ZahlAusString(const S: string): string;
var i, j: Integer; begin SetLength(Result, Length(S)); j := 0; for i := 1 to Length(S) do If S[i] in ['0'..'9'] then begin Inc(j); Result[j] := S[i]; end; SetLength(Result, j); end;
Delphi-Quellcode:
Der Hintergrund ist, dass ich ein Editfeld habe, indem eine Telefonnummer steht, dessen Vorwahl in Klammern steht und nach der letzten Klammer und der eigentlichen Nummer ein Leerzeichen ist.
S := MaskEdit_Anrufe.EditText;
S := StringReplace(S, '(', '', [rfReplaceAll]); S := StringReplace(S, ')', '', [rfReplaceAll]); S := StringReplace(S, ' ', '', [rfReplaceAll]); In meinem Code vergleich ich einen String, in dem die gesamte Telefonnummer (inkl. Vorwahl) ohne Klammern und Leerzeichen steht, mit dem Eingabefeld. Deshalb würds mich interessieren was schneller ist - die Function oder die 3 StringReplace´s. Ich schätze die Function - was meint ihr? |
Re: Was ist schneller? function oder 3x stringreplace?
Auf keinen Fall
![]() ![]() |
Re: Was ist schneller? function oder 3x stringreplace?
HI!
Ich vermute(!) Version 1, da Stringreplace wohl auch über das komplette "Array" läuft und dann eben 3x drüber muss. Ciao Frederic |
Re: Was ist schneller? function oder 3x stringreplace?
Edit: Unsinn entfernt. Ich brauch 'ne Brille ;)
|
Re: Was ist schneller? function oder 3x stringreplace?
Wenn ich das hier lese :
Zitat:
|
Re: Was ist schneller? function oder 3x stringreplace?
|
Re: Was ist schneller? function oder 3x stringreplace?
stringreplace sollte auf jeden fall langsamer sein da es allgemein gehalten ist. außerdem würdest du mit stringreplace wie schon gepostet das ganze 3 mal durchgehen, bei deiner variante allerdings nur einmal..
|
Re: Was ist schneller? function oder 3x stringreplace?
danke für eure Antworten!
ich hab mir mal den Code vom "StringReplace" angeschaut und dort ist auch eine Schleife enthalten. Wenn ich also nun StringReplace 3 mal aufrufe, läuft die Schleife auch 3 mal. Bei meiner Function nur einmal! Ich hab jetzt meinen Code auf meine Function umgeschrieben. |
Re: Was ist schneller? function oder 3x stringreplace?
Generell dürfte ein Besuche bei den
![]() Bei deiner Funktion fällt mir auf, dass du die Größe des Strings 2-mal besetzt und Zum Iterieren durch einen string eignet sich ein PChar ganz gut. ;)
Delphi-Quellcode:
function ZahlAusString(const aSearchString: string): string;
var i : Integer; CurrentChar : PChar; NumberFound : Boolean; NumberStart : Integer; NumberLength : Integer; begin NumberFound := False; NumberStart := -1; NumberLength := 0; CurrentChar := PChar(aSearchString); for i := 1 to Length(aSearchString) do begin if CurrentChar^ in ['0'..'9'] then begin inc(NumberLength); if not NumberFound then begin NumberStart := i; NumberFound := True; end; end else if NumberFound then break; inc(CurrentChar); end; if NumberFound then result := Copy(aSearchString, NumberStart, NumberLength) else result := ''; end; |
Re: Was ist schneller? function oder 3x stringreplace?
@Robert_G
Da fehlt noch ein Break oder ähnliches, sonst wird nämlich aus "(02622) 1234" einfach nur "02622) 1234". Sprich sobald NumberFound true ist müsste bei der nächsten "Nichtziffer" gestoppt werden. |
Re: Was ist schneller? function oder 3x stringreplace?
Zitat:
|
Re: Was ist schneller? function oder 3x stringreplace?
Zitat:
|
Re: Was ist schneller? function oder 3x stringreplace?
Wieso funktioniert denn das?
Delphi-Quellcode:
Woher weiss er welcher char in der schleife bearbeitet werden soll?
CurrentChar := PChar(aSearchString);
for i := 1 to Length(aSearchString) do begin if CurrentChar^ in ['0'..'9'] then begin inc(NumberLength); if not NumberFound then begin NumberStart := i; NumberFound := True; end; end else if NumberFound then break; inc(CurrentChar); end; |
Re: Was ist schneller? function oder 3x stringreplace?
CurrentChar ist ein zeiger auf das aktuelle zeichen.
inc(CurrentChar) setzt den zeiger eine addresse weiter. |
Re: Was ist schneller? function oder 3x stringreplace?
Danke für die Erklärung!
Aber nochmal zu Robert´s Code. Ich hab den heut mal ausprobiert - der hat nen kleinen Nachteil. Der gibt nur Vorwahl aus. |
Re: Was ist schneller? function oder 3x stringreplace?
Zitat:
Zu schnell irgendwas runtergetippt... (Wäre ja auch langweilig wenn geposteter Code einfach so funktioniert... :mrgreen: ) |
Re: Was ist schneller? function oder 3x stringreplace?
Hallo,
ich möchte an meinen alten Thread anknüpfen, da meine jetzige Frage im Grunde auch was damit zu tun hat. Folgendes: Ich muss Chars gegen Chars im Hex-Format austauschen. Soweit so gut. Meine erste Version schaut so aus:
Delphi-Quellcode:
Wie man sieht, wird dort 10x StringReplace aufgerufen, um jeweils ein Char gegen ein Char aus Hex-Werten zu ersetzen.
Text := StringReplace(Text, 'ü', Chr($81), [rfReplaceAll]);
Text := StringReplace(Text, 'ä', Chr($84), [rfReplaceAll]); Text := StringReplace(Text, 'ö', Chr($94), [rfReplaceAll]); Text := StringReplace(Text, 'Ü', Chr($9A), [rfReplaceAll]); Text := StringReplace(Text, 'Ä', Chr($8E), [rfReplaceAll]); Text := StringReplace(Text, 'Ö', Chr($99), [rfReplaceAll]); Text := StringReplace(Text, 'ß', Chr($E1), [rfReplaceAll]); Text := StringReplace(Text, '²', Chr($FD), [rfReplaceAll]); Text := StringReplace(Text, '³', Chr($FE), [rfReplaceAll]); Text := StringReplace(Text, 'µ', Chr($E6), [rfReplaceAll]); Serial.TransmittText(Text); Funktioniert auch - nur da StringReplace langsam ist, dacht ich mir ich könnt es anders machen. Dafür hab ich mir diesen Code ausgedacht:
Delphi-Quellcode:
Ich vermute mal, dass dieser Code schneller ist als 10x StringReplace.
const
Chars: array[1..10] of Char = ('ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', 'ß', '²', '³', 'µ'); Bytes: array[1..10] of Byte = ($84, $94, $81, $8E, $99, $9A, $E1, $FD, $FE, $E6); var i: Integer; j: Integer; S_Text: String; C_Char: Char; begin SetLength(S_Text, length(Text)); S_Text := ''; for i := 1 to length(Text) do begin C_Char := Text[i]; for j := Low(Chars) to High(Chars) do If Chars[j] = C_Char then begin C_Char := Chr(Bytes[j]); break; end; S_Text := S_Text + C_Char; end; Serial.TransmittText(S_Text); Was vermutet ihr? Auch wenn´s etwas OT ist, bringt diese Zeile überhaupt was :?:
Delphi-Quellcode:
SetLength(S_Text, length(Text));
|
Re: Was ist schneller? function oder 3x stringreplace?
Zitat:
|
Re: Was ist schneller? function oder 3x stringreplace?
Zitat:
Zum zeitmessen einfach mal nach GetTickCount suchen. Gruß |
Re: Was ist schneller? function oder 3x stringreplace?
|
Re: Was ist schneller? function oder 3x stringreplace?
Moin Helmi,
zu dem hier
Delphi-Quellcode:
fällt mir leider nur ein Wort ein: Sinnbefreit ;-)
SetLength(S_Text, length(Text));
S_Text := ''; Ist nicht böse gemeint, denn schliesslich kann man nicht alles wissen. Durch das SetLength sorgst Du dafür, dass S_Text soviele Zeichen aufnehmen kann, wie Text lang ist, und mit S_Text := '' bringst Du die Länge wieder auf 0. So wie Du es geschrieben hast (immer das jeweilige Zeichen zum Ergebnisstring addieren) könntest Du SetLength also weglassen... ABER: Da Quell- und Zielstring auch nach dem Ersetzen der Zeichen gleich lang sind, solltest Du besser auf das S_Text := '' verzichten, und die Ersetzung anders lösen (auch wenn Deine Lösung wohl schon merklich schneller sein dürfte als die Variante mit StringReplace), Du kannst nämlich einfach die Zeichen, die unverändert bleiben sollen direkt an den Index im Zielstring schreiben, aus dem Du sie aus dem Quellstring gelesen hast. Ausserdem ist es ungünstig jedesmal in einer Schleife den gesamten String der zu ersetzenden Zeichen durchzugehen, vermutlich wäre hier sogar die Verwendung von Pos schneller. Ich würde es allerdings mit Case lösen:
Delphi-Quellcode:
Über die Reihenfolge musst Du Dir keine Gedanken machen, dass sortiert der Compiler schon so, dass die Case-Anweisung möglichst schnell durchlaufen wird.
var
i: Integer; S_Text: String; begin SetLength(S_Text, length(Text)); for i := 1 to length(Text) do begin case Text[i] of 'ä' : S_Text[i] := chr($84); 'ö' : S_Text[i] := chr($94); //... usw. bis 'µ', dann else S_Text[i] := Text[i]; end; end; Serial.TransmittText(S_Text); end; Mit ein wenig mehr Aufwand könnte man das Ganze auch für Ersetzungen umbauen, die nicht 1:1 sind. |
Re: Was ist schneller? function oder 3x stringreplace?
Hallo Christian,
danke für deine Hinweise. Ich hab eigentlich bisher kaum mit Setlength bei Strings gearbeitet. Die erste Version von dem Code war ohne SetLength. Erst zum Schluss dacht ich mir, da ich schon öfters hier gelesen habe, dass es was bringe, wenn man den "Ausgabe_String" mit SetLength auf die Länge des "Eingabe_Strings" bringt. Dass dann das
Delphi-Quellcode:
das SetLength wieder aufhebt, war mir nicht bewusst. Ist aber gut zu wissen.
S := '';
eine alte Version mit einer case-Abfrage, hatte ich auch mal (die schwirrt auch hier in der DP rum). Da ich aber mal die Länge der Array varierbar machen möchte, wär eine Case-Abfrage nicht möglich. Ich würd schon gern bei dem oberen Code bleiben. Was mir natürlich auch nicht gefällt, dass bei dem oberen Code bei jedem Char die j-Schleife (for-Schleife) durchlaufen werden muss. Ich hab ja momentan einen Parallel-Thread hier in der DP laufen, in dem die Frage gestellt wurde, ob es nicht möglich ist, ohne Schleife einen Eintrag in einem Array zu erhalten (als Index). Pos hab ich versucht, aber ich habs bisher noch nicht mit Arrays gemacht und bin deshalb daran gescheitert |
Re: Was ist schneller? function oder 3x stringreplace?
Hallo,
wieder einmal muss ich auf meine Funktion ![]() Gruß xaromz |
Re: Was ist schneller? function oder 3x stringreplace?
Moin Helmi,
ich hätte da auch noch eine variable Lösung anzubieten:
Delphi-Quellcode:
sTranslation müsste nur entsprechend gefüllt sein, und natürlich alle 256 Zeichen enthalten, wobei an dem Index der zu übersetzenden Zeichen, jeweils der Code des neuen gespeichert ist, und an allen anderen der korrespondierende (z.B. an Index 66 steht 65, +1, da der erste Index im String ja 1 und nicht 0 ist)
var
sTranslation : string; sSource : string; sDest : string; i : Integer; begin SetLength(sDest,Length(sSource)); for i := 1 to Length(sSource) do begin sDest[i] := sTranslation[Ord(sSource[i])+1]; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:53 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz