AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

StringReplace und doppelte Leerzeichen

Ein Thema von Pichel · begonnen am 10. Apr 2006 · letzter Beitrag vom 12. Apr 2006
Antwort Antwort
Seite 3 von 5     123 45      
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#21

Re: StringReplace und doppelte Leerzeichen

  Alt 10. Apr 2006, 19:42
Wenn du jetzt das @XXX[1] noch durch ein PChar(XXX) ersetzt, dann gewinnst du nochmal Zeit, denn @S[index] bewirkt einen UniqueString()-Aufruf. Und das jedes mal. Result ist aber schon ein neuer String, da er mit SetLength neuen Speicher bekommen hat. Ein UniqueString Aufruf ist also nicht notwendig und kostet nur Zeit.

[quoet="3_of_8"] Ihr streitet euch jetzt nicht ernsthaft um ein paar ms Prozessorzeit, oder? [/quote]
Bis jetzt sehe ich keinen Streit. Nur Optimierungs-Methoden, wie mit "einfachen" Mitteln Geschwindigkeit herausschlagen kann. Die PChar-Varianten sind leider ein No-Go wenn man für .NET programmiert. Dort gelten ganz andere Regeln. So ist es in .NET 1.1 besser, wenn man einen String zuerst in ein array of Char umwandlet und dann darauf zugreift, weil damit einige Checks wegfallen. Das funktioniert aber auch nur für bestimmte String-Längen. Usw...
  Mit Zitat antworten Zitat
Benutzerbild von Pichel
Pichel

Registriert seit: 25. Feb 2005
Ort: Kassel
65 Beiträge
 
Delphi 7 Professional
 
#22

Re: StringReplace und doppelte Leerzeichen

  Alt 10. Apr 2006, 20:15
Zitat von sakura:
Nimm mein, die hat auf meinem PC nur 0,78 Millisekunden benötigt
Stimmt, danke habe sie jetzt getestet : 0.741 Sek... aber habe auch vergessen Euch zu sagen, bei meinen Zeiten habe ich nur den Durchlauf der gesamten Funktion gemessen und Euch verschwiegen das da noch ein wenig mehr mit den 7k Zeichen passiert:
Delphi-Quellcode:
  s := AdjustLineBreaks(sl.Text, tlbsLF);
  s := StringReplace(s, #10, #32, [rfReplaceAll,rfIgnoreCase]);
  s := StringReplace(s, #9, #32, [rfReplaceAll,rfIgnoreCase]);
  Result := removeDblSpaces(s);
Das StringReplace müsste sich ja dann auch noch mit Deiner Funktion weiter optimieren lassen?!?

Btw: also die Hilfe in diesem Forum ist einfach die schnellste und beste, ihr seit genial, Dank an Euch!
Grüße aus Kassel.

Konfuzius sprach: Etwas lernen und sich immer wieder darin üben - schafft das nicht auch Befriedigung?
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#23

Re: StringReplace und doppelte Leerzeichen

  Alt 10. Apr 2006, 20:37
Dann will ich mich auch mal beteiligen:
Delphi-Quellcode:
function RemoveDlbSpaces(const AStr: String): String;
var LCount,
    LDstLen,
    LSpCnt,
    LSrcLen : Integer;
    LDst,
    LSrc : PChar;
begin
  LDstLen := 0;
  LSrcLen := Length(AStr);
  SetLength(result, LSrcLen);
  LSpCnt := 0;
  LSrc := PChar(AStr);
  LDst := PChar(result);
  for LCount := 1 to LSrcLen do
  begin
    if LSrc^ = #32 then
      inc(LSpCnt)
    else
      LSpCnt := 0;
    if (LSpCnt < 2) then
    begin
      LDst^ := LSrc^;
      inc(Cardinal(LDst));
      inc(LDstLen);
    end;
    inc(Cardinal(LSrc));
  end;
  SetLength(result, LDstLen);
end;
Bei meinen Tests hat diese Funktion nur 2/3 der Zeit von DerDan benötigt. Ich hoffe ich hab nicht vergessen irgendwas zu berücksichtigen aber ich denke meine Funktion macht das was die anderen auch machen in einer annehmbaren Zeit.

Vielleicht liegt es aber auch an den verschiedenen Testmethoden. Denn die Methode von jbg war bei mir schneller als die von DerDan (jedoch nicht so schnell wie meine).

Es gäbe auch noch die Variante hier mit einem Var-Parameter zu arbeiten (was ja sinn macht wenn man mit dem abgewandelten String weiterarbeiten will). Dann wäre das ganze sicher noch um einiges schneller.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#24

Re: StringReplace und doppelte Leerzeichen

  Alt 11. Apr 2006, 00:23
Zitat von SirThornberry:
Vielleicht liegt es aber auch an den verschiedenen Testmethoden. Denn die Methode von jbg war bei mir schneller als die von DerDan (jedoch nicht so schnell wie meine).
Es hängt auch von der verwendeten CPU ab, da diese manche Befehle schneller als andere ausführen.

Zitat:
Es gäbe auch noch die Variante hier mit einem Var-Parameter zu arbeiten (was ja sinn macht wenn man mit dem abgewandelten String weiterarbeiten will). Dann wäre das ganze sicher noch um einiges schneller.
Dabei müsste man trotzdem eine Kopie des Strings anfertigen, wenn man nicht mit StringReplace-Methoden arbeiten will (Delete+Insert). Und mit einem Rückgabe-String ist die Funktion etwas mächtiger und man kann sie mit Funktionsaufrufen speißen.
  Mit Zitat antworten Zitat
Benutzerbild von Pichel
Pichel

Registriert seit: 25. Feb 2005
Ort: Kassel
65 Beiträge
 
Delphi 7 Professional
 
#25

Re: StringReplace und doppelte Leerzeichen

  Alt 11. Apr 2006, 06:51
Zitat von SirThornberry:
Dann will ich mich auch mal beteiligen
Bei meinen Tests hat diese Funktion nur 2/3 der Zeit von DerDan benötigt.
Also in meiner App jetzt die Testergebnisse: bisher bei 0.751 und nun 0.741

Ggf. liegt die geringe Verbesserung auch noch an den blöden StringReplace aufrufen in welchen ich ja eh nur einzelne Zeichen ersetzt... werde diesebezüglich noch nen bischen basteln und dann mal weitere messergebnisse posten.
Grüße aus Kassel.

Konfuzius sprach: Etwas lernen und sich immer wieder darin üben - schafft das nicht auch Befriedigung?
  Mit Zitat antworten Zitat
Benutzerbild von Pichel
Pichel

Registriert seit: 25. Feb 2005
Ort: Kassel
65 Beiträge
 
Delphi 7 Professional
 
#26

Re: StringReplace und doppelte Leerzeichen

  Alt 11. Apr 2006, 07:38
Zitat von SirThornberry:
function RemoveDlbSpaces(const AStr: String): String;
Also wie gesagt, ich habe ja immer meine gesamte Funktion (mit dem StringReplace) gemessen und daher die letzte "kleine" Verbesserung.
Da ich ja lediglich zusätzlich noch #9, #13 und #10 ersetzen bzw. löschen will hab ich die Funktion nun entsprechend mal angepasst und nun braucht das ganze nur noch 3,77 ms hingegen vorher 0.751 sek!!!.
Genial, das reicht )) !

