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@lists.freepascal.org > http://lists.freepascal.org/mailman/listinfo/fpc-devel > _______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel