views:

138

answers:

5

Maybe this is a compiler specific thing. If so, how about for gcc (g++)? If you use a variable reference/alias like this:

int x = 5;
int& y = x;
y += 10;

Does it actually require more cycles than if we didn't use the reference.

int x = 5;
x += 10;

In other words, does the machine code change, or does the "alias" happen only at the compiler level?

This may seem like a dumb question, but I am curious. Especially in the case where maybe it would be convenient to temporarily rename some member variables just so that the math code is a little easier to read. Sure, we're not exactly talking about a bottleneck here... but it's something that I'm doing and so I'm just wondering if there is any 'actual' difference... or if it's only cosmetic.

+4  A: 

The only way to know for sure is to compile it and examine the output of the compiler. Generally, the overhead for a reference is similar to the overhead for a pointer, because pointers are usually how references are implemented. However, given the simple case you're showing, I believe the reference would be optimized away.

Billy ONeal
Yeah, I may one day do some simple tests and see if it gets optimized out... for now, it's not too important.
cheshirekow
+5  A: 

It may be treated as an alias, but not in terms of efficiency. Underneath the hood, a reference is a pointer with a nicer syntax and higher safety guarantees. Hence you've got a "dereference" operation runtime penalty. UNLESS the compiler optimizes it, but I wouldn't count on that usually.

In case of the question of whether the compiler will optimize it or not, there's no other way than to look at the generated assembly.

Kornel Kisielewicz
Good answer. Thanks
cheshirekow
The answer is not exactly accurate. One of the intents behind references is to implement the concept of an alias, alternative name for an existing object. I believe this is explicitly stated in TC++PL. While this is not always the case, "alias" is still an accurate description of what references are in many cases.
AndreyT
@AndreyT, I never heard of the idea of references being aliases, can you state me the paragraph of the standard where that is implied?
Kornel Kisielewicz
@Kornel Kisielewicz: Stroustrup. TC++PL. 5.5. "A reference is an alternative name for an object".
AndreyT
Kornel: @Andrey clearly says he isn't referring to the standard. If you want to be pedantic about it: §8.3.2.1: *Note: a reference can be thought of as a name of an object.* Also known as an alias. The point is, a reference has behavior intended to represent an alias and is not dictated to be a pointer.
GMan
@GMan point taken, thank you, I edited the answer.
Kornel Kisielewicz
@AndreyT, likewise, point taken.
Kornel Kisielewicz
*higher safety guarantees* ? It's a matter of contract, nothing prevents you from having a null or dangling reference, the only difference with a pointer is that you can't reseat it.
Matthieu M.
A: 

Yes, dereferencing the pointer behind the reference incurs additional runtime costs, but is likely insignificant. Write the code in whatever way is clearest to read and most cleanly articulates the semantics you are aiming for, and then run in a profiler if performance is an issue (the bottleneck is rarely what you guess it is). If you are on MacOS, Shark is fantastic.

Simeon Fitch
Done. Like I said, just curious. Develop on Mac? ew... ;)
cheshirekow
Don't snub what you don't know! :-) The debugging and profiling tools are top notch and don't cost $$$.
Simeon Fitch
+3  A: 

It is true that in most cases references implement the concept of "alias", an alternative name for the object they are bound to.

However, in general case references are implemented through pointers. Nevertheless, a good compiler will only use an actual pointer to implement reference in situations when the actual binding is determined at run-time. If the binding is known at compile time (and the types match), the compiler will normally implement reference as an alternative name for the same object, in which case there will be no performance penalty for accessing the object through the reference (compared to accessing it through its original name).

Your example is one of those when you should expect no performance penalty from the reference.

AndreyT
+3  A: 

Both of these functions compile to exactly the same code in g++, even just using -O1. (I added the return statement to ensure that the calculation wasn't eliminated entirely.)

There is no pointer, only a reference. In this trivial example there was no performance difference. That's no guarantee that this would always be the case (no performance difference) for all uses of reference, though.

int f()
{
    int x = 5;
    x += 10;
    return x;
}

.

int f()
{
    int x = 5;
    int & y = x;
    y += 10;
    return y;
}

Assembler:

movl    $15, %eax
ret
Charles Bailey
Not sure this is a fair test, because as your results show, the entire body of the function can be evaluated at compile time.
Daniel Pryden
@Daniel Pryden: But that's the code that was asked about. Can you suggest a fairer test of the code?
Charles Bailey