would ever passing a primitive to functions by reference be moreeffecient ?

G

Good Guy

In a scenario that a caller function needs to pass one of its local
variables of a primitive type to a callee and doesn't necessarily need
to pass it by reference to track that variable later after callee is
done, I know that it'd be said to pass it by value and that makes
total sense for primitive types with a size equal to or smaller than
size of pointer; but I'm curious that from an assembly
point(performance-wise or space-wise), wouldn't be there a situation
when passing a variable of a primitive type with a size bigger than
pointers like long double on my platform which has a size of 8 bytes
and is bigger than pointers that have a size of 4 bytes; by reference
would be more efficient?
If in this specific case, passing by reference might ever be more
efficient, how can we know to pass by reference or value ?
 
A

AnonMail2005

In a scenario that a caller function needs to pass one of its local
variables of a primitive type to a callee and doesn't necessarily need
to pass it by reference to track that variable later after callee is
done, I know that it'd be said to pass it by value and that makes
total sense for primitive types with a size equal to or smaller than
size of pointer; but I'm curious that from an assembly
point(performance-wise or space-wise), wouldn't be there a situation
when passing a variable of a primitive type with a size bigger than
pointers like long double on my platform which has a size of 8 bytes
and is bigger than pointers that have a size of 4 bytes; by reference
would be more efficient?
If in this specific case, passing by reference might ever be more
efficient, how can we know to pass by reference or value ?

I would assume that, yes, passing some primitives by pointer or
reference would be more efficient if they were larger than a pointer
or reference.

But when coming up with coding guidelines, consistency is very
important. As a general rule, for arguments that are not modified for
the caller to see, I pass classes by const reference and primitives by
value. Taking into account the above, which I think is micro
optimization, would lead to complicated rules with very little, if
any, performance benefit. Also, how would one handle code that is to
be compiled on different platforms that may have different sizes of
primitive types and hence have different "most efficient" ways to pass
them as args?

HTH
 
G

Good Guy

I would assume that, yes, passing some primitives by pointer or
reference would be more efficient if they were larger than a pointer
or reference.

But when coming up with coding guidelines, consistency is very
important.  As a general rule, for arguments that are not modified for
the caller to see, I pass classes by const reference and primitives by
value.  Taking into account the above, which I think is micro
optimization, would lead to complicated rules with very little, if
any, performance benefit.  Also, how would one handle code that is to
be compiled on different platforms that may have different sizes of
primitive types and hence have different "most efficient" ways to pass
them as args?

HTH

In this scenario I do like you also that is passing primitives by
value and objects of classes bigger than 8 bytes(long double on my
platform has a size of 8 bytes) by either constant reference or
pointer to constant. But I'm wondering wouldn't be a guidline out
there discussing this issue even if that's a matter of as you say
micro-optimization for a C++ programmer ? After all this issue can
have impact on the way the job is done and on final machine code.
 
Ö

Öö Tiib

In this scenario I do like you also that is passing primitives by
value and objects of classes bigger than 8 bytes(long double on my
platform has a size of 8 bytes) by either constant reference or
pointer to constant. But I'm wondering wouldn't be a guidline out
there discussing this issue even if that's a matter of as you say
micro-optimization for a C++ programmer ? After all this issue can
have impact on the way the job is done and on final machine code.

This is not optimization. Pushing 4 bytes instead of 8 to stack is
quicker. Using 8 bytes (double) referenced by 4 bytes (location of
double) referenced by 4 bytes (location of parameters in stack) is
slower. So you win nothing if you plan to use that double in your
function. If you don't use it in function then proper optimization is
to remove that parameter at all ... instead of passing it by
reference.
 
G

Good Guy

This is not optimization. Pushing 4 bytes instead of 8 to stack is
quicker. Using 8 bytes (double) referenced by 4 bytes (location of
double) referenced by 4 bytes (location of parameters in stack) is
slower. So you win nothing if you plan to use that double in your
function. If you don't use it in function then proper optimization is
to remove that parameter at all ... instead of passing it by
reference.

In some cases I think it might be possible to load the pointer
directly into some register and thus no difference in terms of speed
if the long double variable was pushed into callee stack frame itself
since there's stack frame pointer after all and one level of
derefrencing required to use the long double variable even if it was
passed by value, of course I know that the long double variable could
have been loaded into some register itself.
 
G

Good Guy

