diff --git a/CHANGELOG.md b/CHANGELOG.md index c5dc4fe..b1d7e80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- The `Drop` impl now uses the `mem::needs_drop()` optimization hint to avoid + unnecessary overhead. ## [0.2.0] - 2017-09-17 ### Added diff --git a/src/lib.rs b/src/lib.rs index 137f7fd..f55cec7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -785,12 +785,19 @@ impl Drop for StableVec { // To achieve all this, we manually drop all remaining elements, then // tell the Vec that its length is 0 (its capacity stays the same!) and // let the Vec drop itself in the end. - let living_indices = self.deleted.iter() - .enumerate() - .filter_map(|(i, deleted)| if deleted { None } else { Some(i) }); - for i in living_indices { - unsafe { - ptr::drop_in_place(&mut self.data[i]); + // + // When `T` doesn't need to be dropped, we can skip this next step. + // While `ptr::drop_in_place()` already uses the `mem::needs_drop()` + // check, it's still useful to check it here, to avoid executing these + // two loops completely. + if mem::needs_drop::() { + let living_indices = self.deleted.iter() + .enumerate() + .filter_map(|(i, deleted)| if deleted { None } else { Some(i) }); + for i in living_indices { + unsafe { + ptr::drop_in_place(&mut self.data[i]); + } } }