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

...