Hallo Hagen,
im Vordergrund stand bei meiner Antwort die Übersichtlichkeit des Quellcodes
Zitat:
Es wird so nicht nur etwas übersichtlicher, sondern ggf auch etwas schneller
ich wollte somit keinesfalls "die performanteste Lösung" aufzeigen, sondern einen brauchbaren Kompromiss.
Zitat von
negaH:
Da du Result als Zählervariable benutzt verhinderst du das der Compiler den Code besser optimieren kann
Das stimmt und dient der Übersichtlichkeit. Es ist wahr, dass auch die Speicherung von Zwischenwerten in
Result als umstritten gilt, ich persönlich finde jedoch ein Kontrukt der Art
Delphi-Quellcode:
function MyProc: Integer;
begin
Result:= 0;
while SomeCriteria do
Inc(Result);
end;
übersichtlicher als
Delphi-Quellcode:
function MyProc: Integer;
var
myExtension: Integer;
begin
myExtension:= 0;
while SomeCriteria do
Inc(myExtension);
Result:= myExtension;
end;
Zitat von
negaH:
der Compiler [..] würde [..] schnelleren Code mit einer simplen for to Schleife erzeugen.
Das stimmt, auch hier wirkt eine Lösung mit
Exit oder
Break eher als Kunstgriff und dient als Hauptzweck der Performancesteigerung. Ich möchte keine Diskussion über Ästhetik anzetteln, aber nach der Klassischen Auffassung sollten For-Schleifen genau dann eingesetzt werden, wenn die Anzahl der Iterationen bekannt ist, was hier nicht der Fall ist.
Break und
Exit eignen sich häufig in komplexeren Fällen, um Kontrollstrukturen zu verlassen, die Abbruchbedingung dieser Schleife hingegen lässt sich "sauber" definieren, so dass die Veränderung der Ablaufsteuerung ausschließlich der Performancesteigerung dient.
Tatsächlich ist die For-Schleife nicht nur bei der Abbruchbedingung genauso performant wie die TopDown lösung, sich arbeitet sogar direkt mit einem Index im array, so dass die Errechnung selbigens bei der While-Schleife entfält.
Code:
[b]DoSthWithStr(AnArray[myIndex])[/b]
mov EAX, [EBX]
call DoSthWithStr
add EBX, $04
innerhalb der For-Schleife und dagegen die errechnung des Indexes innerhalb der Whileschleife:
Code:
[b]DoSthWithStr(AnArray[myIndex])[/b]
mov EAX, [EBP-$04]
mov EAX, [EAX+EBX*4]
call DoSthWithStr
inc EBX
Zitat von
negaH:
Eine BottomUp Schleife ist Cache-unfreundlich
Ich simmte Dir iA zu, allerdings arbeiten wir hier mit Strings, die idR wahllos auf dem Heap platziert sind, so dass bei der Verarbeitung der Strings ohnehin ungeordnet Speicherzugriffe stattfinden. Lediglich die Referenzen nicht aber der im Verhätnis zu ihnen große Speicherbereich zur tatsächlichen Verarbeitung (vergleichen, verlängern, kürzen, etc) könnte somit cache-freundlich Bearbeitet werden.
Für performancekritische Lösungen des ursprünglichen Problems von Steffen würde ich ebenfalls eine Lösung der von Dir vorgeschlagenen Art verwenden, jedoch mit einem besseren Match-Algorithmus als der in
Pos implementierte, bspw einer modifizierte Version des Boyer-Moore-Algorithmus oder einer Form des Hashings...