开发者

May a reference be more efficient than a pointer?

I'm wondering whether sometimes (depends on the platform or compiler or context in code etc) a reference can be more efficient than a po开发者_C百科inter?


May a reference be more efficient than a pointer?

Nopes! Not necessarily. The Standard doesn't say that either.

Most compilers implement reference mechanism via use of pointers. References were added to C++ to support operator overloading and not for efficiency.


Yes, it may. The only way we could say "it can't" is if there were a requirement (explicit or implied) in the standard that references be as slow or slower than equivalent pointers in all cases. There is no such requirement, since the standard doesn't concern itself with that kind of performance detail.

For example, at low optimization levels it would be reasonable for this:

int n = 0;
int *np = &n;
for (int i = 0; i < 10000000; ++i) {
    *np += i;
}
std::cout << n;

to be a little slower than this:

int n = 0;
int &nr = n;
for (int i = 0; i < 10000000; ++i) {
    nr += i;
}
std::cout << n;

simply because it's a little easier in the first case for the compiler to detect that it can avoid the indirection entirely - nr is explicitly an alias for n everywhere it is in scope, whereas *np just so happens to remain an alias for n because we never assign to np after it is initialized. The result with low optimization might well be more indirection in the pointer case and a less efficient loop.

Take a look at the code your compiler emits, though - gcc with no optimization emits the same code for me, it looks to have spotted the alias in both cases and is using a register for the total and a stack slot for i.

Of course you'd expect a good optimizing compiler to "understand" the aliasing in both cases, and emit code that stores n in a register, and only touches that register (not memory) in the loop.


You can pass NULL to the pointer, therefore you have to check if the pointer variable is NULL. That is the only reason why the reference is bit more efficient.

Other then that, compilers are implementing references as pointers.


Yes, references can be more efficient than pointers. The reason lies in optimizers. In general, one of the most expensive operations in a modern CPU is a load from memory. And after you've called a (non-inlined) function, the compiler must assume that any variable in memory that could change, did change. That means that in the following example, it must reload p after calling Bar():

class Foo {
  int* p;
  void Bar(); // defined somewhere else, not visible to compiler.
public:
  Foo() { p = new int; Bar(); std::cout << *p; }
};

Now, the issue here is not that *p must be reloaded, but that p must be reloaded. It too could chance. Now look at the following code:

class Foo {
  int* p; // !
  void Bar(); // defined somewhere else, not visible to compiler.
public:
  Foo() { p = new int; int& r = *p; Bar(); std::cout << r; }
};

Now, the compiler sees that p isn't used after Bar(). r is, and it's probably implemented as a pointer. But it can't be reasssigned! Therefore, the optimizer has the option of saving r across the function call.


C++ References work like "permanently dereferenced" pointers under the hood. I would expect the performance to be the same. However since a reference's pointee can't be reassigned the compiler might be able to apply more optimizations that can't be used for raw pointers.


Nothing can be more efficient than a pointer, save for direct access. But speed is not why references exist.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