473,385 Members | 1,888 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Performance vs. Design (long)

I've had some discussions with colleagues about the
API of a module for sending/receiving messages on a
network connection.

On both ends are different applications, each having
their own internal way of storing the data which has
to be communicated (using a common data protocol).

I proposed to use a common interface, having the face
of the network data protocol (XYZ). Many fields in the
protocol message are optional. I proposed to use a
bit-field structure. To prevent one extra copy of
large chucks of data, I proposed to use pointers.

typedef struct
{
unsigned int number1 : 1;
unsigned int number2 : 1;
unsigned int much_data : 8; /* > 0 means length */
} XYZ_ind;

typedef struct
{
int number1;
int number2;
char *much_data;
XYX_ind_t ind;
} XYZ_data_t;

void XYZ_send(XYZ_data_t *data); /* encodes, then sends */

The receiving side uses a callback, with similar prototype.

Both sides will now have to convert their own internal format
to a XYZ_data_t structure. This creates a clea[n|r] interface,
making the XYZ module independent of either side.
The 'opposing' idea is to not specify a common interface for
all users. So, no XYZ_data_t. Instead of one shared XYZ_send(),
there will be two: A_send(A_data_t *) and B_send(B_data *).
Instead of one module, there will be three.

The only advantage above having a real interface, is performance:
no conversion between internal format to XYZ_data_t (which is not
much more than assignments). The A_send() and B_send() will both
encode the message in their own way, and right away.
Yes, we are working on time-critical stuff, but I have the feeling
that this second approach falls in the 97% of the 'premature opti-
mization, being the root of all evil'. I estimated that the clean
interface may add about 1/1000 to the execution time.

Any thoughts on this issue?

Case

Nov 14 '05 #1
9 913
Case wrote:

I've had some discussions with colleagues about the
API of a module for sending/receiving messages on a
network connection.

On both ends are different applications, each having
their own internal way of storing the data which has
to be communicated (using a common data protocol).

I proposed to use a common interface, having the face
of the network data protocol (XYZ). Many fields in the
protocol message are optional. I proposed to use a
bit-field structure. To prevent one extra copy of
large chucks of data, I proposed to use pointers.

typedef struct
{
unsigned int number1 : 1;
unsigned int number2 : 1;
unsigned int much_data : 8; /* > 0 means length */
} XYZ_ind;
.... snip ... mization, being the root of all evil'. I estimated that the
clean interface may add about 1/1000 to the execution time.

Any thoughts on this issue?


What clean interface? One bit numbers don't carry much
information, and I have a tough time envisioning much_data crammed
into 8 bits. Also, bit fields are inherently non-portable, even
between generations of the same compiler on the same hardware.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #2
CBFalconer wrote:
Case wrote:
I've had some discussions with colleagues about the
API of a module for sending/receiving messages on a
network connection.

On both ends are different applications, each having
their own internal way of storing the data which has
to be communicated (using a common data protocol).

I proposed to use a common interface, having the face
of the network data protocol (XYZ). Many fields in the
protocol message are optional. I proposed to use a
bit-field structure. To prevent one extra copy of
large chucks of data, I proposed to use pointers.

typedef struct
{
unsigned int number1 : 1;
unsigned int number2 : 1;
unsigned int much_data : 8; /* > 0 means length */
} XYZ_ind;


... snip ...
mization, being the root of all evil'. I estimated that the
clean interface may add about 1/1000 to the execution time.

Any thoughts on this issue?

What clean interface? One bit numbers don't carry much
information, and I have a tough time envisioning much_data crammed
into 8 bits. Also, bit fields are inherently non-portable, even
between generations of the same compiler on the same hardware.


XYZ_ind contains presence/length indicators for the actual
structure members, which have the same name.

Case

Nov 14 '05 #3
In <40***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:
into 8 bits. Also, bit fields are inherently non-portable, even ^^^^between generations of the same compiler on the same hardware.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^
Care to provide a couple of concrete examples? I have a hard time
imagining an implementor screwing his user base...

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #4
On Thu, 24 Jun 2004 13:26:24 +0200, Case <no@no.no> wrote:
I've had some discussions with colleagues about the
API of a module for sending/receiving messages on a
network connection.

On both ends are different applications, each having
their own internal way of storing the data which has
to be communicated (using a common data protocol).

I proposed to use a common interface, having the face
of the network data protocol (XYZ). Many fields in the
protocol message are optional. I proposed to use a
bit-field structure. To prevent one extra copy of
large chucks of data, I proposed to use pointers.

typedef struct
{
unsigned int number1 : 1;
unsigned int number2 : 1;
unsigned int much_data : 8; /* > 0 means length */
} XYZ_ind;

typedef struct
{
int number1;
int number2;
char *much_data;
XYX_ind_t ind;
} XYZ_data_t;

