Hallo alle zusammen!
Ich habe mich in letzter Zeit etwas mit WideStrings in Turbo Delphi beschäftigt und dabei festgestellt, dass die Utility-Funktionen für diese verdammt lahm sind.
Als ich der Sache nachgegangen bin ist mir auch schon schnell aufgefallen wieso:
Diese Funktionen rufen teilweise extra Windows-Funktionen auf!
So z.B. bei WideSameText welches intern CompareStringW aus der kernel32.dll aufruft.
Deshalb habe ich mich mal daran gemacht native alternativen für diese Methoden zu schreiben.
Diese erwiesen sich im Test mehr als das 4-fach so schnell sind wie die Originale aus der SysUtils
unit.
Hier der Code:
Delphi-Quellcode:
// FASTER version of WideSameStr
function WideSameStr(
const a,b: WideString): Boolean;
var
ac, bc : PWideChar;
label
ende_false, ende_true;
begin
// If Pointer(a) = Pointer(b) then
// begin
// Result := true;
// exit;
// end;
// If (length(a) <> length(b)) then
// begin
// Result := false;
// exit;
// end;
// If (length(a) = 0) then
// begin
// Result := true;
// exit;
// end;
asm
cmp eax, edx
// a = b
jz ende_true
// --> return true
test eax, eax
// a = nil
jz ende_false
// --> return false
mov ecx, [eax-$04]
test ecx, ecx
// length(a) = 0
jz ende_false
// --> return false
cmp ecx, [edx-$04]
// length(a) <> length(b)
jz ende_true
// --> return false
end;
ende_false:
Result := false;
exit;
ende_true:
ac := @a[1];
bc := @b[1];
repeat
if ac^ <> bc^
then
begin
Result := false;
exit;
end;
inc(ac);
inc(bc);
until ac^ = #0;
Result := true;
end;
// FASTER version of WideSameText
function WideSameText(
const a,b: WideString): Boolean;
var
ac, bc : PWideChar;
label
ende_false, ende_true;
begin
// If Pointer(a) = Pointer(b) then
// begin
// Result := true;
// exit;
// end;
// If (length(a) <> length(b)) then
// begin
// Result := false;
// exit;
// end;
// If (length(a) = 0) then
// begin
// Result := true;
// exit;
// end;
asm
cmp eax, edx
// a = b
jz ende_true
// --> return true
test eax, eax
// a = nil
jz ende_false
// --> return false
mov ecx, [eax-$04]
test ecx, ecx
// length(a) = 0
jz ende_false
// --> return false
cmp ecx, [edx-$04]
// length(a) <> length(b)
jz ende_true
// --> return false
end;
ende_false:
Result := false;
exit;
ende_true:
ac := @a[1];
bc := @b[1];
repeat
if WideUpCase(ac^) <> WideUpCase(bc^)
then
begin
Result := false;
exit;
end;
inc(ac);
inc(bc);
until ac^ = #0;
Result := true;
end;
Mit freundlichen Grüßen
Björn Zeutzheim