diff --git a/library/core/benches/slice.rs b/library/core/benches/slice.rs index dbab00856863b..04efa52078778 100644 --- a/library/core/benches/slice.rs +++ b/library/core/benches/slice.rs @@ -114,3 +114,16 @@ rotate!(rotate_16_usize_4, 16, |i| [i; 4]); rotate!(rotate_16_usize_5, 16, |i| [i; 5]); rotate!(rotate_64_usize_4, 64, |i| [i; 4]); rotate!(rotate_64_usize_5, 64, |i| [i; 5]); + +#[bench] +fn fill_byte_sized(b: &mut Bencher) { + #[derive(Copy, Clone)] + struct NewType(u8); + + let mut ary = [NewType(0); 1024]; + + b.iter(|| { + let slice = &mut ary[..]; + black_box(slice.fill(black_box(NewType(42)))); + }); +} diff --git a/library/core/src/slice/specialize.rs b/library/core/src/slice/specialize.rs index 16a9588989c85..425cf71626f40 100644 --- a/library/core/src/slice/specialize.rs +++ b/library/core/src/slice/specialize.rs @@ -1,3 +1,4 @@ +use crate::mem::{size_of, transmute_copy}; use crate::ptr::write_bytes; pub(super) trait SpecFill { @@ -17,42 +18,18 @@ impl SpecFill for [T] { } impl SpecFill for [T] { - default fn spec_fill(&mut self, value: T) { - for item in self.iter_mut() { - *item = value; - } - } -} - -impl SpecFill for [u8] { - fn spec_fill(&mut self, value: u8) { - // SAFETY: this is slice of u8 - unsafe { - let ptr = self.as_mut_ptr(); - let len = self.len(); - write_bytes(ptr, value, len); - } - } -} - -impl SpecFill for [i8] { - fn spec_fill(&mut self, value: i8) { - // SAFETY: this is slice of i8 - unsafe { - let ptr = self.as_mut_ptr(); - let len = self.len(); - write_bytes(ptr, value as u8, len); - } - } -} - -impl SpecFill for [bool] { - fn spec_fill(&mut self, value: bool) { - // SAFETY: this is slice of bool - unsafe { - let ptr = self.as_mut_ptr(); - let len = self.len(); - write_bytes(ptr, value as u8, len); + fn spec_fill(&mut self, value: T) { + if size_of::() == 1 { + // SAFETY: The size_of check above ensures that values are 1 byte wide, as required + // for the transmute and write_bytes + unsafe { + let value: u8 = transmute_copy(&value); + write_bytes(self.as_mut_ptr(), value, self.len()); + } + } else { + for item in self.iter_mut() { + *item = value; + } } } }