Einzelnen Beitrag anzeigen

Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#16

Re: StringReplace und doppelte Leerzeichen

  Alt 10. Apr 2006, 15:54
SO, bevor ich Dich jetzt auseinander nehme zu meiner Verteidigung. Obige Lösung hatte ich blind in den Browser getippt
Zitat von jbg:
Wobei man deine Funktion auch noch mit ein paar kleineren Änderungen schneller machen kann.
Das war mir klar, daher habe ich mal Deine Aussage alle einzeln getestet. Es zeigt sich, dass man nie immer sagen sollte.
Zitat von jbg:
Das fängt z.B. schon mal damit an, dass man sich das InStr[I] in eine lokale Char Variable zwischen speichern kann (die dann vom Compiler in ein Register geschoben wird).
Der Gewinn lag hier bei unter 0,1%, hätte ich mehr erwartet.
Zitat von jbg:
Des weiteren ist es schneller, wenn man InStr[I + 1] schreibt, und I von 0 bis Length-1 laufen lässt
Macht gar keinen Unterschied. Einfacher Grund, intern wird immer noch rückwärts gezählt und eine zweite Variable für meine Aufrufe genutzt
Zitat von jbg:
(am besten auch noch rückwärts, die die Verarbeitungsreihenfolge in diesem Code sowieso irrelevant ist, weil sowieso keine MultiByteChars beachtet werden [das ist jetzt keine Kritik]).
Dazu war ich jetzt zu faul, auch habe ich keine schnelle Lösung dafür gefunden...
Zitat von jbg:
Außerdem wird die Prüfung auf InStr[I] = #32 zuweimal durchgeführt, also einmal zu viel.
Hier wirst Du überrascht sein, eine einmalige Prüfung und das Speichern in einer weiteren Variable (gleiche kann ja nicht genutzt werden, da der alte Wert noch wichtig wird), verbraucht ca. 7% mehr Rechenzeit. Also besser wie es jetzt ist
Zitat von jbg:
Das Res[Cnt]:=InStr[I] ist auch nicht unbedingt das schnellste,
Stimmt, in der neuen Lösung auf Pointer gewechselt
Zitat von jbg:
Die Hilfsvariable Res ist eigentlich auch nicht notwendig, da man gleich mit Result arbeiten kann und sich somit am Ende den LStrAsg() Aufruf (=Zuweisung) sparen kann.
Dadurch wird allerdings das EAX Register blockiert, welches evtl. durch den Compiler anders für Optimierungen genutzt werden könnte. Es macht hier keinen Unterschied, ist i.A. aber nicht zu empfehlen. Result sollte nach Möglichkeit immer erst am Ende direkt angesprochen werden.
Zitat von jbg:
Man sieht, dass man noch einiges herausholen kann, ohne gleich auf Hand-optimierten Assembler zurückgreifen zu müssen.
Oh Gott, dazu fehlt mir jetzt die Zeit. Aber das Rumspielen war schon einmal interessant, und hat noch einmal ca. 60% Performancegewinn gebracht. Aber das reicht mir jetzt, wer will, der darf weiter machen
Delphi-Quellcode:
function RemoveDblSpaces2(const InStr: string): string;
var
  LastIsSpace, IsSpace: Boolean;
  I: Integer;
  Src, Dst: PChar;
  Res: string;
begin
  SetLength(Res, Length(InStr));
  LastIsSpace := False;
  Src := @InStr[1];
  Dec(Src);
  Dst := @Res[1];
  Dec(Dst);
  for I := 0 to Length(InStr) - 1 do
  begin
    Inc(Src);
    IsSpace := Src^ = #32;
    if LastIsSpace and IsSpace then
      Continue;
    LastIsSpace := IsSpace;
    Inc(Dst);
    Dst^ := Src^;
  end;
  SetLength(Res, (Integer(Dst) - Integer(@Res[1])));
  Result := Res;
end;
......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat