Mal ein paar (unsinnige?) Gedankenspiele:
Ab ins alte Turbopascal, dort enthielt bei Strings das 0. Byte die Länge.
Das dürfte heute bei ShortString noch so sein. Geht ShortString auch? Wenn ja:
Delphi-Quellcode:
var sBaseStr : ShortString;
lBaseStr : Byte absolut sBaseStr;
Damit befindet sich die Längenangabe von sBaseStr automatisch in lBaseStr. Die wiederholte Längenabfrage per Length kann damit entfallen.
Alternativ die Länge nur einmalig abfragen und in Variabeln speichern. Alles entfernen, was wiederholt gemacht werden muss. Lieber ein paar zusätzliche Variabeln "mitschleppen".
Delphi-Quellcode:
function MatchRule(const BaseStr: String; const CompareList: TStringList): Boolean;
var
i : Integer;
j : Integer;
cntForward : Integer;
cntBackward : Integer;
lBase : Integer;
lComp : Integer;
StrBase : String;
lStrBase : Integer; // Länge von StrBase
StrCompare : String;
lStrCompare : Integer; // Länge von StrCompare
lStrBaseStrCompare : Integer; // Differenz: lStrCompare - lStrBase
begin
Result := False;
bBreak := False;
lBase := Length(BaseStr);
for i := 0 to CompareList.Count - 1 do begin
lComp := Length(CompareList[i]);
if InRange(lBase - lComp,-1,1) then begin
cntForward := 0;
cntBackward := 0;
if lBase <= lComp then begin
StrBase := BaseStr;
StrCompare := CompareList[i];
end else begin
StrBase := CompareList[i];
StrCompare := BaseStr;
end;
// compare contains base
lStrBase := Length(StrBase);
lStrCompare := Length(StrCompare);
if lStrBase < lStrCompare then Result:= Pos(StrBase, StrCompare) > 0;
if not Result then begin
// check forward
for j := 1 to lStrBase - 1 do begin // Warum kein Vergleich beim letzten Zeichen?
if StrBase[j] = StrCompare[j] then inc(cntForward)
else break; // Beim ersten Unterschied raus aus For...
end;
// check backward
lStrBaseStrCompare := lStrCompare - lStrBase;
for j := lStrBase downto 1 do begin
if StrBase[j] = StrCompare[j + lStrBaseStrCompare] then
inc(cntBackward)
else break; // Beim ersten Unterschied raus aus For...
end;
if lBase = lComp then
// bei gleicher Länge darf es einen Unterschied geben.
Result := (cntForward + cntBackward) >= (lStrBase - 1)
else
Result := (cntForward + cntBackward) = lStrBase;
end;
if Result then Exit; // hier raus, wenn Result = True;
end;
// else Continue; // überflüssig, da wir hier ja sowieso am Ende der Schleife sind.
end;
end;
Ob das jetzt große Geschwindigkeitsunterschiede gibt, mag ich nicht zu beurteilen.
Meine praktische Erfahrung ist jedoch, dass bei häufig wiederholten Routinen durchaus Geschwindigkeitsvorteile zu erwarten sind, wenn man wiederholt per Pos, Length... ermittelte Werte in separaten Variablen "mitschleppt", um die wiederholte Ausführung, eigentlich trivialer Funktionen, zu eliminieren.