Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Was ist schneller? function oder 3x stringreplace? (https://www.delphipraxis.net/48979-ist-schneller-function-oder-3x-stringreplace.html)

Helmi 3. Jul 2005 21:05


Was ist schneller? function oder 3x stringreplace?
 
Hallo,

ich hab mal wieder eine Frage!

was ist schneller - diese Function:
Delphi-Quellcode:
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;
oder diese 3 StringReplace´s:

Delphi-Quellcode:
  S := MaskEdit_Anrufe.EditText;
  S := StringReplace(S, '(', '', [rfReplaceAll]);
  S := StringReplace(S, ')', '', [rfReplaceAll]);
  S := StringReplace(S, ' ', '', [rfReplaceAll]);
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.

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?

MathiasSimmack 3. Jul 2005 21:12

Re: Was ist schneller? function oder 3x stringreplace?
 
Auf keinen Fall Delphi-Referenz durchsuchenStringReplace. Ich bin zwar nicht firm in Sachen Funktionsanalyse (bezogen auf die Geschwindigkeit), aber Delphi-Referenz durchsuchenStringReplace war schon immer a****langsam.

fkerber 3. Jul 2005 21:12

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

malo 3. Jul 2005 21:14

Re: Was ist schneller? function oder 3x stringreplace?
 
Edit: Unsinn entfernt. Ich brauch 'ne Brille ;)

Hansa 3. Jul 2005 21:30

Re: Was ist schneller? function oder 3x stringreplace?
 
Wenn ich das hier lese :
Zitat:

Delphi 7 Professional
dann würde ich mal im Source nachgucken ! SysUtils.Pas vermutlich. Aber ehrlich gesagt : würde das nur untersuchen, wenn es um ein gigantisches Programm handelt !!

MathiasSimmack 3. Jul 2005 21:41

Re: Was ist schneller? function oder 3x stringreplace?
 
Ich habe nur Delphi 5, Hansa, und bei mir ist Delphi-Referenz durchsuchenStringReplace auch lahm.
Also, wie jetzt? :gruebel:

SirThornberry 3. Jul 2005 21:57

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..

Helmi 3. Jul 2005 22:00

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.

Robert_G 3. Jul 2005 22:04

Re: Was ist schneller? function oder 3x stringreplace?
 
Generell dürfte ein Besuche bei den Bei Google suchenFastcoders einen Versuch Wert sein.

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;

scp 3. Jul 2005 22:21

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.

Robert_G 3. Jul 2005 22:24

Re: Was ist schneller? function oder 3x stringreplace?
 
Zitat:

Zitat von scp
@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.

Ups, da hast du natürlich recht. Ich bessere das gleich aus. ;)

Hansa 3. Jul 2005 23:32

Re: Was ist schneller? function oder 3x stringreplace?
 
Zitat:

Zitat von MathiasSimmack
Ich habe nur Delphi 5, Hansa, und bei mir ist Delphi-Referenz durchsuchenStringReplace auch lahm.
Also, wie jetzt? :gruebel:

Nun ? Ja, wie jetzt ? Wer weiß es ? :mrgreen: Mache mal einen Test.

Helmi 7. Jul 2005 09:06

Re: Was ist schneller? function oder 3x stringreplace?
 
Wieso funktioniert denn das?
Delphi-Quellcode:
   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;
Woher weiss er welcher char in der schleife bearbeitet werden soll?

generic 7. Jul 2005 09:15

Re: Was ist schneller? function oder 3x stringreplace?
 
CurrentChar ist ein zeiger auf das aktuelle zeichen.

inc(CurrentChar) setzt den zeiger eine addresse weiter.

Helmi 7. Jul 2005 09:23

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.

Robert_G 7. Jul 2005 10:10

Re: Was ist schneller? function oder 3x stringreplace?
 
Zitat:

Zitat von Helmi
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.

Jupp hatte ich auch schon gesehen.
Zu schnell irgendwas runtergetippt... (Wäre ja auch langweilig wenn geposteter Code einfach so funktioniert... :mrgreen: )

Helmi 24. Jan 2007 20:28

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:
  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);
Wie man sieht, wird dort 10x StringReplace aufgerufen, um jeweils ein Char gegen ein Char aus Hex-Werten zu ersetzen.
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:
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);
Ich vermute mal, dass dieser Code schneller ist als 10x StringReplace.
Was vermutet ihr?

Auch wenn´s etwas OT ist, bringt diese Zeile überhaupt was :?:
Delphi-Quellcode:
  SetLength(S_Text, length(Text));

Matze 24. Jan 2007 20:38

Re: Was ist schneller? function oder 3x stringreplace?
 
Zitat:

Zitat von Helmi
Ich vermute mal, dass dieser Code schneller ist als 10x StringReplace.
Was vermutet ihr?

Lass beides doch einfach 1 Millionen mal aufrufen und miss die Zeit mit GetTickCount, dann weißt du sicher, was schneller ist, ohne hier ewig spekulieren zu müssen. ;) Wobei ich stark annehme, das deine Funktion um einiges schneller sein wird, aber teste es selbst.

MrKnogge 24. Jan 2007 20:38

Re: Was ist schneller? function oder 3x stringreplace?
 
Zitat:

Zitat von Helmi
Ich vermute mal, dass dieser Code schneller ist als 10x StringReplace.
Was vermutet ihr?

Teste es doch einfach :wink:
Zum zeitmessen einfach mal nach GetTickCount suchen.

Gruß

Hawkeye219 24. Jan 2007 21:17

Re: Was ist schneller? function oder 3x stringreplace?
 
Hallo Helmi,

schaue dir einmal die Funktion Translate an.

Gruß Hawkeye

Christian Seehase 24. Jan 2007 21:19

Re: Was ist schneller? function oder 3x stringreplace?
 
Moin Helmi,

zu dem hier

Delphi-Quellcode:
  SetLength(S_Text, length(Text));
  S_Text := '';
fällt mir leider nur ein Wort ein: Sinnbefreit ;-)
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:
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;
Über die Reihenfolge musst Du Dir keine Gedanken machen, dass sortiert der Compiler schon so, dass die Case-Anweisung möglichst schnell durchlaufen wird.

Mit ein wenig mehr Aufwand könnte man das Ganze auch für Ersetzungen umbauen, die nicht 1:1 sind.

Helmi 24. Jan 2007 21:31

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:
S := '';
das SetLength wieder aufhebt, war mir nicht bewusst. Ist aber gut zu wissen.

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

xaromz 24. Jan 2007 21:43

Re: Was ist schneller? function oder 3x stringreplace?
 
Hallo,

wieder einmal muss ich auf meine Funktion StringReplaceMultiple verweisen. Die ist genau für solche Fälle gedacht. Ich weiß zwar nicht, wie die Performance im Vergleich zu Deiner zweiten Funktion ist, aber grundsätzlich ist das schon ziemlich schnell.

Gruß
xaromz

Christian Seehase 24. Jan 2007 22:04

Re: Was ist schneller? function oder 3x stringreplace?
 
Moin Helmi,

ich hätte da auch noch eine variable Lösung anzubieten:

Delphi-Quellcode:
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;
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)


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