考虑以下代码:
void doSomethingWithString(string& mString)
{
// mString gets modified in here
}
string getCopy1(const string& mString)
{
string result{mString}; doSomethingWithString(result); return result;
}
string getCopy2(string mString)
{
doSomethingWithString(mString); return mString;
}
之间getCopy1
和getCopy2
,什么人:
- 清楚地表明,所传递的字符串是不会得到修改
- 清楚地表明,用户将得到一个新的字符串返回
- 更快/可以更好的编译器优化(C ++ 11启用,考虑移动语义)
?
无论哪种版本清楚地表明,没有意图修改传入的值。
getCopy2
是在一个rvalue被作为参数传递的情况下更有效。 在这种情况下,没有复制需要做,因为参数将被移动而不是复制,和你正在做的没有内部复制。 对于getCopy1
,你总是迫使至少一个拷贝进行。 如果一个左值被作为参数传递,然后一招有待完成,而不是创建一个参考。 这是更有效取决于很多的编译器和字符串实现的细节,但移动的速度应当与创建引用的速度。
我看不出有什么区别,只要返回值。
getCopy1和getCopy2,东西之一:
两个:第一,因为虽然它需要一个参考,所述参考是const
; 第二,因为它创造了它自己的拷贝。
既:它们都返回一个字符串实例;
- 更快/可以更好的编译器优化(C ++ 11启用,考虑移动语义)
二是更好地使用:如果你正在输入参数的副本,做的更好的参数本身(最好让编译器进行复制,随叫随到); 这也是更好,因为在右值引用的情况下,也没有进行任何额外的副本。
了一些测试,对Linux Mint的64 G ++ 4.8.1。 国旗: -std=c++11 -O3 -DNDEBUG
void doSomethingWithString(string& mString) { mString[0] = 'f'; }
string getCopy1(const string& mString)
{
string result{mString}; doSomethingWithString(result); return result;
}
string getCopy2(string mString)
{
doSomethingWithString(mString); return mString;
}
int main()
{
string s{"132958fdgefi9obm3890g54"};
string t{""};
{
startBenchmark();
for(int i{0}; i < 20000000; ++i) t = getCopy1(s);
log(endBenchmark(), "getCopy1 variable");
}
{
startBenchmark();
for(int i{0}; i < 20000000; ++i) t = getCopy1("abcsd");
log(endBenchmark(), "getCopy1 literal");
}
{
startBenchmark();
for(int i{0}; i < 20000000; ++i) t = getCopy2(s);
log(endBenchmark(), "getCopy2 variable");
}
{
startBenchmark();
for(int i{0}; i < 20000000; ++i) t = getCopy2("abcsd");
log(endBenchmark(), "getCopy2 literal");
}
return 0;
}
输出:
[getCopy1 variable] 1236 ms
[getCopy1 literal] 1845 ms
[getCopy2 variable] 993 ms
[getCopy2 literal] 857 ms
结论:
getCopy2
速度更快,尤其是右值(文字字符串)。
getCopy2
可以更好地进行优化,经常。 这是在巧妙地解释“要速度?按值传递。”
文章来源: “std::string” or “const std::string&” argument? (the argument is internally copied and modified)