Skip to content

Commit 569d8ae

Browse files
committed
Optimize out swap_remove_and_drop_unchecked
1 parent d183448 commit 569d8ae

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

crates/bevy_ecs/src/storage/blob_vec.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,24 +183,29 @@ impl BlobVec {
183183
#[must_use = "The returned pointer should be used to dropped the removed element"]
184184
pub unsafe fn swap_remove_and_forget_unchecked(&mut self, index: usize) -> OwningPtr<'_> {
185185
debug_assert!(index < self.len());
186-
let new_len = self.len - 1;
186+
let last = self.len - 1;
187187
let size = self.item_layout.size();
188-
(self.swap)(self.get_unchecked(new_len), self.get_unchecked(index));
189-
self.len = new_len;
188+
(self.swap)(self.get_unchecked(last), self.get_unchecked(index));
189+
self.len = last;
190190
// Cannot use get_unchecked here as this is technically out of bounds after changing len.
191-
self.get_ptr_mut().byte_add(new_len * size).promote()
191+
self.get_ptr_mut().byte_add(last * size).promote()
192192
}
193193

194194
/// # Safety
195195
/// It is the caller's responsibility to ensure that `index` is < self.len()
196196
#[inline]
197197
pub unsafe fn swap_remove_and_drop_unchecked(&mut self, index: usize) {
198198
debug_assert!(index < self.len());
199-
let drop = self.drop;
200-
let value = self.swap_remove_and_forget_unchecked(index);
201-
if let Some(drop) = drop {
202-
(drop)(value);
199+
if let Some(drop) = self.drop {
200+
(drop)(self.get_unchecked_mut(index).promote());
203201
}
202+
let last = self.len - 1;
203+
std::ptr::copy(
204+
self.get_unchecked_mut(last).as_ptr(),
205+
self.get_unchecked_mut(index).as_ptr(),
206+
self.item_layout.size(),
207+
);
208+
self.len = last;
204209
}
205210

206211
/// # Safety

0 commit comments

Comments
 (0)