Skip to content

Commit a143265

Browse files
blussstokhos
authored andcommitted
FEAT: Optimize shift_remove_index using MaybeUninit
1 parent 324ce36 commit a143265

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;
@@ -2460,9 +2460,22 @@ where
24602460
let mut lane_iter = lane.iter_mut();
24612461
let mut dst = if let Some(dst) = lane_iter.next() { dst } else { return };
24622462

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

0 commit comments

Comments
 (0)