 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Adem Guest
|
Posted: Mon Nov 14, 2005 6:37 am Post subject: Hidden cost of this? |
|
|
Hi,
I am thinking of using a structure such as below to
facilitate conversion from one basic type to other(s).
TGenericConverter = packed record
case Byte of
0: (
LongWord0: LongWord;
);
1: (
Integer0: Integer;
Integer1: Integer;
);
2: (
Word0: Word;
Word1: Word;
Word2: Word;
Word3: Word;
);
3: (
Byte0: Byte;
Byte1: Byte;
Byte2: Byte;
Byte3: Byte;
Byte4: Byte;
Byte5: Byte;
Byte6: Byte;
Byte7: Byte;
);
4: (
Integers: array[0..1] of Integer;
);
5: (
Words: array[0..3] of Word;
);
6: (
Bytes: array[0..7] of Byte;
);
end;
The attractive part is, as long as my data is 8-bytes max,
I seem to be able to access its various segments easily. i.e.
<snippet>
var
Value1: TGenericConverter;
begin
Value1.LongWord0 := 12345678;
if Value1.Byte4 then begin
{so something here}
end;
if Value1.Word1 then begin
{so something here}
end;
end;
</snippet>
Looks attractive.
Yet, the fact that I haven't seen much use of this sort of thing
makes me suspect that there may be more than meets the eye (or, I).
What are the pros and cons.
I'd appreciate your views.
Cheers,
Adem
|
|
| Back to top |
|
 |
Hrvoje Brozovic Guest
|
Posted: Mon Nov 14, 2005 7:47 am Post subject: Re: Hidden cost of this? |
|
|
Adem wrote:
| Quote: | Hi,
I am thinking of using a structure such as below to
facilitate conversion from one basic type to other(s).
TGenericConverter = packed record
case Byte of
Looks attractive.
Yet, the fact that I haven't seen much use of this sort of thing
makes me suspect that there may be more than meets the eye (or, I).
|
It seems that you haven't seen much of
low level socket preparation code.
This construct was also used for processor clock
reading (RDTSC) implementation in old Delphi versions.
|
|
| Back to top |
|
 |
Adem Guest
|
Posted: Mon Nov 14, 2005 9:48 am Post subject: Re: Hidden cost of this? |
|
|
Hrvoje Brozovic wrote:
| Quote: | Yet, the fact that I haven't seen much use of this sort of thing
makes me suspect that there may be more than meets the eye (or, I).
It seems that you haven't seen much of low level socket
preparation code.
|
You're right. I don't think I have looked at that code.
| Quote: | This construct was also used for processor clock
reading (RDTSC) implementation in old Delphi versions.
|
Does that mean good :-)
If so, any idea why it isn't more widely used?
Cheers,
Adem
|
|
| Back to top |
|
 |
Adem Guest
|
Posted: Mon Nov 14, 2005 11:58 am Post subject: Re: Hidden cost of this? |
|
|
Lee_Nover wrote:
| Quote: | If so, any idea why it isn't more widely used?
I use it where applicable
most probably haven't thought about it
|
Me the same :-)
Except now.
| Quote: | it's also an elegant way which most coders don't like
.. as in simple stuff is not leet, complicate it to be
a true hax0r
|
:-)
|
|
| Back to top |
|
 |
Primoz Gabrijelcic Guest
|
Posted: Mon Nov 14, 2005 12:17 pm Post subject: Re: Hidden cost of this? |
|
|
FYI, Sysutils.pas defines:
WordRec = packed record
case Integer of
0: (Lo, Hi: Byte);
1: (Bytes: array [0..1] of Byte);
end;
LongRec = packed record
case Integer of
0: (Lo, Hi: Word);
1: (Words: array [0..1] of Word);
2: (Bytes: array [0..3] of Byte);
end;
Int64Rec = packed record
case Integer of
0: (Lo, Hi: Cardinal);
1: (Cardinals: array [0..1] of Cardinal);
2: (Words: array [0..3] of Word);
3: (Bytes: array [0..7] of Byte);
end;
And that's been with us for a looooong time...
Read the source, Luke!
--Primoz
|
|
| Back to top |
|
 |
Lee_Nover Guest
|
Posted: Mon Nov 14, 2005 12:30 pm Post subject: Re: Hidden cost of this? |
|
|
| Quote: | If so, any idea why it isn't more widely used?
I use it where applicable |
most probably haven't thought about it
it's also an elegant way which most coders don't like
... as in simple stuff is not leet, complicate it to be a true hax0r ;)
|
|
| Back to top |
|
 |
Hrvoje Brozovic Guest
|
Posted: Mon Nov 14, 2005 1:24 pm Post subject: Re: Hidden cost of this? |
|
|
Adem wrote:
| Quote: | Hrvoje Brozovic wrote:
Does that mean good
|
It means that there is no hidden cost.
Otherwise, it would be silly to use it
in tick count routine, which is performance
critical by its own nature. Kind of access
you using is known during compile time,
so generated code is same as your case of
record structure is only one.
| Quote: |
If so, any idea why it isn't more widely used?
|
Because it has no use in application code.
Also, for simple cases, you can go through with
absolute directive in variable declaration.
Case of records are typical system glue construct.
Their purpose is to match binary layout of some
old (but not legacy) network and system libraryes.
It is not best performer, because records are mostly
packed for binary compatibility, and not compiler aligned.
In many cases, you can find dummy fields intended for
manual aligment, but not allways.
|
|
| Back to top |
|
 |
