 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Lars G Guest
|
Posted: Sat Mar 31, 2007 8:11 am Post subject: CharPosIEx |
|
|
Hi
I have updated my winner function in Pascal Size Penalty
CharPosIEx_LBG_Pas_12
The function size is shrinked from 99 to 85 bytes.
And the speed on a AMD64
CharPosIEx_LBG_Pas_17_a 4 772 702 1474
CharPosIEx_LBG_Pas_12_a C 940 826 1766
I hope it is fast on the other cpu also.
Lars G
(*
Author: Lars Bloch Gravengaard
Date: 31/03 2007
Instructionset(s): PAS
Function size 85 bytes
*)
function CharPosIEx_LBG_Pas_17_a(SearchChar : Char; const S: string; Offset:
Integer = 1) : Integer;
var
SearchChar_R, SearchChar_ : Char;
StrLength : Integer;
begin
Result := Offset;
if (Result > 0) then
begin
StrLength := Length(S);
if (SearchChar >= 'a') and (SearchChar <= 'z') then
SearchChar_R := char(Ord(SearchChar) - 32)
else
if (SearchChar >= 'A') and (SearchChar <= 'Z') then
SearchChar_R := char(Ord(SearchChar) + 32)
else
SearchChar_R := char(Ord(SearchChar) + 0);
SearchChar_ := SearchChar;
while Result <= StrLength do
begin
if S[Result] = SearchChar_ then exit;
if S[Result] = SearchChar_R then exit;
Inc(Result);
end;
end;
Result := 0;
end; |
|
| Back to top |
|
 |
Bob Gonder Guest
|
Posted: Sat Mar 31, 2007 6:41 pm Post subject: Re: CharPosIEx |
|
|
Lars G wrote:
Hi Lars. I hope I can make a suggestion or two?
I don't do Pascal, so maybe my code is slower, and not written
properly, but this code screams at me, and I feel compelled to
comment.
I hope you will consder/try these ideas and submit any that turn out
to be helpful. (I also hope I'm not spoiling your fun.)
OTOH, this is version 17, so maybe you've already explored these...
| Quote: | begin
StrLength := Length(S);
if (SearchChar >= 'a') and (SearchChar <= 'z') then
SearchChar_R := char(Ord(SearchChar) - 32)
else
if (SearchChar >= 'A') and (SearchChar <= 'Z') then
SearchChar_R := char(Ord(SearchChar) + 32)
else
SearchChar_R := char(Ord(SearchChar) + 0);
|
Is there a reason to convert the char and add 0 ?
| Quote: | SearchChar_ := SearchChar;
|
Is there a reason to copy the original char?
This should be shorter, and maybe faster.
OTOH, you might look at the ToUpper challenge for the fastest.
SearchChar_R := char(Ord(SearchChar) AND $DF)
if (SearchCharR >= 'A') and (SearchCharR <= 'Z') then
SearchChar_R := char(Ord(SearchChar) XOR $20)
else
SearchChar_R := SearchChar
while......
| Quote: | while Result <= StrLength do
begin
if S[Result] = SearchChar_ then exit;
if S[Result] = SearchChar_R then exit;
|
Extra compare if non-letter (slower than needed)
Trading extra size for speed bump on non-alpha searches, you could
have 2 copies of the "while" embeded within the above "if".
Also, the "while" is pretty small. There might be some gain in
unrolling the loop: comparing 2, 3 or 4 S[ ] per loop.
| Quote: | Inc(Result);
end;
end;
Result := 0;
end;
|
SearchChar_R := char(Ord(SearchChar) AND $DF)
if (SearchCharR >= 'A') and (SearchCharR <= 'Z') then
begin
SearchChar_R := char(Ord(SearchChar) XOR $20)
| Quote: | > while Result <= StrLength do
> begin
> if S[Result] = SearchChar then exit;
> if S[Result] = SearchChar_R then exit;
> Inc(Result);
> end;
> end;
end |
else
begin
| Quote: | > while Result <= StrLength do
> begin
> if S[Result] = SearchChar then exit;
> Inc(Result);
> end;
> end;
end
Result := 0;
end; |
|
|
| Back to top |
|
 |
Dennis Guest
|
Posted: Sat Mar 31, 2007 10:39 pm Post subject: Re: CharPosIEx |
|
|
Hi Bob
What about making your own functions and participate in the challenge? It is
fun ;-)
Best regards
Dennis Kjaer Christensen |
|
| Back to top |
|
 |
