-
Notifications
You must be signed in to change notification settings - Fork 13.3k
String cloning is not optimized the same way as String construction #88905
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
Related #24194 |
While trying to understand why this is, I found another strange behavior (godbolt link): cloning a Vec containing elements with more than 1 byte wide cannot be optimized away by the compiler. I think this is because of However, I do not think this is related because all the previous tests used |
This looks like it's a matter of inlining. |
Hum, yes, I think this is it. Trying not to use If it does get eliminated during LTO, it is not a problem. Should I close this issue ? |
It calls `Vec::clone` and performs a newtype-wrap around it, so it should be trivial enough that it doesn't cause major size regressions. It also fixes rust-lang#88905
@rustbot assign @notriddle |
@SadiinsoSnowfall is this example reduced from a realistic use case? |
@notriddle No, I was just playing around with compiler explorer. As the8472 said, this can be optimized during LTO so it might be a non-issue (as shown in the bench run in your PR). |
I don't know if it is really worth looking into, but I think I found some weird behavior in the rust compiler:
Let's consider the two following functions (godbolt link):
They both allocate a String struct but do not use or return it. Rustc is able to optimize away the first one, but not the second one.
If we dig deeper, we can observe that the compiler is not able to optimize away the
to_owned
andclone
method when called on a string. Let's look at the following functions (godbolt link):The fonctions
a
,c
ande
are optimized away even on opt-level 2. Whereas the functionsb
andd
are not and still produce calls toalloc
,dealloc
,drop_in_place
, etc...Looking at the stdlib code,
<&str>::to_owned
internally calls<&[u8]>::to_owned
, which calls<&[u8]>::to_vec
, which calls<&[u8]>::to_vec_in
which ends up callinghack::to_vec
.String::to_string
callsString::to_owned
which callsString::clone
which callsVec<u8>::clone
which calls<&[u8]>::to_vec_in
with the only difference from the<&str>::to_owned
path being that the possibly custom allocator of theVec
internal buffer is cloned and passed to<&[u8]>::to_vec_in
inVec<u8>::clone
.Is it possible that rustc is not able to correctly inline the allocator functions when the default allocator is not directly assumed ?
This was tested on
Rustc 1.55
and `Rustc 1.57.0-nightly (b69fe57 2021-09-10)This issue has been assigned to @notriddle via this comment.
The text was updated successfully, but these errors were encountered: