From 27bddcbc8f299748063d115caa2f59a8e93696e4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 5 Apr 2022 10:16:07 +1000 Subject: [PATCH] Speed up `Vec::clear()`. Currently it just calls `truncate(0)`. `truncate()` is (a) not marked as `#[inline]`, and (b) more general than needed for `clear()`. This commit changes `clear()` to do the work itself. This modest change was first proposed in #74172, where the reviewer rejected it because there was insufficient evidence that `Vec::clear()`'s performance mattered enough to justify the change. Recent changes within rustc have made `Vec::clear()` hot within `macro_parser.rs`, so the change is now clearly worthwhile. Note that this will also benefit `String::clear()`, because it just calls `Vec::clear()`. --- library/alloc/src/vec/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 0b62622de819e..9c235a4260f74 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1881,7 +1881,18 @@ impl Vec { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn clear(&mut self) { - self.truncate(0) + let elems: *mut [T] = self.as_mut_slice(); + + // SAFETY: + // - `elems` comes directly from `as_mut_slice` and is therefore valid. + // - Setting `self.len` before calling `drop_in_place` means that, + // if an element's `Drop` impl panics, the vector's `Drop` impl will + // do nothing (leaking the rest of the elements) instead of dropping + // some twice. + unsafe { + self.len = 0; + ptr::drop_in_place(elems); + } } /// Returns the number of elements in the vector, also referred to