From 4bcfbc36c672f0f30176a31c5a6e529bebd6fbcc Mon Sep 17 00:00:00 2001 From: Djzin Date: Sun, 12 Mar 2017 13:14:47 +0000 Subject: [PATCH] speed up mem::swap --- src/libcore/mem.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index f4ce4697d7c..a7c5d29c5a5 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -109,7 +109,7 @@ pub use intrinsics::transmute; /// [`Clone`][clone]. You need the value's destructor to run only once, /// because a double `free` is undefined behavior. /// -/// An example is the definition of [`mem::swap`][swap] in this module: +/// An example is the (old) definition of [`mem::swap`][swap] in this module: /// /// ``` /// use std::mem; @@ -447,18 +447,15 @@ pub unsafe fn uninitialized() -> T { #[stable(feature = "rust1", since = "1.0.0")] pub fn swap(x: &mut T, y: &mut T) { unsafe { - // Give ourselves some scratch space to work with - let mut t: T = uninitialized(); + let x = x as *mut T as *mut u8; + let y = y as *mut T as *mut u8; - // Perform the swap, `&mut` pointers never alias - ptr::copy_nonoverlapping(&*x, &mut t, 1); - ptr::copy_nonoverlapping(&*y, x, 1); - ptr::copy_nonoverlapping(&t, y, 1); - - // y and t now point to the same thing, but we need to completely - // forget `t` because we do not want to run the destructor for `T` - // on its value, which is still owned somewhere outside this function. - forget(t); + // use an xor-swap as x & y are guaranteed to never alias + for i in 0..size_of::() as isize { + *x.offset(i) ^= *y.offset(i); + *y.offset(i) ^= *x.offset(i); + *x.offset(i) ^= *y.offset(i); + } } }