Anders Isaksson Guest
|
Posted: Sun Apr 01, 2007 12:32 am Post subject: Re: CharPosIEx |
|
|
Lars G wrote:
| Quote: | if (SearchChar >= 'a') and (SearchChar <= 'z') then
SearchChar_R := char(Ord(SearchChar) - 32)
else
if (SearchChar >= 'A') and (SearchChar <= 'Z') then
SearchChar_R := char(Ord(SearchChar) + 32)
|
Is this really a recommended way to switch between upper and lower case? It
relies on the character coding, it doesn't work for anything else than 'A'
to 'Z' (in the to me known codings), and is not used by the AnsiString
functions in the RTL, as far as I can see.
AnsiStrings contains AnsiChars which are 8 bits wide and certainly not
restricted to 7 bit US-ASCII. The above method for case conversion was old
and wrong already in DOS, and should be left in the 7 bit US-ASCII museum!
Why spend time creating a 'super fast' CharPosIEx which is of no interest to
large parts of the world? Isn't it better to create 'fast enough' versions
of *generally* usable functions?
--
Anders Isaksson, Sweden
BlockCAD: http://web.telia.com/~u16122508/proglego.htm
Gallery: http://web.telia.com/~u16122508/gallery/index.htm |
|
| Back to top |
|
 |
