use memmove instead of generic in-place iteration for IntoIter source
this is the original SpecExtend<_, IntoIter> logic except generalizing the fast-path to include a memmove
This commit is contained in:
parent
631543dcb4
commit
a4e385a0d0
@ -2216,14 +2216,22 @@ fn from_iter(iterator: IntoIter<T>) -> Self {
|
||||
// A common case is passing a vector into a function which immediately
|
||||
// re-collects into a vector. We can short circuit this if the IntoIter
|
||||
// has not been advanced at all.
|
||||
if iterator.buf.as_ptr() as *const _ == iterator.ptr {
|
||||
// We can also reuse the memory and move the data to the front if
|
||||
// allocating a new vector and moving to it would result in the same capacity
|
||||
let non_zero_offset = iterator.buf.as_ptr() as *const _ != iterator.ptr;
|
||||
if !non_zero_offset || iterator.len() >= iterator.cap / 2 {
|
||||
unsafe {
|
||||
let it = ManuallyDrop::new(iterator);
|
||||
if non_zero_offset {
|
||||
ptr::copy(it.ptr, it.buf.as_ptr(), it.len());
|
||||
}
|
||||
return Vec::from_raw_parts(it.buf.as_ptr(), it.len(), it.cap);
|
||||
}
|
||||
}
|
||||
|
||||
from_into_iter_source(iterator)
|
||||
let mut vec = Vec::new();
|
||||
vec.extend(iterator);
|
||||
vec
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user