Pass pointers or the things they point to

B

Blue Ocean

I know this is somewhat dependent on the circumstances, but let me ask
anyway. Suppose I have a 100 byte struct or array or something like
that. Which would be more efficient?

void function(struct something foo)
{
foo.this + foo.that;
foo.somethingoranother++;
printf(foo.foostring);
//other operations on the array
}

or

void function(string something *foo)
{
foo->this + foo->that;
foo->somethingoranother++;
printf(foo->foostring);
//other operations on the array
}

I guess the question I'm trying to ask is, how efficient is it to pass
mostly pointers except for primitive types? Is it a better idea to do
that or to pass by value for the most part?
 
M

Malcolm

Blue Ocean said:
I guess the question I'm trying to ask is, how efficient is it to pass
mostly pointers except for primitive types? Is it a better idea to do
that or to pass by value for the most part?
Pass a pointer (a const pointer if the structure doesn't need to be
modified). It is more efficient as you are probably passing a single
register rather than copying data to the stack, and it is more idiomatic - C
programmers expect to see struct arguments passed as pointers.
 
J

Jens.Toerring

Malcolm said:
Pass a pointer (a const pointer if the structure doesn't need to be
modified). It is more efficient as you are probably passing a single
register rather than copying data to the stack, and it is more idiomatic - C
programmers expect to see struct arguments passed as pointers.

Well, I would guess it depends. If you need a copy of the structure
in the function anyway (it's not clear to me from the pseudo-code
what exactly "Blue Ocean" had in mind) it might be even at least as
efficient to pass the structure to the function instead of copying
it yourself. And since all accesses to the elements have to be done
by dereferencing the pointer (after adding an offset) it is not im-
possible that the compiler produces more efficient code when it can
already figure out at compile time where exactly the copy of the
structure is going to end up (e.g. at some fixed offset from the
stack pointer). Cache issues might also play some role...

I guess that passing just a pointer instead of the structure can
only be seen as "more efficient" in all possible cases when one
defines efficiency just as "burning less CPU cycles and doing
less memory accesses during the invocation of the function".
But when one looks at the efficiency of the whole function the
picture can become more complicated, even that complicated that
it's more or less impossible to answer it. Anyway, this is no
question that can be answered from a clean clc point of view,
too many details of the implementation are getting into it...
At least I wouldn't cringe at seeing a structure passed as such
to a function instead of just a pointer to it.

Regards, Jens
 
J

jacob navia

Blue Ocean said:
I know this is somewhat dependent on the circumstances, but let me ask
anyway. Suppose I have a 100 byte struct or array or something like
that. Which would be more efficient?

void function(struct something foo)
{
foo.this + foo.that;
foo.somethingoranother++;
printf(foo.foostring);
//other operations on the array
}

or

void function(string something *foo)
{
foo->this + foo->that;
foo->somethingoranother++;
printf(foo->foostring);
//other operations on the array
}

I guess the question I'm trying to ask is, how efficient is it to pass
mostly pointers except for primitive types? Is it a better idea to do
that or to pass by value for the most part?

Do you want to pass a copy of the data or the data itself?

In some situations is better to pass a copy to keep the
original data, and in some others it is better to pass
the data itself with a pointer to it.

This is dependent on the usage of the data and in the
whole structure of the application. There are no
general rules to know when one solution is better
than the other.

The machine doesn't do a copy when passing a pointer, hence
the operation takes less time. If you need a copy
however, it saves you the writing of code to make a copy
passing the structure by value.
 
B

Barry Schwarz

I know this is somewhat dependent on the circumstances, but let me ask
anyway. Suppose I have a 100 byte struct or array or something like
that. Which would be more efficient?

void function(struct something foo)
{
foo.this + foo.that;
foo.somethingoranother++;
printf(foo.foostring);
//other operations on the array
}

or

void function(string something *foo)
{
foo->this + foo->that;
foo->somethingoranother++;
printf(foo->foostring);
//other operations on the array
}

I guess the question I'm trying to ask is, how efficient is it to pass
mostly pointers except for primitive types? Is it a better idea to do
that or to pass by value for the most part?

Since the two options are not equivalent, questions about efficiency
are irrelevant.

Do you want the original struct in the calling function to be modified
by the activities of function() or not. If the answer is yes, pass
the pointer. If the answer is no, pass the struct.

By the way, what array are you talking about in your comment? Did you
mean struct?


<<Remove the del for email>>
 
A

Aguilar, James

Barry Schwarz said:
By the way, what array are you talking about in your comment? Did you
mean struct?

Forgive me for being confusing. I was originally going to talk about an
array, but then I changed my mind and used a struct.

Thanks for the help.
 
M

Malcolm

Well, I would guess it depends.
You can't be absolutely sure about this type of implementation issue, of
course.
If you need a copy of the structure
in the function anyway (it's not clear to me from the pseudo-code
what exactly "Blue Ocean" had in mind) it might be even at least as
efficient to pass the structure to the function instead of copying
it yourself.
This may be the case. But how often do you need a temporary copy of a struct
in real code? There are examples, of course, but not so many. And if
virtually all your functions are taking a struct employee *, it is far
neater to accept a small runtime penalty and make the one function that does
need a temporary copy also take a (const) struct employee *.
And since all accesses to the elements have to be done
by dereferencing the pointer (after adding an offset) it is not im-
possible that the compiler produces more efficient code when it can
already figure out at compile time where exactly the copy of the
structure is going to end up (e.g. at some fixed offset from the
stack pointer). Cache issues might also play some role...
This isn't impossible. However typically you will pass the structure pointer
in a register, and access will be via read/write through that register.
Access to the stack will be via the stack register. Unless the stack
register is privileged in some way, there won't be a difference. Also, of
course, it is very common to use only some members of the structure passed
in, in which case the pass by value approach causes needless copying.
Anyway, this is no question that can be answered from a clean clc point
of view, too many details of the implementation are getting into it...
At least I wouldn't cringe at seeing a structure passed as such
to a function instead of just a pointer to it.
I think what we need to focus on is that often passing the pointer is far
more efficient (eg an access function that just returns a member variable of
a big opaque structure), whilst occasionally the pass by value method may
offer slight improvements in efficiency.
However a consistent interface is to be preferred, and you also have the
problem of structures which contain pointers as members. Two copies of a
pointer is always asking for trouble.

So except in the case of a clear efficiency need to pass a small structure
on the stack, I would always go for passing the pointer.
 
D

Dan Pop

In said:
I know this is somewhat dependent on the circumstances, but let me ask
anyway. Suppose I have a 100 byte struct or array or something like
that. Which would be more efficient?

void function(struct something foo)
{
foo.this + foo.that;
foo.somethingoranother++;

You're changing the local copy. The caller's master copy remains
unchanged.
printf(foo.foostring);
//other operations on the array
}

or

void function(struct something *foo)
{
foo->this + foo->that;
foo->somethingoranother++;

You're changing the caller's struct.
printf(foo->foostring);
//other operations on the array
}

I guess the question I'm trying to ask is, how efficient is it to pass
mostly pointers except for primitive types? Is it a better idea to do
that or to pass by value for the most part?

It is more than somewhat dependent on the circumstances, it is *entirely*
dependent on the circumstances. The best answer can be obtained only
after a careful analysis of the circumstances.

The main things to consider are:

1. Do you want the local changes to be propagated back to the caller?

2. How much data is involved?

Dan
 

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

Staff online

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top