Lars G Guest
|
Posted: Sun Apr 01, 2007 11:32 am Post subject: Re: CharPosIEx |
|
|
Hi
"Bob Gonder" <notbg (AT) notmindspring (DOT) invalid> skrev i en meddelelse
news:otjs03pogr24ud76vdr5k59ovej61ljll9 (AT) 4ax (DOT) com...
| Quote: | Lars G wrote:
Hi Lars. I hope I can make a suggestion or two?
|
Yes
| Quote: | I don't do Pascal, so maybe my code is slower, and not written
properly, but this code screams at me, and I feel compelled to
comment.
I hope you will consder/try these ideas and submit any that turn out
to be helpful.
I will comment later |
| Quote: | (I also hope I'm not spoiling your fun.)
|
No you not
| Quote: | OTOH, this is version 17, so maybe you've already explored these...
begin
StrLength := Length(S);
if (SearchChar >= 'a') and (SearchChar <= 'z') then
SearchChar_R := char(Ord(SearchChar) - 32)
else
if (SearchChar >= 'A') and (SearchChar <= 'Z') then
SearchChar_R := char(Ord(SearchChar) + 32)
else
SearchChar_R := char(Ord(SearchChar) + 0);
Is there a reason to convert the char and add 0 ?
|
It was faster in one of the other version.
It is the same size but it is a very small differens in speed 1474 to 1472
So this I will Change in the next version.
| Quote: |
SearchChar_ := SearchChar;
Is there a reason to copy the original char?
|
It is faster that way.
I think it somehow help the delphi code optimizer.
| Quote: | This should be shorter, and maybe faster.
OTOH, you might look at the ToUpper challenge for the fastest.
SearchChar_R := char(Ord(SearchChar) AND $DF)
if (SearchCharR >= 'A') and (SearchCharR <= 'Z') then
SearchChar_R := char(Ord(SearchChar) XOR $20)
|
Do this work ?
| Quote: | Extra compare if non-letter (slower than needed)
|
'Modern' CPU's can do more than one thing at the time.
| Quote: | Trading extra size for speed bump on non-alpha searches, you could
have 2 copies of the "while" embeded within the above "if".
Also, the "while" is pretty small. There might be some gain in
unrolling the loop: comparing 2, 3 or 4 S[ ] per loop.
|
And I think it is slower (bigger code)
But why not make you own function ? Mayby you's are faster :-)
Lars |
|
| Back to top |
|
 |
Lars G Guest
|
Posted: Sun Apr 01, 2007 11:53 am Post subject: Re: CharPosIEx |
|
|
"Anders Isaksson" <blockcad (AT) REMOVEgmail (DOT) com> skrev i en meddelelse
news:460eb753 (AT) newsgroups (DOT) borland.com...
| Quote: |
Why spend time creating a 'super fast' CharPosIEx which is of no interest
to large parts of the world? Isn't it better to create 'fast enough'
versions of *generally* usable functions?
|
Why are you using delphi then ? Delphi is full of code "no interest to
large parts of the world".
Then will there be decent unicode suport in delphi ?
Lars |
|
| Back to top |
|
 |
Dennis Guest
|
Posted: Sun Apr 01, 2007 7:07 pm Post subject: Re: CharPosIEx |
|
|
Hi Anders
I think you are mistaken with regard to the functionality of CharPosIEx.
What do others think?
| Quote: | Is this really a recommended way to switch between upper and lower case?
It
relies on the character coding, it doesn't work for anything else than 'A'
to 'Z' (in the to me known codings), and is not used by the AnsiString
functions in the RTL, as far as I can see.
|
What about UpperCase/LowerCase?
Look at my first function. It works with both InitializeLookUpTable
functions.
procedure InitializeLookUpTable;
var
I : Byte;
S1, S2 : AnsiString;
begin
SetLength(LookUpTable, 256);
for I := 0 to 255 do
begin
S1 := Char(I);
S2 := UpperCase(S1);
LookUpTable[I] := S2[1];
end;
end;
procedure InitializeLookUpTable2;
var
I : Byte;
begin
for I := 0 to 255 do
begin
if (Char(I) >= 'a') and (Char(I) <= 'z') then
LookUpTable2[I] := Char(I - 32)
else
LookUpTable2[I] := Char(I);
end;
end;
//Author: Dennis Kjaer Christensen
//Date: 12/12 2005
//Instructionset(s): IA32
function CharPosIEx_DKC_Pas_10_a(SearchChar : Char; const S: string; Offset:
Integer = 1) : Integer;
var
StrLength : Integer;
SearchCharUpper, CharUpper : Char;
begin
Result := 0;
if (Offset <= 0) then
Exit;
if S = '' then
Exit;
StrLength := PInteger(Integer(S)-4)^;
if StrLength <= 0 then
Exit;
if Offset > StrLength then
Exit;
SearchCharUpper := LookUpTable[Ord(SearchChar)];
Result := Offset;
repeat
CharUpper := LookUpTable[Ord(S[Result])];
if SearchCharUpper = CharUpper then
Exit;
Inc(Result);
until (Result > StrLength);
Result := 0;
end;
| Quote: | AnsiStrings contains AnsiChars which are 8 bits wide and certainly not
restricted to 7 bit US-ASCII. The above method for case conversion was old
and wrong already in DOS, and should be left in the 7 bit US-ASCII museum!
|
I think we are correctly supporting AnsiStrings.
| Quote: | Why spend time creating a 'super fast' CharPosIEx which is of no interest
to
large parts of the world? Isn't it better to create 'fast enough' versions
of *generally* usable functions?
|
We are trying to fastest possible versions of *generally* usable functions?
This is the optimum solution. "Fast enough" is not compatible with Fastcode.
Regards
Dennis |
|
| Back to top |
|
 |
Bob Gonder Guest
|
Posted: Sun Apr 01, 2007 7:59 pm Post subject: Re: CharPosIEx |
|
|
Dennis wrote:
| Quote: | What about making your own functions and participate in the challenge?
|
Maybe you didn't see the part where I said I don't do Pascal ?
| Quote: | It is fun
|
No doubt. |
|
| Back to top |
|
 |
Bart van der Werf Guest
|
Posted: Sun Apr 01, 2007 8:41 pm Post subject: Re: CharPosIEx |
|
|
| Quote: | AnsiStrings contains AnsiChars which are 8 bits wide and certainly not
restricted to 7 bit US-ASCII. The above method for case conversion was
old
and wrong already in DOS, and should be left in the 7 bit US-ASCII
museum!
I think we are correctly supporting AnsiStrings.
|
You might want to try a MBCS codepage and think again.
under a mbcs codepage (and under utf8vcl) an AnsiString acutally can contain
multibyte characters. usually a leadbyte followed by one or more tailbytes. |
|
| Back to top |
|
 |
Bob Gonder Guest
|
Posted: Sun Apr 01, 2007 8:43 pm Post subject: Re: CharPosIEx |
|
|
Lars G wrote:
| Quote: | "Bob Gonder" skrev i en meddelelse
Is there a reason to convert the char and add 0 ?
It was faster in one of the other version.
|
Counterintuitive. Figured it might have accidentally-on-purpose
aligned the while loop properly.
| Quote: | This should be shorter, and maybe faster.
Do this work ?
|
I don't know the "proper" Pascal bit-wise AND and XOR commands, but
yes,
| Quote: | SearchChar_R := char(Ord(SearchChar) AND $DF)
Turning off bit $20 converts alpha to uppercase. |
Non-alphas become other non-alphas.
| Quote: | if (SearchCharR >= 'A') and (SearchCharR <= 'Z') then
SearchChar_R := char(Ord(SearchChar) XOR $20)
If alpha, switching bit $20 swaps case. |
But then neither this code nor yours converts non-ASCII letters.
| Quote: | Extra compare if non-letter (slower than needed)
Trading extra size for speed bump on non-alpha searches, you could
have 2 copies of the "while" embeded within the above "if".
'Modern' CPU's can do more than one thing at the time.
|
But I don't think they do compares at the same time.
| Quote: | Also, the "while" is pretty small. There might be some gain in
unrolling the loop: comparing 2, 3 or 4 S[ ] per loop.
And I think it is slower (bigger code)
|
Bigger yes (not much though). Slower...maybe not.
Bigger is not always slower.
| Quote: | But why not make you own function ? Mayby you's are faster
|
I don't have Delphi or Pascal, nor do I know the language.
Asm and C are my forte, and thinking hard on dipping into C++.
There isn't enough lifeforce left in me for Pascal. |
|
| Back to top |
|
 |
Anders Isaksson Guest
|
|
| Back to top |
|
 |
Anders Isaksson Guest
|
Posted: Mon Apr 02, 2007 12:22 am Post subject: Re: CharPosIEx |
|
|
Dennis wrote:
| Quote: | What about UpperCase/LowerCase?
|
That code you've shown has the flaw that it will not even try to convert
characters with a code > 'z'. Ergo, your code is for 7 bit US-ASCII. Even if
it had taken care of that it would not work, as adding/subtracting 32 isn't
going to make åäö into ÅÄÖ (that's small a-ring, a-umlaut, o-umlaut to
capital versions of the same) and vice versa, and these are characters
available in an AnsiString (among many others). Using a lookup table will
work, IFF you produce the lookup table with the help of the Windows API (not
UpperCase which is 'A'-'z' only), AND react to any change in locale that may
happen while the program is running. Initializing the table once at startup
will not be enough for that.
As we are talking about Ansi-strings, I would expect the functions to work
on such strings...
| Quote: | I think we are correctly supporting AnsiStrings.
|
If so, why is there one UpperCase() and one AnsiUpperCase() in the Delphi
RTL? UpperCase works on 7 bit US-ASCII, AnsiUppercase uses Windows to cater
for the current locale.
| Quote: | We are trying to fastest possible versions of *generally* usable
functions?
|
The CharPosIEx's as shown are not generally usable - they are limited to the
7 bit US-ASCII charset. AnsiStrings aren't.
--
Anders Isaksson, Sweden
BlockCAD: http://web.telia.com/~u16122508/proglego.htm
Gallery: http://web.telia.com/~u16122508/gallery/index.htm |
|
| Back to top |
|
 |
Dennis Guest
|
Posted: Thu Apr 05, 2007 2:48 pm Post subject: Re: CharPosIEx |
|
|
Hi Bob
| Quote: | Maybe you didn't see the part where I said I don't do Pascal ?
|
I missed that.
Best regards
Dennis Kjaer Christensen |
|
| Back to top |
|
 |
Dennis Guest
|
Posted: Thu Apr 05, 2007 2:51 pm Post subject: Re: CharPosIEx |
|
|
Hi Anders
So CharPosIEx is "only" supporting AnsiStrings as well as
UpperCase/LowerCase?
Best regards
Dennis Kjaer Christensen |
|
| Back to top |
|
 |
Dennis Guest
|
Posted: Thu Apr 05, 2007 3:50 pm Post subject: Re: CharPosIEx |
|
|
Hi Anders
You are in reality asking us to make AnsiUpperCase, AnsiLowerCase and
AnsiCharPosIEx challenges?
This is fine and we can put them on our list of coming challenges.
Best regards
Dennis Kjaer Christensen |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|