Delphi-Quellcode:
function CollapseString(const AStr: String): String;
var LCount,
    LDstLen,
    LSpCnt,
    LSrcLen : Integer;
    LDst,
    LSrc : PChar;
begin
  LDstLen := 0;
  LSrcLen := Length(AStr);
  SetLength(result, LSrcLen);
  LSpCnt := 0;
  LSrc := PChar(AStr);
  LDst := PChar(result);
  for LCount := 1 to LSrcLen do begin
    if (LSrc^ = #10)
    or (LSrc^ = #13)
    or (LSrc^ = #9)
      then LSrc^ := #32;
    if LSrc^ = #32
      then inc(LSpCnt)
      else LSpCnt := 0;
    if (LSpCnt < 2) then begin
      LDst^ := LSrc^;
      inc(Cardinal(LDst));
      inc(LDstLen);
    end;
    inc(Cardinal(LSrc));
  end;
  SetLength(result, LDstLen);
end;
Grüße aus Kassel.

Konfuzius sprach: Etwas lernen und sich immer wieder darin üben - schafft das nicht auch Befriedigung?
  Mit Zitat antworten Zitat
DerDan

Registriert seit: 15. Nov 2004
Ort: Donaueschingen
251 Beiträge
 
Delphi XE3 Professional
 
#27

Re: StringReplace und doppelte Leerzeichen

  Alt 11. Apr 2006, 10:59
Ich hab mal die Tips berücksichtigt und meine Funktion ein wenig zusammengefasst:
ich find ihn noch lesbarer wie meinen Alten.

Tatsächlich gibts wohl Abweichungen im Bereich der 20% alleine durch unterschiedliche CPU, HW und was weis ich.

Schade das niemand eine Assembler Lösung anbietet.


mfg

DerDan



Delphi-Quellcode:
function RemoveDblSpaces3(const InStr: string): string;
var
  Src, Dst: PChar;
begin
  SetLength(Result, Length(InStr));
  Src := Pointer (InStr);
  Dst := Pointer (Result);
  while (Src^ > #0) do
  begin
    while (Src^ <> #0) do
    begin
      Dst^ := Src^;
      inc (Dst);
      if (Src^ = #32) then break;
      inc (Src);
    end;
    while Src^ = #32 do
    begin
      inc (Src);
    end;
  end;
  SetLength(Result, (Integer(Dst) - Integer(@Result[1])));
end;

Code:
Zeit1(   35,40 ms)/Zeit2    81,14% =  -18,86% (SirThornberry)
Zeit2(   43,63 ms)/Zeit2   100,00%             (sakura)
Zeit3(   32,77 ms)/Zeit2    75,12% =  -24,88% (derDan neu)
Zeit4(   36,84 ms)/Zeit2    84,44% =  -15,56% (jbg)
nichts ist so schön wie man es sich vorstellt
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#28

Re: StringReplace und doppelte Leerzeichen

  Alt 11. Apr 2006, 12:46
Das hier ist bei einem AMD 64 noch etwas (8%) schneller:
Delphi-Quellcode:
Function RemoveDblSpaces4(const InStr: string): string;
var
  Src, Dst: PChar;
begin
  SetLength(Result, Length(InStr));
  Src := Pointer (InStr);
  Dst := Pointer (Result);
  while (Src^ > #0) do Begin
    If PWord(Src)^ <> $2020 Then Begin // $2020 = 2 Blanks hintereinander
      Dst^:= Src^;
      inc (Dst);
      End;
    inc (Src);
  end;
  SetLength(Result, (Integer(Dst) - Integer(@Result[1])));
end;
Grob getestet, das Gerüst ist von DerDan.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
DerDan

Registriert seit: 15. Nov 2004
Ort: Donaueschingen
251 Beiträge
 
Delphi XE3 Professional
 
#29

Re: StringReplace und doppelte Leerzeichen

  Alt 11. Apr 2006, 12:59
Zitat von alzaimar:
Das hier ist bei einem AMD 64 noch etwas (8%) schneller:
Auch auf einem Intel, hab dort zwischen 1 bis 5 % bessere Geschwindigkeit


Respekt


DerDan
nichts ist so schön wie man es sich vorstellt
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#30

Re: StringReplace und doppelte Leerzeichen

  Alt 11. Apr 2006, 14:56
Ich hatte in der Mittagspause auch mal ein wenig Lust auf den Thread bekommen...
Ich habe alzaimar Idee aufgegriffen und den Character noch variabel gemacht.
Außerdem mag ich es nicht, wenn man Funktionen abhängig von #0 macht:
Delphi-Quellcode:
function RemoveDblSpaces5(const inputString : String; const character : Char) : String;
var
  currentChar, destinationChar : PChar;
  doubleChar : Word;
  inputEndAddress : Integer;
begin
  doubleChar := (Byte(character) shl 8) + Byte(character);

  SetLength(Result, Length(inputString));

  destinationChar := Pointer(Result);
  currentChar := Pointer(inputString);

  inputEndAddress:= (Length(inputString) * SizeOf(Char)) + Integer(currentChar);

  while Integer(currentChar) < inputEndAddress do
  begin
    destinationChar^ := currentChar^;

    repeat
      Inc(currentChar);
    until PWord(currentChar)^ <> doubleChar;

    Inc(destinationChar);
  end;

  SetLength(Result, (Integer(destinationChar) - Integer(@Result[1])));
end;
Ich habe es gerade mal mit 3 unterschiedlich großen Dateien(1KB, 32KB, 110KB: alles hässliche PL/SQL Skripts ) getestet.
Ich habe es nochmal auf der VM wiederholt, da ich dort eine etwas konstatere Auslastung habe als auf der übervölkerten "richtigen" Maschine.
Output
10000 iterations
File: small.txt
-> RemoveDblSpaces3: 43.49 ms
-> RemoveDblSpaces4: 31.32 ms
-> RemoveDblSpaces5: 22.69 ms
File: medium.txt
-> RemoveDblSpaces3: 2043.64 ms
-> RemoveDblSpaces4: 1581.14 ms
-> RemoveDblSpaces5: 1528.30 ms
File: large.txt
-> RemoveDblSpaces3: 7639.53 ms
-> RemoveDblSpaces4: 5031.43 ms
-> RemoveDblSpaces5: 5115.06 ms

VM Output
10000 iterations
File: small.txt
-> RemoveDblSpaces3: 44,02 ms
-> RemoveDblSpaces4: 22,79 ms
-> RemoveDblSpaces5: 22,49 ms
File: medium.txt
-> RemoveDblSpaces3: 2798,26 ms
-> RemoveDblSpaces4: 2411,56 ms
-> RemoveDblSpaces5: 2697,73 ms
File: large.txt
-> RemoveDblSpaces3: 8291,78 ms
-> RemoveDblSpaces4: 6943,51 ms
-> RemoveDblSpaces5: 6741,50 ms
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 5     123 45      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz