better way to pass arguements to a function

S

sam_cit

Hi Everyone,

I have the following structure and i have a function that will
work(modify/edit) the members of the structure, please tell me which is
a better apprach considering both time and memory complexity,

struct sample
{
char* string;
int n;
}*p;

(a0 func(struct sample*p)
{
char * local_string = p->string;
int local_n = p->n;
...
}

// This will have three variables on the stack

(b) func(char *local_string,int local_n)
{
...
}

//This will have two variables on the stack

I feel first approach was good, but looking at one increased member in
stack, i'm wondering... also note that i'm storing the members of the
structure into a local variable because in real project the structure
name and pointer are lengthy and doesn't help in readability of the
code. Please let me know your suggestions...
 
R

Richard Heathfield

(e-mail address removed) said:
Hi Everyone,

I have the following structure and i have a function that will
work(modify/edit) the members of the structure, please tell me which is
a better apprach considering both time and memory complexity,

struct sample
{
char* string;
int n;
}*p;

(a0 func(struct sample*p)
{
char * local_string = p->string;
int local_n = p->n;
...
}

// This will have three variables on the stack

Not necessarily. There might not even be a stack. What you do have, however,
is three objects - p, local_string, and local_n - which exist only for the
lifetime of the call to func().
(b) func(char *local_string,int local_n)
{
...
}

//This will have two variables on the stack

Not necessarily. There might not even be a stack. What you do have, however,
is two objects - local_string and local_n - which exist only for the
lifetime of the call to func().
I feel first approach was good, but looking at one increased member in
stack, i'm wondering... also note that i'm storing the members of the
structure into a local variable because in real project the structure
name and pointer are lengthy and doesn't help in readability of the
code. Please let me know your suggestions...

I suggest that you forget about "the stack", and forget about whether it's
better to use two objects or three (or, heavens above, four!), and focus
instead on clarity and correctness. If you use good algorithms,
implementing them clearly and correctly, you will find that this is almost
always good enough. Indeed, for many people it's *always* good enough.
 
S

sam_cit

I suggest that you forget about "the stack", and forget about whether it's
better to use two objects or three (or, heavens above, four!), and focus
instead on clarity and correctness. If you use good algorithms,
implementing them clearly and correctly, you will find that this is almost
always good enough. Indeed, for many people it's *always* good enough.

I agree, yes the logic of the function is good enough in itself and
assuming everything else is fine, whats the harm in optimizing the code
further (even if it seems to be insignificant), say for example my
function may be called many times... if that is the case which of the
above would you prefer???
 
C

Chris Dollin

Hi Everyone,

I have the following structure and i have a function that will
work(modify/edit) the members of the structure, please tell me which is
a better apprach considering both time and memory complexity,

struct sample
{
char* string;
int n;
}*p;

(a0 func(struct sample*p)
{
char * local_string = p->string;
int local_n = p->n;
...
}

// This will have three variables on the stack

That depends on your implementation.
(b) func(char *local_string,int local_n)
{
...
}

//This will have two variables on the stack

That depends on your implementation. To a good first approximation,
this isn't the thing to worry about, unless you (a) know the
implementation very well and (b) have good reason to worry.

I'd say that the first one was the obvious right one: you have
sample objects and you pass pointers to them around.
I feel first approach was good, but looking at one increased member in
stack, i'm wondering... also note that i'm storing the members of the
structure into a local variable because in real project the structure
name and pointer are lengthy and doesn't help in readability of the
code. Please let me know your suggestions...

Do what's clear.

Fix the coding standard if it's getting in the way of clarity without
more important benefit elsewhere.

Note that if you do:

int local_n = p->n;

and then update `local_n` you'll have to reflect that back to
`p->n`: forgetting to do do could be a problem (that should be
caught by your test suite).
 
C

Chris Dollin

(e-mail address removed) wrote:

(DON'T DROP ATTRIBUTIONS. It was Richard Heathfield who said the ">>" parts
below, and your post should have said so.)
I agree, yes the logic of the function is good enough in itself and
assuming everything else is fine, whats the harm in optimizing the code
further (even if it seems to be insignificant), say for example my
function may be called many times... if that is the case which of the
above would you prefer???

Because it wastes precious developer time on something that you don't
know is an issue, and introduces additional chances to make a mistake.

If your application runs fast enough, worrying about how to make it
faster isn't as worthwhile as implementing a new feature with
business value (whatever that may be in your field).

If it /doesn't/ run fast enough, guessing where you should optimise
is a time-honoured technique for getting the wrong answer. Instead,
/measure/ where your code is spending its time. You may well be
surprised. (I have been.) Then when you know where the cycles are
leaking away, /think/ about how to improve it. Look for possible
orders-of-magnitude improvement in the algorithms, such as replacing
linear search by hash tables or binary chop, not piddling little
ones like the number of automatic variables in a function.

Sometimes you /do/ have to worry about micro-optimisation. But it's
rare that you have to /start/ there.

Oh, and remember the -O flag that many C compilers have.
 
C

Charlton Wilbur

CD> If it /doesn't/ run fast enough, guessing where you should
CD> optimise is a time-honoured technique for getting the wrong
CD> answer. Instead, /measure/ where your code is spending its
CD> time. You may well be surprised. (I have been.) Then when you
CD> know where the cycles are leaking away, /think/ about how to
CD> improve it. Look for possible orders-of-magnitude improvement
CD> in the algorithms, such as replacing linear search by hash
CD> tables or binary chop, not piddling little ones like the
CD> number of automatic variables in a function.

CD> Sometimes you /do/ have to worry about micro-optimisation. But
CD> it's rare that you have to /start/ there.

An example from my own experience, though a couple years old: the
PowerPC architecture is very fast at floating point operations, very
fast at integer operations, but very slooooooow at converting integers
to floating point numbers and vice versa. A programmer, prematurely
optimizing, decided that for speed he would do all the math in a
computation-intensive loop with integers, because, as everybody knows,
integer math is faster.

Profiling identified the offending function, but it was a PowerPC
expert who put his finger on the cause.

Charlton
 
D

Dave Vandervies

Chris Dollin said:
Sometimes you /do/ have to worry about micro-optimisation. But it's
rare that you have to /start/ there.

Oh, and remember the -O flag that many C compilers have.

And, since you're remembering -O, you should also be remembering two
things about it:
-If your code works by accident (as opposed to working because it's
correct), optimization will probably break it.
-If you have trouble understanding how and why your code works, the
optimizer will probably also have trouble understanding it.

Coincidentally, micro-optimizing your code is a good way to run into
problems with these things.


dave
 
S

sam_cit

Coincidentally, micro-optimizing your code is a good way to run into
problems with these things.

Hello everyone, i understand the point made by everyone, its kind of
not to change when the optimization doesn't help a great bit, however
assuming that there will be no breakage and everything else is fine, i
just want to know which one should be used...
 
C

Chris Dollin

Hello everyone, i understand the point made by everyone, its kind of
not to change when the optimization doesn't help a great bit, however
assuming that there will be no breakage and everything else is fine, i
just want to know which one should be used...

The clearest and most straightforward one (which, in my view, is the
one that passes the pointer-to-struct around, rather than the bits-and-
pieces).
 
S

sam_cit

The clearest and most straightforward one (which, in my view, is the
one that passes the pointer-to-struct around, rather than the bits-and-
pieces).

Yes, but in a way, when a pointer to the structure is passed as a
whole, it gives the functions more of freedom to operate on the
structure members and when this happens the complexity of the function
may be increased, by complexity i mean cyclomatic complexity... thats
one drawback i see for the big projects where developers come in and
change and keep moving out...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top