简体   繁体   中英

what is the overhead of passing a reference?

how expensive is it to access a member variable when the getter in question return a reference?

for example, if you have a class that needs to use such an accessor fairly often, how much more efficient would it be to store said reference in the class that needs to use it and simply initialise it once?

Get functions generally shouldn't return references. The reason for this is that it makes the member available to the public - if you want to do this just make it a public member.

class foo {
  int bar;
  public:
    int& get_bar() { return bar; } // this is silly! Just make bar public!
}

Anyway, if it's as simple as get_bar it will be inlined to something akin to foo.bar . As Oli noted, you could also make it a const reference, although for small types like int you should go ahead and return by value.

With more expensive types, references start to be beneficial. You can assume that:

  • Value's 'overhead' is based on size of what you're returning
  • Reference's 'overhead' is based on size of reference and cost to dereference

Eg:

foo x;
x.get_value().func(); // calls copy constructor at least once and destructor
x.get_reference().func(); // may require dereference when using

Regarding complexity, returning or passing a reference is just like passing a pointer. Its overhead is equivalent to passing an integer the size of a pointer, plus a few instructions . In short, that is as fast as is possible in nearly every case. Builtin types (eg int, float) less than or equal to the size of a pointer are the obvious exception.

At worst, passing/returning a reference can add a few instructions or disable some optimizations. Those losses rarely exceed the costs of returning/passing objects by value (eg calling a copy constructor + destructor is much higher, even for a very basic object). Passing/returning by reference is a good default unless every instruction counts, and you have measured that difference.

Therefore, using references has incredibly low overhead.

One can't really quantify how much faster it would be without knowing the complexity of your types and their constructor/destructor, but if it is not a builtin type, then holding a local and returning it by reference will be fastest in most cases - it all depends on the complexity of the object and its copy, but only incredibly trivial objects could come close the speed of the reference.

If the function definition is available and is relatively simple, then such a function is getting inlined and there is no overhead whatsoever compared to accessing a member directly. Otherwise the sequence of operations is as simple as getting the address a class/structure object, applying an offset to get an address of the member, and returning this address to the caller. Now, for those cases it makes sense to return by reference only if object is non-copyable or its size is greater than the size of a pointer. The reason for non-copyable objects is obvious, otherwise you look at copying overhead - size of structure versus size of a pointer. So the rule of thumb is this - return large objects by reference (or pointer), and small objects (integers, doubles, etc.) by copying them. And in those cases where you do not have to control access rights to members trough-out your program - simply use structures with public access to members and do not bloat your code with tons of getters and setters.

Frankly, if you start wondering about this overhead: have you already thought about calling conventions, using stdcall instead of cdecl?

The amount of speed you gain from that is similar to what you're talking about when discussing this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM