传递引用的开销是多少?

Sir*_*lot 7 c++ performance coding-style reference pass-by-reference

当有问题的getter返回引用时访问成员变量有多贵?

例如,如果你有一个需要经常使用这种访​​问器的类,那么将所述引用存储在需要使用它的类中并简单地初始化一次会有多高效?

Pub*_*bby 5

获取函数通常不应返回引用.这样做的原因是它使该成员对公众开放 - 如果你想这样做只是让它成为一个公共成员.

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

无论如何,如果它很简单,get_bar它将被内联到类似的东西foo.bar.正如Oli指出的那样,你也可以把它作为const引用,虽然对于像int你这样的小类型你应该继续并按值返回.

对于更昂贵的类型,参考开始是有益的.你可以假设:

  • 价值的"开销"基于您返回的大小
  • 参考的"开销"基于参考的大小和解除引用的成本

例如:

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

  • 你总是可以返回一个`const int&`.但更重要的一点仍然是,它将内部结构与界面相结合.(我不打算给这个+1,因为它没有回答这个问题......) (3认同)

jus*_*tin 5

关于复杂性,返回或传递引用就像传递指针一样。它的开销相当于传递一个指针大小的整数,外加一些指令。简而言之,这几乎在每种情况下都尽可能快。小于或等于指针大小的内置类型(例如int,float)是明显的例外。

最糟糕的是,传递/返回引用可能会添加一些指令或禁用某些优化。这些损失很少超过按值返回/传递对象的成本(例如,即使对于非常基本的对象,调用复制构造函数+析构函数的成本也要高得多)。除非每条指令都计数,并且您已测量了该差异,否则按引用传递/返回是一个很好的默认值。

因此,使用引用具有极低的开销。

在不知道类型及其构造函数/析构函数的复杂性的情况下,无法真正量化它速度,但是如果它不是内置类型,那么在大多数情况下,保持局部并通过引用返回将是最快的-所有这些都取决于对象及其副本的复杂性,但是只有极少的琐碎对象才能接近引用的速度。