VecDeque: improve performance for From<[T; N]>

Create VecDeque directly from the array instead of inserting items one-by-one.
This commit is contained in:
Cheng XU 2021-08-28 21:09:36 -07:00
parent 2ab73cf63d
commit c3cff0a754
No known key found for this signature in database
GPG Key ID: 8794B5D7A3C67F70
2 changed files with 41 additions and 1 deletions

View File

@ -3003,6 +3003,16 @@ impl<T, const N: usize> From<[T; N]> for VecDeque<T> {
/// assert_eq!(deq1, deq2); /// assert_eq!(deq1, deq2);
/// ``` /// ```
fn from(arr: [T; N]) -> Self { fn from(arr: [T; N]) -> Self {
core::array::IntoIter::new(arr).collect() let mut deq = VecDeque::with_capacity(N);
let arr = ManuallyDrop::new(arr);
if mem::size_of::<T>() != 0 {
// SAFETY: VecDeque::with_capacity ensures that there is enough capacity.
unsafe {
ptr::copy_nonoverlapping(arr.as_ptr(), deq.ptr(), N);
}
}
deq.tail = 0;
deq.head = N;
deq
} }
} }

View File

@ -507,6 +507,36 @@ fn test_from_vec_zst_overflow() {
assert_eq!(vd.len(), vec.len()); assert_eq!(vd.len(), vec.len());
} }
#[test]
fn test_from_array() {
fn test<const N: usize>() {
let mut array: [usize; N] = [0; N];
for i in 0..N {
array[i] = i;
}
let deq: VecDeque<_> = array.into();
for i in 0..N {
assert_eq!(deq[i], i);
}
assert!(deq.cap().is_power_of_two());
assert_eq!(deq.len(), N);
}
test::<0>();
test::<1>();
test::<2>();
test::<32>();
test::<35>();
let array = [(); MAXIMUM_ZST_CAPACITY - 1];
let deq = VecDeque::from(array);
assert!(deq.cap().is_power_of_two());
assert_eq!(deq.len(), MAXIMUM_ZST_CAPACITY - 1);
}
#[test] #[test]
fn test_vec_from_vecdeque() { fn test_vec_from_vecdeque() {
use crate::vec::Vec; use crate::vec::Vec;