home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
NEWS
/
554
/
JUIN
/
UPPER2.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-10-07
|
4KB
|
79 lines
{─ Fido Pascal Conference ────────────────────────────────────────────── PASCAL ─
Msg : 22 of 91
From : Bob Swart 2:281/256.12 11 Jun 93 21:00
To : Sean Palmer 1:104/123.0
Subj : uppercase contest
────────────────────────────────────────────────────────────────────────────────
> Also to Bob Swart
Also to Wilbert ;-)
> Just thought I'd improve what little I can on the uppercase routine so
> far. This should be faster than Bob's inline macro...
I couldn't resist, you here's an InLine macro that's about 10-50% faster than
your routine.
> this changes a compare/jump into a subtract...
It looks a bit like the SBB code Wilbert posted earlier, only your routine
doesn't eliminate the jump if no change is made to the character.
> To Wilbert: clearing the prefetch queue takes less time than an extra
> explicit memory reference each time through the loop.
On what machines have you tested this? On a 386 you seem correct, but I don't
know about a 486 (or Pentium for that matter).
> mov bx,$1961 {'z'-'a', 'a'}{
> :
> sub al,bl
> cmp al,bh
> ja @S;
> sub byte ptr[si-1],32
I used some parts of your routine, unrolled the loop to uppercase two
characters at the same time, start with the first character if the number of
characters in the string is odd, and eliminated some extra jumps and the loop
(although I use a modified loop-like construct, of course). I came up with the
following 52-byte InLine macro, which is the fastest I have seen so far:}
procedure Upper11(var Str: String);
{ 52 Bytes by Bob Swart, 11-6-1993 }
InLine(
$8C/$DA/ { mov DX,DS }
$BB/Ord('a')/
Ord('z')-Ord('a')/ { mov BX,'z'-'a'/'a' }
$5E/ { pop SI }
$1F/ { pop DS }
$FC/ { cld }
$AC/ { lodsb }
$88/$C1/ { mov CL,AL }
$30/$ED/ { xor CH,CH }
$D1/$E9/ { shr CX,1 }
$73/$0B/ { jnc @Part1 }
$AC/ { lodsb }
$28/$D8/ { sub AL,BL }
$38/$F8/ { cmp AL,BH }
$77/$04/ { ja @Part1 }
$80/$6C/$FF/
Ord('a')-Ord('A')/ {@Loop: sub Byte Ptr[SI-1],'a'-'A'}
$E3/$14/ {@Part1:jcxz @Exit }
$AD/ { lodsw }
$28/$D8/ { sub AL,BL }
$38/$F8/ { cmp AL,BH }
$77/$04/ { ja @Part2 }
$80/$6C/$FE/
Ord('a')-Ord('A')/ { sub Byte Ptr[SI-2],'a'-'A'}
$49/ {@Part2:dec CX }
$28/$DC/ { sub AH,BL }
$38/$FC/ { cmp AH,BH }
$77/$EC/ { ja @Part1 }
$EB/$E6/ { jmp @Loop }
$8E/$DA); {@Exit: mov DS,DX }
> inline macros are great and all but they really bloat your code...
Oh well, even when written as a 'genuine' BASM routine it still is faster than
your routine (It is slower when the string has only one character, but faster
on all other cases, relatively gaining speed (compared to your routine) when
the length of the string increases.
But remember:
{$BOLD ON}
There Ain't No Such Thing As The Fastest Code!
{$BOLD OFF}