For Programmers: Free Programming Magazines  


Home > Archive > VC Language > January 2006 > A question about efficiency









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author A question about efficiency
David++

2006-01-25, 4:17 am

Dear list,

I have a question regarding functions and passing by value Vs passing by
references.

When we pass by value a copy is made of the passed object. (So thus does
every object have a default copy constructor?). When we pass by reference we
merely take the address of the object and make changes to the object at that
address..is this correct?

I imagine it is more processor intensive and uses more memory to pass by
value then. Where as, when we pass by reference as no copy of the object is
made we save a little memory overhead...does this seem feasible?

I would like to make my code efficient as possible and try to reduce
overhead where I can. Using a simple console app I have two functions, one
passes by value, and one passes by reference. I am hoping the pass by
reference function is more efficient. Please have a look and tell me what you
think, or if you have any other recomendations.

Thanks!

David

Code -

#include <iostream>

using namespace std;

float func1(float f)
{
float g;

g = f + 10;

return(g);
}

void func2(float &f, float &g)
{
g = f + 10;
}

int main()
{
float fGain = 10;
float jGain = 0;

cout << "Doing func1...\n";
jGain = func1(fGain);

cout << "The value of jGain is : ";
cout << jGain;
cout << "\n\n";

cout << "Reset jGain to 0\n";
jGain = 0;

cout << "Doing func2...\n";
func2(fGain, jGain);

cout << "The value of jGain is : ";
cout << jGain;

cout << "\n\n";
return 0;
}


Ulrich Eckhardt

2006-01-25, 4:17 am

David++ wrote:
> I have a question regarding functions and passing by value Vs passing by
> references.
>
> When we pass by value a copy is made of the passed object. (So thus does
> every object have a default copy constructor?).


Google for "C++ Law Three".

> When we pass by reference we merely take the address of the object and
> make changes to the object at that address..is this correct?


Right. The difference to passing a pointer is mainly that you implicitly
document that the pointer is not zero.

> I imagine it is more processor intensive and uses more memory to pass by
> value then. Where as, when we pass by reference as no copy of the object
> is made we save a little memory overhead...does this seem feasible?


It depends. If I have a small object, creating a copy might turn out to be
faster than dereferencing a pointer.

> I would like to make my code efficient as possible and try to reduce
> overhead where I can. Using a simple console app I have two functions, one
> passes by value, and one passes by reference. I am hoping the pass by
> reference function is more efficient. Please have a look and tell me what
> you think, or if you have any other recomendations.


Theories are no replacement for benchmark. You need to measure this
performance.


> float func1(float f)
> {
> float g;
>
> g = f + 10;
>
> return(g);
> }
>
> void func2(float &f, float &g)
> {
> g = f + 10;
> }


Performance can also be affected by whether these are inlined or not. In any
case, I guess that the function calling overhead is larger than the
difference in how fast the content of the functions are executed. Unless
you have data from benchmarks requiring improvements, stay as natural as
possible:

float add_10( float g)
{
return g+10.0f;
}


Uli

Frederic Fuzier

2006-01-25, 7:58 am

Regarding efficiency, if you pass a parameter by reference because you only
want to avoid the copy, it's better to have a parameter which is a const
reference.

void func2(const float &f, float &g)
{
g = f + 10;
}

Doing this, the call can be made both on a const and non-const f object,
even a literal value.
As a side effect, it allows implicit conversion, for instance from int

In func2, g is then documented as an in/out parameter.

As Uli has suggested for his function add_10, func1 could be write as :
float func1(float f)
{
return (f+10.0f);
}
for an object more complex than a float the compiler may optimize the code
with the "return value optimization" which avoids the creation of temporary
objects.

Fred




Alexander Grigoriev

2006-01-25, 7:23 pm

On the other hand, it doesn't make sense to pass 4-byte const POD (float) by
reference.

"Frederic Fuzier" <remove_ffuzier@repgroup.net> wrote in message
news:%23b1zCHaIGHA.516@TK2MSFTNGP15.phx.gbl...
> Regarding efficiency, if you pass a parameter by reference because you
> only want to avoid the copy, it's better to have a parameter which is a
> const reference.
>
> void func2(const float &f, float &g)
> {
> g = f + 10;
> }
>
> Doing this, the call can be made both on a const and non-const f object,
> even a literal value.
> As a side effect, it allows implicit conversion, for instance from int
>
> In func2, g is then documented as an in/out parameter.
>
> As Uli has suggested for his function add_10, func1 could be write as :
> float func1(float f)
> {
> return (f+10.0f);
> }
> for an object more complex than a float the compiler may optimize the code
> with the "return value optimization" which avoids the creation of
> temporary objects.
>
> Fred
>
>
>
>



