Avoid cloning in Dedup::clear_duplicates

Co-authored-by: Niklas Mohrin <niklas.mohrin@gmail.com>
This commit is contained in:
Danilo Bargen 2021-01-29 14:23:09 +01:00
commit 2e1e0006b2

View file

@ -1,3 +1,5 @@
use std::mem;
/// An extension trait to clear duplicates from a collection.
pub(crate) trait Dedup<T: PartialEq + Clone> {
fn clear_duplicates(&mut self);
@ -6,17 +8,13 @@ pub(crate) trait Dedup<T: PartialEq + Clone> {
/// Clear duplicates from a collection, keep the first one seen.
///
/// For small vectors, this will be faster than a `HashSet`.
/// Based on <https://stackoverflow.com/a/57889826/284318>
impl<T: PartialEq + Clone> Dedup<T> for Vec<T> {
fn clear_duplicates(&mut self) {
let mut already_seen = Vec::with_capacity(self.len());
self.retain(|item| {
if already_seen.contains(item) {
false
} else {
already_seen.push(item.clone());
true
let orig = mem::replace(self, Vec::with_capacity(self.len()));
for item in orig {
if !self.contains(&item) {
self.push(item);
}
})
}
}
}