Skip to content

Commit

Permalink
Speed up Vec::clear().
Browse files Browse the repository at this point in the history
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()`.
  • Loading branch information
nnethercote committed Apr 5, 2022
1 parent 6a9080b commit 27bddcb
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1881,7 +1881,18 @@ impl<T, A: Allocator> Vec<T, A> {
#[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
Expand Down

0 comments on commit 27bddcb

Please sign in to comment.