-
Notifications
You must be signed in to change notification settings - Fork 13.3k
specialize Extend for Vec with IntoIter #41191
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
Conversation
Could this perhaps elide the unsafety by delegating to the other specialization? |
4a2f784
to
75e3607
Compare
@alexcrichton er, of course. Now delegating to extending from slice. |
@bors: r+ |
📌 Commit 75e3607 has been approved by |
…r, r=alexcrichton specialize Extend for Vec with IntoIter Before, `vec.extend(&other_vec)` was quite a bit faster than `vec.extend(other_vec)`. This allows extending by consuming a vec to use the same code as extending from a slice.
@bors r- Travis found an issue with this |
Can't this be a |
d567538
to
ade6fe3
Compare
@arielb1 I had assumed not, because you'd need to drop items that weren't So, I've refactored to make this make use of the same code as |
ade6fe3
to
d7b2906
Compare
r? @bluss |
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.
Lgtm, memcpy is indeed what we do to move ownership of the elements from the iterator's buffer to the vec's. The request for change is basically a style issue, but I thought it was worthwhile.
src/libcollections/vec.rs
Outdated
/// | ||
/// Does not drop elements from slice, must be handled by caller. | ||
#[inline] | ||
unsafe fn append_slice(&mut self, other: &[T]) { |
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.
We use other
here to transfer ownership of the elements, I'd be more comfortable with passing them as other: *mut [T]
, and it could also be even more clear in the comment that elements are moved from other; especially since elements are not dropped after actual use of the method. (No strong opinion on which *const
or *mut
to use.)
d7b2906
to
4d900be
Compare
@bluss updated to |
Looks great! Could you also add some tests which exercise this specific specialization? (and corner cases like empty vectors, zero-sized types, etc) |
4d900be
to
94075c4
Compare
@alexcrichton there were tests for |
src/libcollections/vec.rs
Outdated
other.set_len(0); | ||
} | ||
} | ||
|
||
/// Appends a elements to `Self`, without moving. |
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.
This method does move elements read from other
into self
's allocation. It should also not talk about dropping, because no T
elements need to be dropped or are dropped; they are just moved from being stored in one buffer to the other.
Can the method append_elements
use an argument of type *const [T]
instead? Coercions from &[T]
should make that simple to call in both the calling sites.
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.
(Please change this comment to say that it moves the elements, or at least not say without moving, because it is moving them.)
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.
Updated type to *const [T]
.
I've changed to docs to the suggested, but the original made more sense to me. It's only half moving the elements. It has directly copied them, but the original buffer has not been modified, so if the caller doesn't do something, they'll have copied potentially uncopiable data, and have data unsafety. 🤷♂️
94075c4
to
f85a533
Compare
@bors: r+ |
📌 Commit f85a533 has been approved by |
…ichton specialize Extend for Vec with IntoIter Before, `vec.extend(&other_vec)` was quite a bit faster than `vec.extend(other_vec)`. This allows extending by consuming a vec to use the same code as extending from a slice.
☀️ Test successful - status-appveyor, status-travis |
Before,
vec.extend(&other_vec)
was quite a bit faster thanvec.extend(other_vec)
. This allows extending by consuming a vec to use the same code as extending from a slice.