tomsseisums
tomsseisums

Reputation: 13367

Are there any performance gains when creating new variable passed by reference vs. passed by value?

I'm not interested in concrete values, but just theoretical answers.

  1. For example, in loops when we need to use the same values over and over, would it work faster if values would be passed by reference instead of value?

  2. And what about objects? Assuming that our object contains some values for this specific instance of an object. Instead of instantiating new object, can we pass it by reference to gain performance wise? Or should we clone it?

I hope I've made myself clear, thanks in advance.

Upvotes: 0

Views: 243

Answers (5)

Trott
Trott

Reputation: 70125

If all you are interested in is performance, then as a general rule, pass by reference performs better than pass by value.

Upvotes: 1

Nemo
Nemo

Reputation: 71555

The general rule on modern CPUs is "math is fast, memory is slow".

If you are talking about C++, passing integers, floats, and even small objects by value is likely to be faster. Pass-by-reference can prevent a variety of compiler optimizations thanks to aliasing concerns.

For larger objects, passing by reference will be faster. (Definitely do not clone them, because memory is slow.)

The real answer to this question, though, is to write your code in a natural, straightforward way, and do not worry about this sort of question until your profiler tells you to.

[update, to elaborate on the aliasing problem]

For example, consider the following two functions:

void
foo1(int a, int b, int &c, int &d)
{
    c = a + b;
    d = a - b;
}

void
foo2(const int &a, const int &b, int &c, int &d)
{
    c = a + b;
    d = a - b;
}

With optimization enabled, my compiler (gcc 4.5.2, x86_64) produces this code for foo1:

leal    (%rsi,%rdi), %eax
subl    %esi, %edi
movl    %eax, (%rdx)
movl    %edi, (%rcx)
ret

...and this for foo2:

movl    (%rsi), %eax
addl    (%rdi), %eax
movl    %eax, (%rdx)
movl    (%rdi), %eax
subl    (%rsi), %eax
movl    %eax, (%rcx)
ret

Your compiler will do something similar. The problem is that in foo2, "c" or "d" might refer to the same memory location as "a" or "b", so the compiler has to insert extra loads/stores to worry about that case.

This is a trivial example, but more complex ones show similar behavior. For simple types and even small structs, pass by value usually results in faster code.

Upvotes: 3

Ted Hopp
Ted Hopp

Reputation: 234847

It depends on the language and the implementation. Generally, passing by reference is faster because all you have to pass is an address (a pointer). For data types smaller than a pointer, there may be a small savings in memory and/or time to pass the value. However, in most language copying even a small object would require the call to a copy constructor of some kind, which would kill any possible savings. On the other hand, passing by reference creates an object or variable alias, which in some languages can be a problem. Also, in some languages you can't pass a compile-time constant by reference; the compiler turns a call func(1) into something like int _1 = 1; func(_1).

I should also mention that in some languages (like Java) it is impossible to pass an object by value or a primitive type by reference. For those languages, of course, your question is moot.

Upvotes: 1

James
James

Reputation: 8586

Pass by value copies the value - if it's a small primitive - say, int, it's not much going to matter - you either copy the int on to the stack to make the call, or you copy its address (same size, roughly, so no real gain).

For a large non-trivial object, pass by value will be much more costly - you build a new copy of that object.

It's unclear what you mean about the loop - PBV/PBR will mainly only matter during function calls.

Upvotes: 1

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81724

Absolutely. Pass-by-reference is virtually always a big win, especially for class types where a nontrivial constructor and destructor must run. The only times where you could expect pass-by-value to win might be for passing data smaller than a pointer -- individual characters, for example -- and even then, it'd be a very hardware-specific argument.

Upvotes: 1

Related Questions