However, it could be that the sizeof the object (say a string) is
actually 8 bytes or less, while the cost of copying the object might
require an allocation of considerably more bytes along with copying
them. Might that be a good criterion? In other words, if making a copy
of the object could result in memory allocated on the heap, then pass by
const reference, otherwise pass by value?

I'm not a big fan of worrying about such micro-optimizations, or
micro-pessimizations for that matter. I would rather simply pass by
value until, and unless it is shown that copying is causing a
performance issue. If it is causing an issue, then pass by const
reference.

The thing is I'm thinking of a tool that may be of use in this case
and could analyze the matter and with its knowledge of assembly tell
what will be the difference in terms of any efficiency dimension
between two methods of passing by reference and by value in our code
but I don't know if such thing exists at all.
 
J

Jorgen Grahn

However, it could be that the sizeof the object (say a string) is
actually 8 bytes or less, while the cost of copying the object might
require an allocation of considerably more bytes along with copying
them. Might that be a good criterion? In other words, if making a copy
of the object could result in memory allocated on the heap, then pass by
const reference, otherwise pass by value?

I'm not a big fan of worrying about such micro-optimizations, or
micro-pessimizations for that matter. I would rather simply pass by
value until, and unless it is shown that copying is causing a
performance issue. If it is causing an issue, then pass by const
reference.

What worries me about that approach is, how will I ever notice? If
copy constructors inline, and I pass a great many different types by
value, I'll have an overhead smeared out over much of the application
and invisible.

I do what I think most people do: pass primitive types by value and
class types by const reference.

Sometimes I have a whole family of obviously tiny class types, and
then I pass these by value too. (But then I do that for the /whole/
family, even if some of them might be slightly larger or slightly more
expensive to copy than a pointer.)

/Jorgen
 
G

Goran

The thing is I'm thinking of a tool that may be of use in this case
and could analyze the matter and with its knowledge of assembly tell
what will be the difference in terms of any efficiency dimension
between two methods of passing by reference and by value in our code
but I don't know if such thing exists at all.

I am sorry, but I think that you are way off with your reasoning and
that you should simply stop. For example, locality of reference easily
beats any data/code size consideration in this simple case (meaning
that I think that a copy will be faster). But that is pure
speculation, mine argument, and your, too.

BTW, the tool that does what you are thinking about is a profiler. I
don't see how some static code analysis tool would do better,
particularly due to hardware effects.

Did you try to measure any of this on your actual code and data? That
would have been much more telling (without being general, but IMO any
general advice is not really possible).

On top of that, I think that you are massively in the land of micro-
optimization and premature optimization. I never optimize until I know
that I need to go faster, and even then, I am looking for "hot" spots.
Details like the one you evoke are last I'd look into.

Goran.
 
W

werasm

In a scenario that a caller function needs to pass one of its local
variables of a primitive type to a callee and doesn't necessarily need
to pass it by reference to track that variable later after callee is
done, I know that it'd be said to pass it by value and that makes
total sense for primitive types with a size equal to or smaller than
size of pointer; but I'm curious that from an assembly
point(performance-wise or space-wise), wouldn't be there a situation
when passing a variable of a primitive type with a size bigger than
pointers like long double on my platform which has a size of 8 bytes
and is bigger than pointers that have a size of 4 bytes; by reference
would be more efficient?
If in this specific case, passing by reference might ever be more
efficient, how can we know to pass by reference or value ?

In some cases passing by reference might be more efficient
(micro optimization), but then you loose that benefit as soon
as you perform indirection to get the value again. Pointless
IMHO.

Regards,

Werner
 
Ö

Öö Tiib

In some cases I think it might be possible to load the pointer
directly into some register and thus no difference in terms of speed
if the long double variable was pushed into callee stack frame itself
since there's stack frame pointer after all and one level of
derefrencing required to use the long double variable even if it was
passed by value, of course I know that the long double variable could
have been loaded into some register itself.

Seems, that you started to think in right direction. You can not
exactly predict and affect what happens on machine code level. Keyword
"register" is ignored by modern compilers, keyword "inline" means
merely that you may put function definition into header without
getting linker errors about duplicate symbols. It is compilers
playground to optimize such things by using registers to carry
parameters or by inlining functions. Therefore we are possibly talking
about a parameter that will be not passed at all. Compiler may
optimize if observable behavior of compiled program remains conforming
with standard.

If you are interested about performance then arrange yourself a good
profiler and you will soon see that places where majority of the
running time goes are elsewhere (dynamic allocation, inefficient
algorithms, various I/O, clumsy multihreading etc).
 
