 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Olivier Pons Guest
|
Posted: Mon Nov 21, 2005 6:47 pm Post subject: Optimising help... |
|
|
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
|
Posted: Mon Nov 21, 2005 7:24 pm Post subject: Re: Optimising help... |
|
|
| 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
|
Posted: Mon Nov 21, 2005 7:24 pm Post subject: Re: Optimising help... |
|
|
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
|
Posted: Mon Nov 21, 2005 7:31 pm Post subject: Re: Optimising help... |
|
|
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
|
Posted: Mon Nov 21, 2005 7:34 pm Post subject: Re: Optimising help... |
|
|
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
|
Posted: Mon Nov 21, 2005 8:07 pm Post subject: Re: Optimising help... |
|
|
| 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
|
Posted: Mon Nov 21, 2005 9:04 pm Post subject: Re: Optimising help... |
|
|
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
|
Posted: Thu Nov 24, 2005 1:19 pm Post subject: Re: Optimising help... |
|
|
"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 |
|
 |
|
|
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
|
|