From 2ab73cf63d94d9ca0dc8a777813ad9339b3991f1 Mon Sep 17 00:00:00 2001 From: Cheng XU Date: Sat, 28 Aug 2021 19:46:58 -0700 Subject: [PATCH 1/2] add benchmark for From<[T; N]> in VecDeque --- library/alloc/benches/vec_deque.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) 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); + }) +} From c3cff0a75412f18971a325640a5dd7bd67b28972 Mon Sep 17 00:00:00 2001 From: Cheng XU Date: Sat, 28 Aug 2021 21:09:36 -0700 Subject: [PATCH 2/2] VecDeque: improve performance for From<[T; N]> Create VecDeque directly from the array instead of inserting items one-by-one. --- .../alloc/src/collections/vec_deque/mod.rs | 12 +++++++- .../alloc/src/collections/vec_deque/tests.rs | 30 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index e4b28204158d9..31d92b0ef7366 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -3003,6 +3003,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;