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 

Optimising help...

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Language BASM
View previous topic :: View next topic  
Author Message
Olivier Pons
Guest





PostPosted: Mon Nov 21, 2005 6:47 pm    Post subject: Optimising help... Reply with quote



Could this be optimized a lot ?

function EncodeTriplet(const Value: AnsiString; Delimiter: AnsiChar;
Specials: TSpecials): AnsiString;
var
n, l: Integer;
s: AnsiString;
c: AnsiChar;
begin
SetLength(Result, Length(Value) * 3);
l := 1;
for n := 1 to Length(Value) do
begin
c := Value[n];
if c in Specials then
begin
Result[l] := Delimiter;
Inc(l);
s := IntToHex(Ord(c), 2);
Result[l] := s[1];
Inc(l);
Result[l] := s[2];
Inc(l);
end
else
begin
Result[l] := c;
Inc(l);
end;
end;
Dec(l);
SetLength(Result, l);
end;


Back to top
Avatar Zondertau
Guest





PostPosted: Mon Nov 21, 2005 7:24 pm    Post subject: Re: Optimising help... Reply with quote



Quote:
Could this be optimized a lot ?

I think you can make it somewhat faster by inlining IntToHex, replacing

Quote:
s := IntToHex(Ord(c), 2);
Result[l] := s[1];
Inc(l);
Result[l] := s[2];
Inc(l);

With:

s := IntToHex(Ord(c), 2);
Result[l] := HEXCHARS[Ord(c) shr 4];
Inc(l);
Result[l] := HEXCHARS[Ord(c) and 15];
Inc(l);

and:

const
HEXCHARS: array[0..15] of Char = ('0', '1', '2', ..., 'D', 'E', 'F');

Using a PChar instead of a string would improve performance since it
would avoid several UniqueString calls.

I assume TSpecials is a set of Char. In this case you should make it
const to avoid copying it (a set of char takes 32 bytes). If you
(nearly) always use the same value it might be better to create a
separate function for that case.

It would probably be slightly better to combine the incs, since when
accessing a string a constant offset must be used anyways (because they
start at 1).

--
The Fastcode Project: http://www.fastcodeproject.org/

Back to top
Pierre le Riche
Guest





PostPosted: Mon Nov 21, 2005 7:24 pm    Post subject: Re: Optimising help... Reply with quote



Hi Olivier,

Quote:
SetLength(Result, Length(Value) * 3);
if c in Specials then
s := IntToHex(Ord(c), 2);
SetLength(Result, l);

Those four lines strike me as the spots where your application will probably
spend the most time. The middle two can be made faster by using lookup
tables. IntToHex is certainly overkill for converting a byte to hexadecimal
text, but if there are very few delimiters then it may be a non-issue. If
you have to rebuild the lookup table for the "c in Specials" frequently then
it won't be worthwhile if "Value" is typically short.

On the other hand, if "Value" is usually very short it might be faster to
determine the exact length for "result" beforehand and then set the length
correctly the first time.

I suggest you use Eric's excellent SamplingProfiler to determine where your
bottleneck lies.

Regards,
Pierre



Back to top
Pierre le Riche
Guest





PostPosted: Mon Nov 21, 2005 7:31 pm    Post subject: Re: Optimising help... Reply with quote

Hi Avatar,

Quote:
Using a PChar instead of a string would improve performance since it
would avoid several UniqueString calls.

Good catch. Doing this should give a very nice speed improvement.

Regards,
Pierre



Back to top
danny heijl
Guest





PostPosted: Mon Nov 21, 2005 7:34 pm    Post subject: Re: Optimising help... Reply with quote

Olivier Pons schreef:

Quote:
Could this be optimized a lot ?

IntToHex can be optimized a lot.

You could write a decent IntToHex routine and declare it as an inline
function if you have D2005, or simply write it inline as for instance
(untested):


function EncodeTriplet(const Value: AnsiString; Delimiter: AnsiChar;
Specials: TSpecials): AnsiString;
const
Hex: array[0..15] of Char = (
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
);
var
n, l: Integer;
s: AnsiString;
c: AnsiChar;
begin
SetLength(Result, Length(Value) * 3);
l := 1;
for n := 1 to Length(Value) do
begin
c := Value[n];
if c in Specials then
begin
Result[l] := Delimiter;
Inc(l);
Result[l] := Hex[((Ord(c) shr 4) and $0F)];
Inc(l);
Result[l] := Hex[Ord(c) and $0F];
Inc(l);
end
else
begin
Result[l] := c;
Inc(l);
end;
end;
Dec(l);
SetLength(Result, l);
end;


Danny
---

Back to top
Avatar Zondertau
Guest





PostPosted: Mon Nov 21, 2005 8:07 pm    Post subject: Re: Optimising help... Reply with quote

Quote:
Result[l] := Hex[((Ord(c) shr 4) and $0F)];

And $0F can be ommited here since Ord(c) in [0..255] so that
(Ord(c) shr 4) in [0..15].

--
The Fastcode Project: http://www.fastcodeproject.org/

Back to top
danny heijl
Guest





PostPosted: Mon Nov 21, 2005 9:04 pm    Post subject: Re: Optimising help... Reply with quote

Avatar Zondertau schreef:

Quote:
And $0F can be ommited here since Ord(c) in [0..255] so that
(Ord(c) shr 4) in [0..15].


You're right, it is a straight translation from C code I've been using
for years.

Danny
---

Back to top
pgx@pgrahams.com
Guest





PostPosted: Thu Nov 24, 2005 1:19 pm    Post subject: Re: Optimising help... Reply with quote

"Avatar Zondertau" <avatarzt (AT) gmail (DOT) com (please reply to newsgroup)>
wrote:

Quote:
HEXCHARS: array[0..15] of Char = ('0', '1', '2', ..., 'D', 'E', 'F');

Don't forget the programer optimization:

HEXCHARS: array[0..15] of Char ='0123456789ABCDEF';

No runtime speedup, but much easier to type!

Phil

Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Language BASM All times are GMT
Page 1 of 1

 
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.