From b25d795ecf28427cb983c28a889ff9383badecdf Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Mon, 18 Jan 2021 02:26:32 -0500 Subject: [PATCH] optimize ArrayVec::fill --- src/arrayvec.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/arrayvec.rs b/src/arrayvec.rs index bffd35e..943eae4 100644 --- a/src/arrayvec.rs +++ b/src/arrayvec.rs @@ -403,10 +403,19 @@ impl ArrayVec { pub fn fill>( &mut self, iter: I, ) -> I::IntoIter { + // If this is written as a call to push for each element in iter, the + // compiler emits code that updates the length for every element. The + // additional complexity from that length update is worth nearly 2x in + // the runtime of this function. let mut iter = iter.into_iter(); - for element in iter.by_ref().take(self.capacity() - self.len()) { - self.push(element); + let mut pushed = 0; + let to_take = self.capacity() - self.len(); + let target = &mut self.data.as_slice_mut()[self.len as usize..]; + for element in iter.by_ref().take(to_take) { + target[pushed] = element; + pushed += 1; } + self.len += pushed as u16; iter }