Reputation: 93274
Consider this code:
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;
}
Between getCopy1
and getCopy2
, what one:
?
Upvotes: 1
Views: 4611
Reputation: 93274
Ran some tests, with G++ 4.8.1 on Linux Mint x64.
Flags: -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;
}
Output:
[getCopy1 variable] 1236 ms
[getCopy1 literal] 1845 ms
[getCopy2 variable] 993 ms
[getCopy2 literal] 857 ms
Conclusion:
getCopy2
is faster, especially with rvalues (literal strings).
Upvotes: 3
Reputation: 5127
getCopy2
can be often better optimized. This is neatly explained in "Want Speed? Pass by Value."
Upvotes: 2
Reputation: 64308
Either version clearly shows there is no intent to modify the value that is passed in.
getCopy2
is more efficient in the case where an rvalue is being passed as the parameter. In that case, no copy needs to be done, since the parameter will be moved instead of copied, and you are doing no internal copying. For getCopy1
, you always force at least one copy to be made. If an lvalue is being passed as the parameter, then a move needs to be done instead of creating a reference. Which is more efficient depends on a lot of details of the compiler and the string implementation, but the speed of the move should be comparable to the speed of creating a reference.
I don't see any difference as far as the return value.
Upvotes: 4
Reputation: 27365
Between getCopy1 and getCopy2, what one:
- Clearly shows that the passed string isn't going to get modified
Both: first, because although it takes a reference, the reference is const
; second, because it creates it's own copy.
- Clearly shows that the user will get a new string returned
Both: they both return a string instance;
- Is faster / can be better optimized by the compiler (C++11 enabled, consider move semantics)
The second is better to use: if you are making a copy of the input parameter, better do it in the parameter itself (better let the compiler make the copy, on call); It is also better because in the case of a rvalue reference, there is no extra copy done.
Upvotes: 3