Skip to content

Commit ec7f8d9

Browse files
committed
Auto merge of #81874 - tesuji:spec_slice_fill, r=matthewjasper
Specialize slice::fill with Copy type and u8/i8/bool I don't expect rustperf could measure any perf improvements with this changes since `slice::fill` is newly added. Godbolt link for this change: <https://rust.godbolt.org/z/r3fzee>. r? `@matthewjasper` since this patch added new specialization.
2 parents 8e863eb + 010e194 commit ec7f8d9

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

library/core/src/slice/mod.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ mod iter;
3535
mod raw;
3636
mod rotate;
3737
mod sort;
38+
mod specialize;
3839

3940
#[stable(feature = "rust1", since = "1.0.0")]
4041
pub use iter::{Chunks, ChunksMut, Windows};
@@ -2866,13 +2867,7 @@ impl<T> [T] {
28662867
where
28672868
T: Clone,
28682869
{
2869-
if let Some((last, elems)) = self.split_last_mut() {
2870-
for el in elems {
2871-
el.clone_from(&value);
2872-
}
2873-
2874-
*last = value
2875-
}
2870+
specialize::SpecFill::spec_fill(self, value);
28762871
}
28772872

28782873
/// Fills `self` with elements returned by calling a closure repeatedly.

library/core/src/slice/specialize.rs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use crate::ptr::write_bytes;
2+
3+
pub(super) trait SpecFill<T> {
4+
fn spec_fill(&mut self, value: T);
5+
}
6+
7+
impl<T: Clone> SpecFill<T> for [T] {
8+
default fn spec_fill(&mut self, value: T) {
9+
if let Some((last, elems)) = self.split_last_mut() {
10+
for el in elems {
11+
el.clone_from(&value);
12+
}
13+
14+
*last = value
15+
}
16+
}
17+
}
18+
19+
impl<T: Copy> SpecFill<T> for [T] {
20+
default fn spec_fill(&mut self, value: T) {
21+
for item in self.iter_mut() {
22+
*item = value;
23+
}
24+
}
25+
}
26+
27+
impl SpecFill<u8> for [u8] {
28+
fn spec_fill(&mut self, value: u8) {
29+
// SAFETY: this is slice of u8
30+
unsafe {
31+
let ptr = self.as_mut_ptr();
32+
let len = self.len();
33+
write_bytes(ptr, value, len);
34+
}
35+
}
36+
}
37+
38+
impl SpecFill<i8> for [i8] {
39+
fn spec_fill(&mut self, value: i8) {
40+
// SAFETY: this is slice of i8
41+
unsafe {
42+
let ptr = self.as_mut_ptr();
43+
let len = self.len();
44+
write_bytes(ptr, value as u8, len);
45+
}
46+
}
47+
}
48+
49+
impl SpecFill<bool> for [bool] {
50+
fn spec_fill(&mut self, value: bool) {
51+
// SAFETY: this is slice of bool
52+
unsafe {
53+
let ptr = self.as_mut_ptr();
54+
let len = self.len();
55+
write_bytes(ptr, value as u8, len);
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)