[fpc-devel] Patch to speed up Uppercase/Lowercase functions
Michael Van Canneyt
michael at freepascal.org
Sat Jun 11 18:36:44 CEST 2005
On Sat, 11 Jun 2005, David Butler wrote:
> 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.
That is why I use pchar and one uniquestring;
It prevents all these automated uniquestring calls.
>
> Just for comparison, here is the implementation in Fundamentals. The
> pure pascal version is like your lowercase2.
It's quite different; the use of a var changes it a lot;
An in-place replacement routine is of course faster...
Michael.
>
> {$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
>
>
>
> _______________________________________________
> fpc-devel maillist - fpc-devel at lists.freepascal.org
> http://lists.freepascal.org/mailman/listinfo/fpc-devel
>
More information about the fpc-devel
mailing list