Rollup merge of #73529 - pickfire:liballoc-specfromelem-i8, r=cuviper
Add liballoc impl SpecFromElem for i8 Speedup vec![1_i8; N] for non-zero element. Before test do_bench_from_elem_i8 ... bench: 130 ns/iter (+/- 7) = 61 MB/s test do_bench_from_elem_u8 ... bench: 121 ns/iter (+/- 4) = 66 MB/s After test do_bench_from_elem_i8 ... bench: 123 ns/iter (+/- 7) = 65 MB/s test do_bench_from_elem_u8 ... bench: 121 ns/iter (+/- 5) = 66 MB/s No speed difference if element is already zero. ```rust #[bench] fn do_bench_from_elem_i8(b: &mut Bencher) { b.bytes = 8 as u64; b.iter(|| { let dst = ve::vec![10_i8; 100]; assert_eq!(dst.len(), 100); assert!(dst.iter().all(|x| *x == 10)); }) } ``` As suggested by @cuviper https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/SpecForElem.20for.20other.20integers r? @cuviper CC @joshtriplett Edit: Wow, I just realized both reviewers are Josh.
This commit is contained in:
commit
23b0776a59
@ -1801,6 +1801,21 @@ impl<T: Clone> SpecFromElem for T {
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecFromElem for i8 {
|
||||
#[inline]
|
||||
fn from_elem(elem: i8, n: usize) -> Vec<i8> {
|
||||
if elem == 0 {
|
||||
return Vec { buf: RawVec::with_capacity_zeroed(n), len: n };
|
||||
}
|
||||
unsafe {
|
||||
let mut v = Vec::with_capacity(n);
|
||||
ptr::write_bytes(v.as_mut_ptr(), elem as u8, n);
|
||||
v.set_len(n);
|
||||
v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SpecFromElem for u8 {
|
||||
#[inline]
|
||||
fn from_elem(elem: u8, n: usize) -> Vec<u8> {
|
||||
@ -1845,7 +1860,6 @@ fn is_zero(&self) -> bool {
|
||||
};
|
||||
}
|
||||
|
||||
impl_is_zero!(i8, |x| x == 0);
|
||||
impl_is_zero!(i16, |x| x == 0);
|
||||
impl_is_zero!(i32, |x| x == 0);
|
||||
impl_is_zero!(i64, |x| x == 0);
|
||||
|
Loading…
Reference in New Issue
Block a user