void XYZ_send(XYZ_data_t *data); /* encodes, then sends */
I wouldn't use the bit fields. Aside from their portability problems,
they will probably be less efficient - the transmission time saved
will be less than the additional processing time.
[OT]
Communications protocols typically send the message size first, making
it easy to grab the entire message in two reads, and making it easy to
send variable size messages, or change your mind about the message
size.
I assume that your send routine is sending the data that much_data
points to, not the pointer itself.
The receiving side uses a callback, with similar prototype.

Both sides will now have to convert their own internal format
to a XYZ_data_t structure. This creates a clea[n|r] interface,
making the XYZ module independent of either side.
The 'opposing' idea is to not specify a common interface for
all users. So, no XYZ_data_t. Instead of one shared XYZ_send(),
there will be two: A_send(A_data_t *) and B_send(B_data *).
Instead of one module, there will be three.

The only advantage above having a real interface, is performance:
no conversion between internal format to XYZ_data_t (which is not
much more than assignments). The A_send() and B_send() will both
encode the message in their own way, and right away.
Yes, we are working on time-critical stuff, but I have the feeling
that this second approach falls in the 97% of the 'premature opti-
mization, being the root of all evil'. I estimated that the clean
interface may add about 1/1000 to the execution time.

Any thoughts on this issue?

Case


--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 14 '05 #5
Alan Balmer wrote:
On Thu, 24 Jun 2004 13:26:24 +0200, Case <no@no.no> wrote:
I've had some discussions with colleagues about the
API of a module for sending/receiving messages on a
network connection.

On both ends are different applications, each having
their own internal way of storing the data which has
to be communicated (using a common data protocol).

I proposed to use a common interface, having the face
of the network data protocol (XYZ). Many fields in the
protocol message are optional. I proposed to use a
bit-field structure. To prevent one extra copy of
large chucks of data, I proposed to use pointers.

typedef struct
{
unsigned int number1 : 1;
unsigned int number2 : 1;
unsigned int much_data : 8; /* > 0 means length */
} XYZ_ind;

typedef struct
{
int number1;
int number2;
char *much_data;
XYX_ind_t ind;
} XYZ_data_t;

void XYZ_send(XYZ_data_t *data); /* encodes, then sends */


I wouldn't use the bit fields. Aside from their portability problems,
they will probably be less efficient - the transmission time saved
will be less than the additional processing time.
[OT]
Communications protocols typically send the message size first, making
it easy to grab the entire message in two reads, and making it easy to
send variable size messages, or change your mind about the message
size.
I assume that your send routine is sending the data that much_data
points to, not the pointer itself.


I think I am so much in this design, that I forgot to
mention essentials for understanding it for outsiders.
Sorry about this people. I don't send the XYZ_ind_t
field, which is only used to indicate which fields of
the actual data in the rest of the struct needs to be
send.

