[fpc-devel] Patch to speed up Uppercase/Lowercase functions
David Butler
david at e.co.za
Sat Jun 11 18:07:53 CEST 2005
On Sat, 11 Jun 2005 13:33:57 +0200 (CEST), you wrote:
>To compare, I made 6 versions of Lowercase:
>Result on an AMD 64 3000:
>Lowercase time to execute: 00:00:01.563
>Lowercase2 Time to execute: 00:00:01.363
>Lowercase3 Time to execute: 00:00:01.394
>Lowercase4 Time to execute: 00:00:00.999
>Lowercase5 Time to execute: 00:00:01.021
>Lowercase6 Time to execute: 00:00:00.948
>
>So, judge for yourself. I think this is worth the 256 byte lookup table.
One of the major optimisations for the LowerCase function is actually
for the case when the function does nothing!
The most expensive operation in the whole LowerCase function is the
UniqueString allocation for when the string changes. For the case
where the string is already in lower case it is important not call
UniqueString. It makes a 600% difference is speed on Delphi for my
test case (haven't tested on fpc yet).
This is why it is important to have this line in Lowercase2 for
example:
if (result[i] in ['A'..'Z']) then
It prevents the UniqueString call if nothing changes.
Just for comparison, here is the implementation in Fundamentals. The
pure pascal version is like your lowercase2.
{$IFDEF USE_ASM386}
procedure ConvertLower(var S: AnsiString);
asm
OR EAX, EAX
JZ @Exit
PUSH EAX
MOV EAX, [EAX]
OR EAX, EAX
JZ @ExitP
MOV ECX, [EAX - 4]
OR ECX, ECX
JZ @ExitP
XOR DH, DH
@L2:
DEC ECX
MOV DL, [EAX + ECX]
CMP DL, 'A'
JB @L1
CMP DL, 'Z'
JA @L1
OR DH, DH
JZ @Uniq
@L3:
ADD DL, 'a' - 'A'
MOV [EAX + ECX], DL
@L1:
OR ECX, ECX
JNZ @L2
OR DH, DH
JNZ @Exit
@ExitP:
POP EAX
@Exit:
RET
@Uniq:
POP EAX
PUSH ECX
PUSH EDX
CALL UniqueString
POP EDX
POP ECX
MOV DH, 1
JMP @L3
end;
{$ELSE}
procedure ConvertLower(var S: AnsiString);
var F : Integer;
begin
For F := 1 to Length(S) do
if S[F] in ['A'..'Z'] then
S[F] := AnsiChar(Ord(S[F]) + 32);
end;
{$ENDIF}
Regards
David
More information about the fpc-devel
mailing list