Kristofer Skaug Guest
|
Posted: Mon Nov 14, 2005 7:49 pm Post subject: Re: Hidden cost of this? |
|
|
Adem wrote:
| Quote: | TGenericConverter = packed record
case Byte of
0: (
LongWord0: LongWord;
);
|
Quickie comments here:
(1) That LongWord should probably be an Int64...
(2) You mix signed and unsigned integer types, as well as generic and
fixed-size types, in these different crackers.
For example 'Integer' is a generic type (size unspecified, platform
dependent) while 'LongInt' is guaranteed to be a 32-bit integer.
This could get you in trouble. To be consistent (and safe) you'd want to
have either:
Unsigned: 1x UInt64*, 2x LongWord, 4x Word, 8x Byte
(* not really supported AFAIK, although the type is predeclared in D7 and
up)
or:
Signed: 1x Int64, 2x LongInt, 4x SmallInt, 4x ShortInt
| Quote: | What are the pros and cons.
|
I don't think there are too many cons, I use these kinds of definitions
myself from time to time; e.g. if you want the value of byte 6 inside an
Int64, you don't need to write all that ugly masking and shifting code, but
simply write TGenericConverter(MyI64).Bytes[5]. Crisp, and exquisitly
clear/understandable.
One thing I recall from the past is that while it sometimes offers a very
elegant way to access sub-regions of an integer, it is often not optimal for
performance (depending on the context). So if you're after blistering fast
code, this may not be the way to do it. Again, the classic tradeoff between
readability and performance.
HTH,
--
Kristofer
|
|
| Back to top |
|
 |
Adem Guest
|
Posted: Tue Nov 15, 2005 5:58 am Post subject: Re: Hidden cost of this? |
|
|
Kristofer Skaug wrote:
| Quote: | Adem wrote:
TGenericConverter = packed record
case Byte of
0: (
LongWord0: LongWord;
);
Quickie comments here:
(1) That LongWord should probably be an Int64...
(2) You mix signed and unsigned integer types, as well as
generic and fixed-size types, in these different crackers.
|
You're, of course, right.
And I should stop using XN as my IDE :-)
| Quote: | What are the pros and cons.
I don't think there are too many cons, I use these kinds of
definitions myself from time to time; e.g. if you want the value
of byte 6 inside an Int64, you don't need to write all that ugly
masking and shifting code, but simply write TGenericConverter
(MyI64).Bytes[5]. Crisp, and exquisitly clear/understandable.
|
That is what I always thought too. Except that I seem to see
more of masking and shifting than this sort of stuff. Which is
what brought me to ask.
| Quote: | One thing I recall from the past is that while it sometimes
offers a very elegant way to access sub-regions of an integer,
it is often not optimal for performance (depending on the context).
So if you're after blistering fast code, this may not be the way
to do it. Again, the classic tradeoff between readability and
performance.
|
Can you elaborate on this a little more please --if you can
recall what they were, I mean the speed concerns.
Cheers,
Adem
|
|
| Back to top |
|
 |
Adem Guest
|
Posted: Tue Nov 15, 2005 6:07 am Post subject: Re: Hidden cost of this? |
|
|
Hrvoje Brozovic wrote:
| Quote: | Adem wrote:
Hrvoje Brozovic wrote:
Because it has no use in application code.
|
There could be though.. Such as parsing fized length
records.
I have also used them while communicating with embedded
controllers (Opto22 stuff), but it is hardly an application
code --as you said.
| Quote: | It is not best performer, because records are mostly
packed for binary compatibility, and not compiler aligned.
In many cases, you can find dummy fields intended for
manual aligment, but not allways.
|
So, If I got you right, if *I* make sure that easch case
*is* the same size as all the others (using dummy bytes
where necessary) it will not suffer speedwise.
If this is correct, it is good enough for me --i.e. it is,
then the best performer?
If not, what is?
Cheers,
Adem
|
|
| Back to top |
|
 |
Adem Guest
|
Posted: Tue Nov 15, 2005 6:09 am Post subject: Re: Hidden cost of this? |
|
|
Primoz Gabrijelcic wrote:
| Quote: | FYI, Sysutils.pas defines:
|
[...]
| Quote: | And that's been with us for a looooong time...
|
Point taken. Though you're right, I really haven't
seen any such use in the millions of lines of code
I have d/l'ed from Torry's etc. or purchased.
Probably none at all..
| Quote: | Read the source, Luke!
|
:-)
Cheers,
Adem
|
|
| Back to top |
|
 |
Hrvoje Brozovic Guest
|
Posted: Wed Nov 16, 2005 9:23 am Post subject: Re: Hidden cost of this? |
|
|
Adem wrote:
| Quote: |
So, If I got you right, if *I* make sure that easch case
*is* the same size as all the others (using dummy bytes
where necessary) it will not suffer speedwise.
|
No, you didn't get me right. Aligment means that elements
should start at 4 or even 8 bytes positinons. If records
are packed, compiler will put elements without aligment gaps.
So you need to provoke gaps with dummy elements for aligment.
|
|
| 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
|
|