当应用于基元类型时,const通过引用调用是否会提高性能?

时间:2015-03-19 10:07:15

标签: c++ performance call-by-value

关于对象(尤其是字符串),通过引用调用比按值调用更快,因为函数调用不需要创建原始对象的副本。使用const,还可以确保不会滥用引用。

我的问题是,如果使用原始类型(如bool,int或double),const call-by-reference是否也更快。

void doSomething(const string & strInput, unsigned int iMode);
void doSomething(const string & strInput, const unsigned int & iMode);

我怀疑,只要原始类型的字节大小超过地址值的大小,就可以使用call-by-reference。即使差异很小,我也想利用它,因为我经常调用其​​中的一些功能。

其他问题:内联会对我的问题的答案产生影响吗?

5 个答案:

答案 0 :(得分:4)

  

我怀疑只要原始类型的字节大小超过地址值的大小,就有利于使用call-by-reference。即使差异很小,我也希望利用这一优势,因为我经常调用其​​中的一些功能。

基于预感的性能调整在C ++中大约占0%的时间(这是我对统计数据的直觉,它通常有效...)

正确const T&小于T if sizeof(T) > sizeof(ptr)是正确的,通常是32位或64位,具体取决于系统..

现在问问自己:

1)有多少内置类型大于64位?

2)是不是要复制32位值得使代码不太清楚?如果您的功能变得非常快,因为您没有将32位值复制到它,可能它不会做太多?

3)你真的那么聪明吗? (扰流警报:不。)看到这个伟大的答案,因为它几乎总是一个坏主意: https://stackoverflow.com/a/4705871/1098041

最终只是通过价值传递。如果在(彻底)分析之后你发现某个函数是一个瓶颈,并且你尝试的所有其他优化都不够(并且你应该在此之前尝试其中的大部分),那就是const-by-const-reference。

然后看到它没有改变任何东西。滚动和哭泣。

答案 1 :(得分:3)

除了其他答案,我还要注意,当你传递一个引用并在你的函数中使用(也就是取消引用)时,它可能比制作副本要慢。

这是因为函数的局部变量(通常)一起加载到缓存中,但是当其中一个是指针/引用并且函数使用它时,它可能导致缓存未命中。这意味着它需要转到(较慢的)主内存来获取指向变量,这可能比使用函数一起加载到缓存中的副本要慢。

即使对于小物件也是如此。通过价值传递可能会更快。

(我在非常好的书中读到了这一点:Computer Systems: a programmers perspective

关于整个缓存命中/遗漏主题的更有趣的讨论:How does one write code that best utilizes the CPU cache to improve performance?

答案 2 :(得分:2)

const是在编译时计算的关键字。它对运行时性能没有任何影响。您可以在此处阅读更多相关信息:https://isocpp.org/wiki/faq/const-correctness

答案 3 :(得分:2)

在64位架构上,没有原始类型---至少在C ++ 11中没有 - 它比指针/引用大。您应该对此进行测试,但直观地说,const T&int64_t应该有相同数量的数据,而sizeof(T) < sizeof(int64_t)的原始数据应该更少。因此,只要您可以测量任何差异,按值传递基元应该更快如果您的编译器正在做明显的事情 - 这就是为什么我强调如果你在这里需要确定性,你应该写一个测试用例。

另一个考虑因素是原始函数参数最终会出现在CPU寄存器中,这使得访问它们的速度与内存访问速度一样快。当const T&是基元时,您可能会发现为T参数生成的指令多于T参数。您可以通过编译器检查汇编器输出来测试它。

答案 4 :(得分:0)

我被教导了:

    当参数变量是基本内置类型之一时,
  • 按值传递,例如boolintfloat 。这些类型的对象非常小,以至于通过引用传递不会导致效率的任何提高。此外,如果您想制作变量的副本。

  • 如果要有效传递不需要更改的值,请传递常量引用。

  • 仅在您想要更改参数变量的值时传递引用。但是尽可能避免改变参数变量。