-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Swap self and other in vec::append when it avoids a reallocation #77538
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -243,8 +243,8 @@ use crate::raw_vec::RawVec; | |
/// * It would penalize the general case, incurring an additional branch | ||
/// on every access. | ||
/// | ||
/// `Vec` will never automatically shrink itself, even if completely empty. This | ||
/// ensures no unnecessary allocations or deallocations occur. Emptying a `Vec` | ||
/// `Vec` will not automatically shrink itself, even if completely empty, when doing so | ||
/// would cause unnecessary allocations or deallocations to occur. Emptying a `Vec` | ||
/// and then filling it back up to the same [`len`] should incur no calls to | ||
/// the allocator. If you wish to free up unused memory, use | ||
/// [`shrink_to_fit`]. | ||
|
@@ -1257,6 +1257,14 @@ impl<T> Vec<T> { | |
#[inline] | ||
#[stable(feature = "append", since = "1.4.0")] | ||
pub fn append(&mut self, other: &mut Self) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or we could just put a big notice that possible allocation stealing in the docs of |
||
// Reuses other if doing so allows us to turn a certain reallocation within self | ||
// into a potential, future reallocation in other. | ||
// The capacity limit ensures that we are not stealing a large preallocation from `other` | ||
// that is not commensurate with the avoided reallocation in self. | ||
if self.len == 0 && self.capacity() < other.len && other.capacity() / 2 <= other.len { | ||
mem::swap(self, other); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even though this helps the general case but it may regress on some cases where users want to reuse the capacity of the other There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. without this change: it must allocate now to grow |
||
return; | ||
} | ||
unsafe { | ||
self.append_elements(other.as_slice() as _); | ||
other.set_len(0); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe playing with words would confuse most users, this does not feel much different to me. Maybe
Maybe a big but helps? Probably needs rewrapping.