From 602e55dc67b04e97dd96f45f9b80e0b0daa13060 Mon Sep 17 00:00:00 2001 From: bluss Date: Sun, 25 Mar 2018 23:21:18 +0200 Subject: [PATCH] FEAT: Use drop_in_place for truncate and clear (and drop) This should perform better in both release and debug mode. NOTE: This is significant because it changes the drop order of the elements, and how we handle panicking destructors. If just one of the destructors panic during ArrayVec drop, clear or truncate, the rest of the elements should still drop. If we encounter another panic during that process, however, Rust will abort as usual for panic during unwinding. --- src/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 96e7a24..3f16fc9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -459,12 +459,18 @@ impl ArrayVec { /// assert_eq!(&array[..], &[1, 2, 3]); /// ``` pub fn truncate(&mut self, len: usize) { - while self.len() > len { self.pop(); } + unsafe { + if len < self.len() { + let tail: *mut [_] = &mut self[len..]; + self.set_len(len); + ptr::drop_in_place(tail); + } + } } /// Remove all elements in the vector. pub fn clear(&mut self) { - while let Some(_) = self.pop() { } + self.truncate(0) } /// Retains only the elements specified by the predicate.