Skip to content

Commit e792370

Browse files
committed
FEAT: Optimize shift_remove_index using MaybeUninit
1 parent 27decf1 commit e792370

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

src/impl_methods.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9-
use std::mem::{size_of, ManuallyDrop};
9+
use std::mem::{size_of, ManuallyDrop, MaybeUninit};
1010
use alloc::slice;
1111
use alloc::vec;
1212
use alloc::vec::Vec;
@@ -2462,9 +2462,22 @@ where
24622462
let mut lane_iter = lane.iter_mut();
24632463
let mut dst = if let Some(dst) = lane_iter.next() { dst } else { return };
24642464

2465-
for elt in lane_iter {
2466-
std::mem::swap(dst, elt);
2467-
dst = elt;
2465+
// Logically we do a circular swap here, all elements in a chain
2466+
// Using MaybeUninit to avoid unecessary writes in the safe swap solution
2467+
//
2468+
// for elt in lane_iter {
2469+
// std::mem::swap(dst, elt);
2470+
// dst = elt;
2471+
// }
2472+
//
2473+
let mut slot = MaybeUninit::<A>::uninit();
2474+
unsafe {
2475+
slot.as_mut_ptr().copy_from_nonoverlapping(dst, 1);
2476+
for elt in lane_iter {
2477+
(dst as *mut A).copy_from_nonoverlapping(elt, 1);
2478+
dst = elt;
2479+
}
2480+
(dst as *mut A).copy_from_nonoverlapping(slot.as_ptr(), 1);
24682481
}
24692482
});
24702483
// then slice the axis in place to cut out the removed final element

0 commit comments

Comments
 (0)