what is the overhead of passing a reference?

蓝咒 提交于 2019-12-05 04:45:46

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 (e.g. 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 (e.g. 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.

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

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!