【问题标题】:Reasons to not pass simple types by reference?不通过引用传递简单类型的原因?
【发布时间】:2012-05-26 23:03:23
【问题描述】:

据我了解,您不应该在 c++ 中通过引用传递简单类型,因为它不会提高性能,甚至对性能不利(?)。至少这是我设法从网上收集到的。

但我找不到原因为什么它对性能不好,是因为 c++ 创建一个新的简单类型比它更快地查找变量或什么是是吗?

【问题讨论】:

  • 即使没有任何“性能”考虑,引用参数也会改变调用语义...
  • 如果通过常量引用传递,我希望这是编译器优化(编译器会将其转换为按值传递)。

标签: c++ performance


【解决方案1】:

如果你创建一个引用,它是:

pointer to memory location -> memory location

如果你使用一个值,它是:

memory location

由于必须以任何一种方式(引用或值)复制值,因此通过引用传递不会提高性能;必须进行一次额外的查找。所以理论上它会“恶化”性能,但不会有任何你会注意到的程度。

【讨论】:

  • 这是一个误导性的答案。 “因为必须以任一方式复制值”。通过 ref 传递不会导致复制值,而是在同一对象上使用指针操作。所以传递double 意味着创建double 的副本(如果它是左值)并在函数中使用该副本。传递引用意味着您将指针传递给函数并在使用值时执行解引用,但不将 var 放入堆栈。如果你有一个带有 ref arg 的函数调用另一个带有值 arg 的函数,那么只有第二个函数会在堆栈上分配 var。
  • @AdamHunyadi:通过引用传递会导致指针被复制(直至优化)。这就是我所说的“价值”。 (您可以通过阅读您引用的部分之后的括号来判断。)
【解决方案2】:

这是一个很好的问题,您提出这个问题表明您正在关注您的代码。不过,好消息是,在这种特殊情况下,有一个简单的出路。

Dave Abrahms 的这篇优秀文章回答了您的所有问题,然后回答了一些问题:Want Speed? Pass by Value.

老实说,总结它并没有做到链接公正,这是一个真正的必读。但是,长话短说,您的编译器足够聪明,可以正确执行,如果您尝试手动执行,您可能会阻止编译器进行某些优化。

【讨论】:

【解决方案3】:

内部引用在指针处处理,每次访问它们时都需要取消引用。这显然需要额外的操作。

【讨论】:

  • 引用不是指针。您也不应该将引用视为指针(它只会让思考它们变得更加困难)。
  • 我可以同意在本地范围内创建的引用,但是将东西作为引用传递给方法呢?如果您不按值传递(阅读:将副本放在堆栈上),那么您唯一的选择是将指针传递给引用的对象。您必须通过堆栈或寄存器传递一些东西,因此它必须是整个值或指向它的指针。而且由于引用显然不是整个值,它们必须是指针。我更喜欢以 C# 和 Java 的“它简单地工作”的方式来考虑它们,但在内部它们就像自动取消引用的指针一样工作。
  • 您现在正在将语言结构(指针/引用)映射到实现细节上。这更没用了。
  • 问题是为什么简单的类型不应该通过引用传递。除了实现细节之外,没有理由不通过引用传递东西。不这样做的原因(除了不允许函数修改传入的原始变量)是由于实现细节而导致速度变慢。
  • 然后根据实现细节写下你的答案。不是您对引用如何工作的错误看法。
【解决方案4】:

例如,在 32 位模式下,int 大小为 4 字节,int * 指针大小为 4 字节。 直接传递 4 字节 int 比传递 4 字节指针然后通过该指针加载 int 更快。

【讨论】:

  • @Loki Astari:某些配置中的参数总是从内存中加载(应该是指针还是值),但是如果是指针,那么将会从内存中再次加载,情况并非如此值本身作为参数传递。
猜你喜欢
  • 1970-01-01
  • 2011-05-18
  • 2012-05-01
  • 2015-02-22
  • 2019-05-18
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
相关资源
最近更新 更多