Should I always pass a std::string by const reference to a function if all that is done inside that function is to copy that string? Additionally, what is the difference (perf or otherwise) between passing by value and passing by reference? As I understand, one uses operator=
and the other copy constructor. Is that the case?

- 14,063
- 21
- 79
- 118
-
4when you pass by reference, no copy is made. when you pass by value, copy constructor is used. – Anycorn Oct 11 '10 at 05:23
2 Answers
Don't believe everything you read on the internet. It is better to pass by const reference. To give proof, I wrote a test program...
test.cpp:
#include <ctime>
#include <iostream>
#include <string>
void foo(std::string s);
void bar(const std::string& s);
int main() {
const std::string s("test string");
clock_t start = clock();
for (int it = 0; it < 1000000; ++it)
foo(s);
std::cout << "foo took " << (clock() - start) << " cycles" << std::endl;
start = clock();
for (int it = 0; it < 1000000; ++it)
bar(s);
std::cout << "bar took " << (clock() - start) << " cycles" << std::endl;
}
aux.cpp:
#include <string>
std::string mystring;
void foo(std::string s) { mystring = s; }
void bar(const std::string& s) { mystring = s; }
Compiled with 'g++ -O3 test.cpp aux.cpp' and got the printout:
foo took 93044 cycles
bar took 10245 cycles
Passing by reference is faster by an order of magnitude.

- 349,597
- 67
- 533
- 578

- 25,185
- 9
- 78
- 101
-
1
-
With g++ 4.8.1 on x86_64 I get 4130 vs. 1820. The gap is closing. – John Kugelman Mar 19 '14 at 14:41
-
1With Clang 602 I see 22500 vs 17000 (appx., consistent). Gap is pretty much closed there. – Alex Celeste Aug 07 '15 at 15:46
-
4This test is misleading, since you are comparing the difference between making two copies vs one copy (obviously two is slower). The real claim about passing by value is that, if we are going to copy the argument, we should pass by value *and then move the parameter into the target*. So the body of `foo` should look like`mystring = ::std::move(s)`. I think you'll find the result far different in this case. – Ken Wayne VanderLinde Oct 11 '16 at 20:07
-
2So I tried Ken idea. const ref: ~12000 cycles. two copy: 16000 cycles. copy + move: ~12000 cycles. Then I tried with a long string and got: const ref: ~12000 cycles. two copy: 80000 cycles. copy + move: ~80000cycles. const ref seems to be consistently more efficient – Guillaume Gris Oct 11 '16 at 20:56
-
1@GuillaumeGris Forgive my scepticism, but those numbers do not sound correct. Are you certain you were performing a copy followed by a move? I will run the test myself to be sure, but it just doesn't sit right. The copy+move case should only be an extra pointer swap compared to the single copy of the const ref case, and I can't see that causing a 500-600% overhead. – Ken Wayne VanderLinde Oct 13 '16 at 02:26
Should I always pass a std::string by const reference to a function if all that is done inside that function is to copy that string?
No. If you are going to just copy the string inside of the function, you should pass by value. This allows the compiler to perform several optimizations. For more, read Dave Abraham's "Want Speed? Pass by Value."
What is the difference (perf or otherwise) between passing by value and passing by reference? As I understand, one uses operator= and the other copy constructor. Is that the case?
No, that is not at all the case. A reference is not an object; it is a reference to an object. When you pass by value, a copy of the object being passed is made. When you pass by reference, a reference to the existing object is made and there is no copy. A good introductory C++ book will explain these basic concepts in detail. It is critical to understand the basics if you want to develop software in C++.

- 1
- 1

- 348,265
- 75
- 913
- 977
-
I think it depends on what he means by making a copy. If it's to, say, a member then it should be passed as a reference and just copied to the member. In C++0x, do it by value and `std::move` it into the member. – GManNickG Oct 11 '10 at 05:34
-
Instead of using std::move you could use the swap method (or std::swap) to get a similiar behaviour, when you can't/don't use c++0x – Grizzly Oct 11 '10 at 13:52
-
Is there a combination of compiler and example code where passing by value actually performs better? I would like to know. – Johan Kotlinski Oct 13 '10 at 21:01