I decided to use bit-fields because of their small size
compared to using a set of booleans (i.e., int's). This
is because I need to initializa all indicators to 0;
again a matter of performance. In my real aplication
there are about 40 optional fields, of which less than
half are actually being used on average.

In my view, bit-fields are not that performance demanding
compared to using int's set to 0 or 1. What do you think?

Case

Nov 14 '05 #6

On Thu, 24 Jun 2004, Case - wrote:

typedef struct
{
unsigned int number1 : 1;
unsigned int number2 : 1;
unsigned int much_data : 8; /* > 0 means length */
} XYZ_ind;
I wouldn't use the bit fields.

[...] I decided to use bit-fields because of their small size
compared to using a set of booleans (i.e., int's). This
is because I need to initializa all indicators to 0;
again a matter of performance. In my real aplication
there are about 40 optional fields, of which less than
half are actually being used on average.

In my view, bit-fields are not that performance demanding
compared to using int's set to 0 or 1. What do you think?


I would use a set of flags, myself.

struct XYZ_ind
{
unsigned long fields;
int much_data;
};

#define FIELD_NUMBER1 0x0001
#define FIELD_NUMBER2 0x0002
#define FIELD_FOO 0x0004
[...]

Then instead of 'if (x->number1)' you would write
'if (x->fields & FIELD_NUMBER1)'. Extra typing, but guaranteed to
be small (unlike bit-fields, AFAIK) and pretty fast in practice.
And bitwise flags are IMHO less obscure than bit-fields, although
you could argue both ways, I suppose.

And of course initializing all your flags to zero becomes a single
assignment, instead of 32 assignments. That's a plus.

If you need more than 32 flags, just add a 'fields2' member to
your struct. If it sounds reasonable, you might segregate the
flags by purpose, e.g.

unsigned int header_flags;
unsigned int encoding_flags;
unsigned int message_flags;
unsigned int network_flags;
[...]

HTH,
-Arthur
Nov 14 '05 #7
In article <40**********************@dreader2.news.tiscali.nl >,
Case - <no@no.no> wrote:
I decided to use bit-fields because of their small size
compared to using a set of booleans (i.e., int's). This
is because I need to initializa all indicators to 0;
again a matter of performance. In my real aplication
there are about 40 optional fields, of which less than
half are actually being used on average.

In my view, bit-fields are not that performance demanding
compared to using int's set to 0 or 1. What do you think?


Bit fields are inherently non-portable. To maximise portability, send a
sequence of unsigned char values with values from 0 to 255. Instead of
bit-fields, use the eight bits in the unsigned char.

Otherwise, at the very least you will end up having to define your
structs in different ways depending on the compiler.
Nov 14 '05 #8
"Case -" <no@no.no> wrote in message
news:40**********************@dreader2.news.tiscal i.nl...
Alan Balmer wrote:
On Thu, 24 Jun 2004 13:26:24 +0200, Case <no@no.no> wrote:
I've had some discussions with colleagues about the
API of a module for sending/receiving messages on a
network connection.

On both ends are different applications, each having
their own internal way of storing the data which has
to be communicated (using a common data protocol).

I proposed to use a common interface, having the face
of the network data protocol (XYZ). Many fields in the
protocol message are optional. I proposed to use a
bit-field structure. To prevent one extra copy of
large chucks of data, I proposed to use pointers.

typedef struct
{
unsigned int number1 : 1;
unsigned int number2 : 1;
unsigned int much_data : 8; /* > 0 means length */
} XYZ_ind;

typedef struct
{
int number1;
int number2;
char *much_data;
XYX_ind_t ind;
} XYZ_data_t;

void XYZ_send(XYZ_data_t *data); /* encodes, then sends */


I wouldn't use the bit fields. Aside from their portability problems, they will probably be less efficient - the transmission time saved
will be less than the additional processing time.
[OT]
Communications protocols typically send the message size first, making it easy to grab the entire message in two reads, and making it easy to send variable size messages, or change your mind about the message
size.
I assume that your send routine is sending the data that much_data
points to, not the pointer itself.


I think I am so much in this design, that I forgot to
mention essentials for understanding it for outsiders.
Sorry about this people. I don't send the XYZ_ind_t
field, which is only used to indicate which fields of
the actual data in the rest of the struct needs to be
send.

I decided to use bit-fields because of their small size
compared to using a set of booleans (i.e., int's). This
is because I need to initializa all indicators to 0;
again a matter of performance. In my real aplication
there are about 40 optional fields, of which less than
half are actually being used on average.

In my view, bit-fields are not that performance demanding
compared to using int's set to 0 or 1. What do you think?

It depends upon the processor. Some processors have built-in
bit-handling instructions; some do not. Most mid- to high-range
processors handle ints much more efficiently than they handle individual
bits.

Travis
Nov 14 '05 #9
I would use flags either.
--
Felipe Magno de Almeida
Ciencia da Computacao - Unicamp
fe************@ic.unicamp.br - UIN: 146989862
Cause Rock and Roll can never die.
"if you want to learn something really well, teach it to a computer."
What is Communism?
Answer: "Communism is the doctrine of the conditions of the liberation
of the proletariat." (by Karl Marx)
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

25
by: Brian Patterson | last post by:
I have noticed in the book of words that hasattr works by calling getattr and raising an exception if no such attribute exists. If I need the value in any case, am I better off using getattr...
6
by: Andreas Lauffer | last post by:
I changed from Access97 to AccessXP and I have immense performance problems. Details: - Access XP MDB with Jet 4.0 ( no ADP-Project ) - Linked Tables to SQL-Server 2000 over ODBC I used...
5
by: Scott | last post by:
I have a customer that had developed an Access97 application to track their business information. The application grew significantly and they used the Upsizing Wizard to move the tables to SQL...
24
by: Bob Alston | last post by:
Most of my Access database implementations have been fairly small in terms of data volume and number of concurrent users. So far I haven't had performance issues to worry about. <knock on wood> ...
4
by: Martin | last post by:
I am using graphics as backgrounds for forms,buttons,labels etc. The question is: is it faster to load all graphics from files on app start or to use it embeded (places in editor during design)....
13
by: bjarne | last post by:
Willy Denoyette wrote; > ... it > was not the intention of StrousTrup to the achieve the level of efficiency > of C when he invented C++, ... Ahmmm. It was my aim to match the performance...
2
by: brian.gabriel | last post by:
I have a core web service that acts as a gateway for several third party web services. Each one of the third party web services has it's own "interface" class derived from a main interface. When...
9
by: HC | last post by:
Hello, all, I started out thinking my problems were elsewhere but as I have worked through this I have isolated my problem, currently, as a difference between MSDE and SQL Express 2005 (I'll just...
13
by: atlaste | last post by:
Hi, I'm currently developing an application that uses a lot of computational power, disk access and memory caching (to be more exact: an information retrieval platform). In these kind of...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.