Bo Persson

2006-01-25, 7:23 pm


"David++" <David@discussions.microsoft.com> skrev i meddelandet
news:1D85B2D9-2408-4B8B-B5E8-ED445C413D49@microsoft.com...
> Dear list,
>
> I have a question regarding functions and passing by value Vs
> passing by
> references.
>
> When we pass by value a copy is made of the passed object. (So thus
> does
> every object have a default copy constructor?). When we pass by
> reference we
> merely take the address of the object and make changes to the object
> at that
> address..is this correct?


Yes. One common use of pass by reference is when we actually want to
update the original value.

>
> I imagine it is more processor intensive and uses more memory to
> pass by
> value then. Where as, when we pass by reference as no copy of the
> object is
> made we save a little memory overhead...does this seem feasible?


As usual, it depends. :-)

You have to pass the parameter somehow. That will use some resources,
whatever you do.

Some objects, like the built in types, or objects with "cheap" copy
constructors are not very expensive to copy. If you make a copy, one
benefit is that you can't accidentally change the original value.

Also, on a 64 bit computer a pointer or a reference might use 64 bits,
while a float only uses 32 bits. Which one is cheapest to copy or
store? :-)

>
> I would like to make my code efficient as possible and try to reduce
> overhead where I can. Using a simple console app I have two
> functions, one
> passes by value, and one passes by reference. I am hoping the pass
> by
> reference function is more efficient. Please have a look and tell me
> what you
> think, or if you have any other recomendations.
>


Generally you shouldn't bother with this, until you have a program
that works correctly, but runs to slow. Most often you will find that
your program runs fast enough. And if it doesn't, it depends more on
the work your functions perform, than on the way you pass the
parameters.




Bo Persson


Brian Muth

2006-01-25, 7:23 pm

IMHO this is a case of "premature optimization".

You need to profile your application first to find out where the bottlenecks
exist. You could very well be focussing on a completely irrelevent section
of code.

Brian


Ben Voigt

2006-01-26, 7:08 pm


"Frederic Fuzier" <remove_ffuzier@repgroup.net> wrote in message
news:%23b1zCHaIGHA.516@TK2MSFTNGP15.phx.gbl...
> Regarding efficiency, if you pass a parameter by reference because you
> only want to avoid the copy, it's better to have a parameter which is a
> const reference.
>
> void func2(const float &f, float &g)
> {
> g = f + 10;
> }
>
> Doing this, the call can be made both on a const and non-const f object,
> even a literal value.
> As a side effect, it allows implicit conversion, for instance from int
>
> In func2, g is then documented as an in/out parameter.
>
> As Uli has suggested for his function add_10, func1 could be write as :
> float func1(float f)
> {
> return (f+10.0f);
> }
> for an object more complex than a float the compiler may optimize the code
> with the "return value optimization" which avoids the creation of
> temporary objects.


For code like this (assuming you have an array of function pointers or some
such so inlining isn't applicable), the optimization
is to pass the parameter and return value of the FPU stack, where it's
already ready to use, and you can't get faster than that.

References imply passing the value in memory, so you have an address. Even
if it's in L1 data cache, it's still far slower than in a register.

I think floating point values are pass-in-register by default. For other
data types, check the __fastcall keyword.

>
> Fred
>
>
>
>



David++

2006-01-27, 4:01 am

Ok, thankyou everyone for your opinions and tips. What amazes me is that even
a simple function can be implemented in many different ways. Knowing the
right way or picking the 'best way' for the job is something which I feel
must come with experience.

With regards to the code I posted. I have finished my program, it is a
real-time digital audio effect and uses some quite processor intensive dsp
algorithms. I've had varying results under different platforms ranging from
1% CPU to 10% CPU. I'm personally getting around 5% CPU. So now I am at the
stage where I want to look at each individual function I use and try and make
it as cost effective and safe as possible. I must admit I've been inspired by
the Meyers C++ book, its kinda opened up a new way to think about coding for
me.

Well, thanks once again for all the very useful answers you made....the
learning continues.

Best Regards,
David
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com