Skip to content

Commit 17cc606

Browse files
committed
FEAT: Optimize shift_remove_index using MaybeUninit
1 parent cc88042 commit 17cc606

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

src/impl_methods.rs

Lines changed: 18 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,10 +2462,24 @@ where
24622462
Zip::from(tail.lanes_mut(axis)).for_each(|lane| {
24632463
// TODO give ArrayViewMut1 a split_first method?
24642464
let (mut fst, mut rest) = lane.split_at(Axis(0), 1);
2465+
2466+
// Logically we do a circular swap here, all elements in a chain
2467+
// Using MaybeUninit to avoid unecessary writes in the safe swap solution
2468+
//
2469+
// for elt in rest.iter_mut() {
2470+
// std::mem::swap(dst, elt);
2471+
// dst = elt;
2472+
// }
2473+
//
2474+
let mut slot = MaybeUninit::<A>::uninit();
24652475
let mut dst = &mut fst[0];
2466-
for elt in rest.iter_mut() {
2467-
std::mem::swap(dst, elt);
2468-
dst = elt;
2476+
unsafe {
2477+
slot.as_mut_ptr().copy_from_nonoverlapping(dst, 1);
2478+
for elt in rest.iter_mut() {
2479+
(dst as *mut A).copy_from_nonoverlapping(elt, 1);
2480+
dst = elt;
2481+
}
2482+
(dst as *mut A).copy_from_nonoverlapping(slot.as_ptr(), 1);
24692483
}
24702484
});
24712485
}

0 commit comments

Comments
 (0)