Sod*_*der 0 c++ performance const function pass-by-reference
将参数传递给将在短时间内调用数百万次的函数和方法时,传递所述参数的开销开始显示.
void foo(const SomeType&st){...}
对于像std :: string,std :: vector等类型...规则是通过引用传递,以便不会发生无意义的副本.然而,当处理诸如双打,英特等的POD时,故事却完全不同.
关于性能,如果函数/方法不需要改变参数,在决定是否应该通过引用,const引用或复制传递时,常见的"需要注意的事项"是什么?
void foo1(SomeType& st)
{
...
}
void foo2(const SomeType& st)
{
...
}
void foo3(SomeType st)
{
...
}
void foo4(SomeType* st)
{
...
}
Run Code Online (Sandbox Code Playgroud)
注意:这不是关于const正确性的问题.还在32/64位平台上寻找与gcc和msvc相关的答案.
一些可能相关的问答:
最好的答案是让您阅读平台中的调用约定,但一般来说,对于小类型(适合寄存器或有时稍微大一些),通过值传递通常会更快.当您通过指针或引用指针是按值传递,这将具有复制原始对象相同的成本,再加上它需要解引用.
当对象变大时,复制指针和取消引用的成本通常会小于复制大对象的成本,因此您应该使用引用.如果您不打算修改对象,请传递const&
.
是否应该通过副本传递int/unsigned int?是否应该只在64位或更高目标上通过副本传递double?
即使在32位体系结构中,您也应该按值传递整数和双精度数.再次,查看您的体系结构的调用约定(通常用编译器记录).
如果函数可以内联 - 参数如何在物质中传递?
如果函数是内联的,则编译器可以对其进行优化,并且例如通过替换对原始对象的引用的使用来移除引用的成本.
当通过ref/const ref传入时,别名如何影响问题?
如果您不打算修改参数(正如您在问题中声明的那样),则别名无关紧要.如果传递可以以算法不期望的方式修改的指针/引用,则会出现别名问题.
在什么情况下,参数的显式副本在堆栈上是有益的?
忽略堆栈部分:当对象很小时.请注意,使用的调用约定甚至可能不使用堆栈(它可能会传递寄存器中的值).我建议你阅读这篇关于不同调用约定的文章