diff --git a/library/alloc/benches/vec_deque.rs b/library/alloc/benches/vec_deque.rs index bf2dffd1e931e..404cfa6addb73 100644 --- a/library/alloc/benches/vec_deque.rs +++ b/library/alloc/benches/vec_deque.rs @@ -52,3 +52,18 @@ fn bench_try_fold(b: &mut Bencher) { b.iter(|| black_box(ring.iter().try_fold(0, |a, b| Some(a + b)))) } + +#[bench] +fn bench_from_array_1000(b: &mut Bencher) { + const N: usize = 1000; + let mut array: [usize; N] = [0; N]; + + for i in 0..N { + array[i] = i; + } + + b.iter(|| { + let deq: VecDeque<_> = array.into(); + black_box(deq); + }) +} diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 4a2b0b33bf2b2..007548ad1ab58 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -3004,6 +3004,16 @@ impl From<[T; N]> for VecDeque { /// assert_eq!(deq1, deq2); /// ``` 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::() != 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 } } diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index 56257e4346254..2be83f68f017f 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -507,6 +507,36 @@ fn test_from_vec_zst_overflow() { assert_eq!(vd.len(), vec.len()); } +#[test] +fn test_from_array() { + fn test() { + 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] fn test_vec_from_vecdeque() { use crate::vec::Vec;