J

Joshua Maurice

This is not optimization. Pushing 4 bytes instead of 8 to stack is
quicker. Using 8 bytes (double) referenced by 4 bytes (location of
double) referenced by 4 bytes (location of parameters in stack) is
slower. So you win nothing if you plan to use that double in your
function. If you don't use it in function then proper optimization is
to remove that parameter at all ... instead of passing it by
reference.

I think we have different definitions of optimization. Worrying about
any kind of runtime performance speed is optimization (of runtime
performance). To use an example, picking the correct algorithm based
on Big-O analysis is optimization.

However, I do agree that worrying about such micro-optimization
without the backing of a profiler is often a waste of time and often
results in code obfuscation.
 
I

Ian Collins

Too true. The thing to do is write your code so that converting from
pass by value to pass by const reference (or the other way around,) is
painless.

Isn't it rather hard to do the opposite??
 
G

Good Guy

I am sorry, but I think that you are way off with your reasoning and
that you should simply stop. For example, locality of reference easily
beats any data/code size consideration in this simple case (meaning
that I think that a copy will be faster). But that is pure
speculation, mine argument, and your, too.

BTW, the tool that does what you are thinking about is a profiler. I
don't see how some static code analysis tool would do better,
particularly due to hardware effects.

Did you try to measure any of this on your actual code and data? That
would have been much more telling (without being general, but IMO any
general advice is not really possible).

On top of that, I think that you are massively in the land of micro-
optimization and premature optimization. I never optimize until I know
that I need to go faster, and even then, I am looking for "hot" spots.
Details like the one you evoke are last I'd look into.

Goran.

Gotta check out see how profiler might help.
 
G

Good Guy

In some cases passing by reference might be more efficient
(micro optimization), but then you loose that benefit as soon
as you perform indirection to get the value again. Pointless
IMHO.

Regards,

Werner

there's stack frame pointer and one level of derefrencing required to
use the variable passed by value to stack frame of callee as far as I
know.
 
G

Good Guy

I think we have different definitions of optimization. Worrying about
any kind of runtime performance speed is optimization (of runtime
performance). To use an example, picking the correct algorithm based
on Big-O analysis is optimization.

However, I do agree that worrying about such micro-optimization
without the backing of a profiler is often a waste of time and often
results in code obfuscation.

Nice point.
 
Ö

Öö Tiib

I think we have different definitions of optimization. Worrying about
any kind of runtime performance speed is optimization (of runtime
performance). To use an example, picking the correct algorithm based
on Big-O analysis is optimization.

The answer was about OP problem what is quicker, there you have
difference of fraction of nanosecond in either direction if at all,
but it may matter within innermost loop of most used function in your
application.
However, I do agree that worrying about such micro-optimization
without the backing of a profiler is often a waste of time and often
results in code obfuscation.

I actually constantly optimize my code towards more readable and
simple. One parameter less is simpler. One indirection less is
simpler. Normal member function instead of virtual is simpler. etc.
Simplicity saves time when reading the code. These are also often
running quicker.
 
W

werasm

there's stack frame pointer and one level of derefrencing required to
use the variable passed by value to stack frame of callee as far as I
know.

I might be wrong, but "passing by reference" is probably
implemented by passing a pointer by value and some
syntactical sugar. This (pointer) value then has to be dereferenced
to get the address, and that address has to be dereference to get
the real value. This is still one more indirection.

Regards,

Werner
 
M

Maxim Yegorushkin

In a scenario that a caller function needs to pass one of its local
variables of a primitive type to a callee and doesn't necessarily need
to pass it by reference to track that variable later after callee is
done, I know that it'd be said to pass it by value and that makes
total sense for primitive types with a size equal to or smaller than
size of pointer; but I'm curious that from an assembly
point(performance-wise or space-wise), wouldn't be there a situation
when passing a variable of a primitive type with a size bigger than
pointers like long double on my platform which has a size of 8 bytes
and is bigger than pointers that have a size of 4 bytes; by reference
would be more efficient?
If in this specific case, passing by reference might ever be more
efficient, how can we know to pass by reference or value ?

Depends on the calling conventions of your platform.

For example, on x86-64 Linux the first 6 arguments are passed in
registers and objects of different sizes are passed either directly in
registers or pushed on the stack when passing by value. In this
environment it makes sense to pass by value to reduce the number of
instructions the callee has to perform to load the argument in a
register(s).

There are other advantages in passing by value in C++.
http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/
 

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

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top