-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Prefer pass-by-value over pass-by-rvalue #1046
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I don't have any preference on rvalues. All that code came from @BillyDonahue, who might have an opinion? |
I tried to modify |
I commented on pull #1067 . |
I'd like to get to consensus that this issue can be closed. The
So nothing expensive right now, but the |
I don't understand the concern. Let's consider three cases of objects: 1 - l-value object (e.g. a non-temporary class instance) With a single pass by value, these objects are: With For things where copying is actually cheaper than moving, e.g. void append(int foo) {
// passes the value of foo (not a reference), which is copied or moved as appropriate.
} Versus: void append(const int& foo) {
// passes a reference to foo, which is then copied.
}
void append(int&& foo) {
// passes a reference to foo, which is moved.
} Can you describe a case where having const ref and move-only methods is better? |
Okay, let's dive in. Since we're now discussing
It's important that append is a consuming function, so we have to tally its body's cost as well. https://gcc.godbolt.org/z/krvCk-
Empirical results: 1 - copy + move + dtor
Empirical results: 1 - copy |
I made a more thorough experiment out of it to take account of the effect of translation unit boundaries, which are at play here in https://github.com/BillyDonahue/experimental/tree/make_container/container_moves I see 9 operations in the ByValue experiments and 5 operations in the ByRef experiments. |
Thanks for making the experiment. I played around with it and broke up the test result for clarity's sake. In the case of passing a plain Value (case 2), both strategies constructed a new value, move-assigned it, and destructed the old one. For const reference, byRef (e.g. const& and && declarations), the compiler was smart enough to use a single copy-assign statement, same for a move-only r-value. In every case, byRef either matched the number of instructions or had fewer. It's definitely more performant, assuming copy/move and copy-assign/move-assign have the same complexity (which they definitely should). I'm happy to close this issue, these results are pretty conclusive IMO. My results for posterity:
|
I would prefer not specifying rvalue only on the function parameter. It's similarly efficient to have a pass-by-value parameter that you can move in and out of.
If you declare as:
bool insert(ArrayIndex index, Value newValue);
You can call as
Value foo(); insert(index, std::move(foo))
Some good material on this.
http://blogs.microsoft.co.il/sasha/2014/08/21/c-sink-parameter-passing/
The text was updated successfully, but these errors were encountered: