Skip to content

Commit 1a97b80

Browse files
authored
Help the compiler elide copies in try_remove() (#160)
1 parent 4955f79 commit 1a97b80

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

src/lib.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@
2727
//! value associated with a given key is removed from a slab, that key may be
2828
//! returned from future calls to `insert`.
2929
//!
30+
//! # Performance notes
31+
//!
32+
//! Methods that remove values and return them, such as [`Slab::remove`] and
33+
//! [`Slab::try_remove`], might copy the removed values to the stack even if
34+
//! their return values are unused. For types that don't have drop glue, the
35+
//! compiler can usually elide these copies.
36+
//!
3037
//! # Examples
3138
//!
3239
//! Basic storing and retrieval.
@@ -1115,19 +1122,21 @@ impl<T> Slab<T> {
11151122
/// ```
11161123
pub fn try_remove(&mut self, key: usize) -> Option<T> {
11171124
if let Some(entry) = self.entries.get_mut(key) {
1118-
// Swap the entry at the provided value
1119-
let prev = mem::replace(entry, Entry::Vacant(self.next));
1120-
1121-
match prev {
1122-
Entry::Occupied(val) => {
1123-
self.len -= 1;
1124-
self.next = key;
1125-
return val.into();
1126-
}
1127-
_ => {
1128-
// Woops, the entry is actually vacant, restore the state
1129-
*entry = prev;
1130-
}
1125+
if let Entry::Occupied(_) = entry {
1126+
// Here we use `std::mem::replace` to move the entry's value to
1127+
// the stack and set the entry as vacant in one shot. By doing
1128+
// this only when the entry is occupied, the compiler should be
1129+
// able to elide copying the bytes to the stack if the value
1130+
// turns out to be unused.
1131+
1132+
let val = match core::mem::replace(entry, Entry::Vacant(self.next)) {
1133+
Entry::Occupied(val) => val, // confirmed occupied above
1134+
_ => unreachable!(),
1135+
};
1136+
1137+
self.len -= 1;
1138+
self.next = key;
1139+
return val.into();
11311140
}
11321141
}
11331142
None

0 commit comments

Comments
 (0)