-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Switch to copy-and-swap idiom for operator=. #37
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
Switch to copy-and-swap idiom for operator=. #37
Conversation
This allows the compiler to elide a copy when rhs is a temporary.
Common patterns like: json_obj[key] = strval; save a strdup from this optimization. |
For the benefit of anybody following along at home, the performance effect here |
Switch to copy-and-swap idiom for operator=.
Hello, thanks for this useful project. However, I don't think it's beneficial to merge the code like that. IMHO, someone on stackoverflow said is true ONLY when compiler implicitly create move ctors for class. But since your classes had manually implemented its ctors and/or dtor, compiler would not create move ctors for them. Please kindly refer to flowing documentation: |
Xiao-Chong, the benefits of copy-and-swap are clear here. Do you have a link to the StackOverflow reference you're citing? The copy was being made anyway inside the body of the move constructor, so this isn't ever slower than the old code. When the rhs of the assignment is a temporary, the compiler can apply "copy elision" to save that copy from happening, and we win. You are right that we can do better still than this by adding rvalue-reference overloads of operator= and the ctors, but I was reluctant to introduce C++11 into the project for my first patch :). I can certainly continue to make improvements like that if they'd be welcomed, braced by "#if __cplusplus>=201103L" version checks, of course. |
@BillyDonahue , Thanks for your reply and explanation. I didn't notice that "copy elision" benefits. ;-) |
Switch to copy-and-swap idiom for operator=.
Copy elision is a Good Thing. However, Yes, C++11 changes, with I have rebased this change to simplify the history. |
I didn't check the assembly, but there are only specific contexts in which the compiler is allowed to elide a copy, even if it has side effects. This optimization opportunity for copies is more aggressive than what's allowed for an inlining optimizer, which can't ever choose to omit side effects. Relevant std section here:
Passing a temporary to a function argument is one case, returning a local from a function is another. But copies like the one in the body of the old operator= are not elidable. The optimizer can't know that the copy+swap+destruct will produce the same effect as eliding the copy. There are malloc and free calls in the copy ctor and destructor, so there are nonlocal side effects. But even if that weren't the case, I'd be shocked to see the whole sequence omitted by an inlining optimizer. Glad to see you're open to C++11 optimizations! |
See issue #40 |
This allows the compiler to elide a copy when rhs is a temporary.