通过引用传递原始类型会适得其反吗?

use*_*112 17 c++

可能重复:
基于数据类型传递值或引用是否更好?
没有通过引用传递简单类型的原因?

我做了一些测试,其中我有两个场景,每个场景有两个相同的功能 - 一个通过引用传递参数,另一个通过值传递.带有字符串的场景显示了大量的性能提升(因为创建了一个字符串的副本,调用了构造函数),而使用long的测试在通过引用传递值时没有显示任何性能提升.事实上,有时表现更差.

这是原始类型的预期吗?没有必要通过引用传递它们吗?

我期待在不使用引用的情况下制作原始类型的副本,因此期望小的性能提升.

Ben*_*igt 29

通过值传递基元类型可以获得最佳性能.这是因为:

  • 原语是可以浏览的,因此副本的成本取决于大小
  • 在大多数环境中,原语只是小double而且long long比参考大
  • 按值传递可以避免别名,允许优化器真正做到这一点

最后一点经常被忽视,但可以产生相当大的差异.


Som*_*ame 8

是的,这是预期的行为.当您通过引用传递参数时,实际上是在传递变量的地址(就像使用指针一样).通常地址是一个4或8字节的整数,所以除非你的原始类型大于那个,否则你不会获得任何性能提升(即使它更大,你可能不会)


Mat*_*son 5

现代编译器非常聪明,因此,如果函数不是“隐藏的”(也就是说,在生成代码时编译器看不到的一部分),那么它可能根本就没有任何区别。但是,如果编译器遵循您的指令,则将简单类型作为引用传递可能会带来很大的不同。特别是如果该值在代码中多次更新。

我在工作的地方看到了一些代码,该代码是这样的:

void SomeClass::FindLength(int &len)
{
     listEntry* list = theList;   // theList is a member variable. 
     len = 0;
     while (list)
     {
         len++;
         list = list->next;
     }
 }
Run Code Online (Sandbox Code Playgroud)

通过更改代码来执行以下操作:

void SomeClass::FindLength(int &len)
{
     listEntry* list = theList;   // theList is a member variable. 
     int tempLen = 0;
     while (list)
     {
         tempLen++;
         list = list->next;
     }
     len = tempLen;
 }
Run Code Online (Sandbox Code Playgroud)

整个代码的运行速度提高了约30%,并在很多地方调用(我认为中间有一些if条件,因此我们不能只跟踪长度)。并且由于它是API函数的一部分,因此无法更改函数签名。

使用该引用的速度较慢的原因是,每次更新时,编译器都会写入该引用值,这是从内存到寄存器,增量寄存器和存储寄存器到内存的负载。通过该tempLen解决方案,编译器可以使用寄存器,该寄存器要快得多。


kas*_*sak 4

在 C++ 中,引用只是使用指针的便捷方式。当您使用指针时,您会添加额外的间接寻址。复制基本类型与复制指针一样便宜。这就是为什么通过引用传递的基本类型有点慢