BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CharPosIEx
Goto page 1, 2  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Language BASM
View previous topic :: View next topic  
Author Message
Lars G
Guest





PostPosted: Sat Mar 31, 2007 8:11 am    Post subject: CharPosIEx Reply with quote



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





PostPosted: Sat Mar 31, 2007 6:41 pm    Post subject: Re: CharPosIEx Reply with quote



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





PostPosted: Sat Mar 31, 2007 10:39 pm    Post subject: Re: CharPosIEx Reply with quote



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





PostPosted: Sun Apr 01, 2007 12:32 am    Post subject: Re: CharPosIEx Reply with quote

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





PostPosted: Sun Apr 01, 2007 11:32 am    Post subject: Re: CharPosIEx Reply with quote

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





PostPosted: Sun Apr 01, 2007 11:53 am    Post subject: Re: CharPosIEx Reply with quote

"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





PostPosted: Sun Apr 01, 2007 7:07 pm    Post subject: Re: CharPosIEx Reply with quote

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





PostPosted: Sun Apr 01, 2007 7:59 pm    Post subject: Re: CharPosIEx Reply with quote

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 Wink

No doubt.
Back to top
Bart van der Werf
Guest





PostPosted: Sun Apr 01, 2007 8:41 pm    Post subject: Re: CharPosIEx Reply with quote

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





PostPosted: Sun Apr 01, 2007 8:43 pm    Post subject: Re: CharPosIEx Reply with quote

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 Smile

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





PostPosted: Sun Apr 01, 2007 11:57 pm    Post subject: Re: CharPosIEx Reply with quote

Lars G wrote:

Quote:
Why are you using delphi then ? Delphi is full of code "no interest to
large parts of the world".

I'll use what's available to me. But my point was "why make Delphi routines
that are *even more* limited than the ones already in Delphi?"

--
Anders Isaksson, Sweden
BlockCAD: http://web.telia.com/~u16122508/proglego.htm
Gallery: http://web.telia.com/~u16122508/gallery/index.htm
Back to top
Anders Isaksson
Guest





PostPosted: Mon Apr 02, 2007 12:22 am    Post subject: Re: CharPosIEx Reply with quote

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





PostPosted: Thu Apr 05, 2007 2:48 pm    Post subject: Re: CharPosIEx Reply with quote

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





PostPosted: Thu Apr 05, 2007 2:51 pm    Post subject: Re: CharPosIEx Reply with quote

Hi Anders

So CharPosIEx is "only" supporting AnsiStrings as well as
UpperCase/LowerCase?

Best regards
Dennis Kjaer Christensen
Back to top
Dennis
Guest





PostPosted: Thu Apr 05, 2007 3:50 pm    Post subject: Re: CharPosIEx Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Language BASM All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.