0
votes

When passing parameters to functions and methods that will be called millions of times in a short amount of time, the overhead of passing said parameters begins to show.

void foo(const SomeType& st) { ... }

For types like std::string, std::vector etc... the rule is to pass by reference so that pointless copies don't occur. However when dealing with PODs such as doubles, ints etc, the story is quite different.

With regards to performance, If the function/method does not need to mutate the parameters, what are the common 'things to look out for' when deciding if one should pass by reference, const reference or copy?

void foo1(SomeType& st)
{
   ...
}

void foo2(const SomeType& st)
{
   ...
}

void foo3(SomeType st)
{
   ...
}

void foo4(SomeType* st)
{
   ...
}
  • Should an int/unsigned int always be passed by copy?
  • Should a double be passed by copy only on 64-bit or higher targets?
  • If the function can be inlined - does how the parameters are passed in matter?
  • How does aliasing affect problems when passing in by ref/const ref?
  • Under what circumstance would a explicit copy of the parameter be beneficial on the stack?

Note: This is a not a question about const-correctness. Also looking for answers relating to gcc and msvc on 32/64-bit platforms.

Some possibly related Q/As:

"const T &arg" vs. "T arg"

https://stackoverflow.com/a/2139254/754951

Pass by Reference / Value in C++

Why pass by const reference instead of by value?

1

1 Answers

6
votes

The best answer is for you to read the calling conventions in your platform, but in general, for small types (those that fit in a register or even sometimes slightly bigger), it will usually be faster to pass by value. When you pass by pointer or reference a pointer is passed by value, which will have the same cost of copying the original object, plus it will require dereferences.

When the objects become big then the cost of copying the pointer plus the dereference will usually be smaller than the cost of copying a large object, so you should use references. If you don't intend to modify the object, pass const&.

Should an int/unsigned int always be passed by copy? Should a double be passed by copy only on 64-bit or higher targets?

Even in 32bit architectures you should pass ints and doubles by value. Again, look at the calling conventions for your architecture (usually documented with the compiler).

If the function can be inlined - does how the parameters are passed in matter?

If the function is inlined the compiler can optimize it, and will for example, remove the cost of the reference by substituting the uses of the reference for the original object in place.

How does aliasing affect problems when passing in by ref/const ref?

If you are not going to modify the argument (as you claim in the question) aliasing will not matter. You will have aliasing problems if you pass pointers/references that can be modified in a way that the algorithm does not expect.

Under what circumstance would a explicit copy of the parameter be beneficial on the stack?

Ignoring the on the stack part: when the objects are small. Note that the calling convention used might not even use the stack (it might pass the value in a register). I recommend that you read this article on the different calling conventions