Skip to content

Commit f66bcc5

Browse files
committed
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. #[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
1 parent 2d8bd9b commit f66bcc5

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

src/liballoc/vec.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1803,6 +1803,21 @@ impl<T: Clone> SpecFromElem for T {
18031803
}
18041804
}
18051805

1806+
impl SpecFromElem for i8 {
1807+
#[inline]
1808+
fn from_elem(elem: i8, n: usize) -> Vec<i8> {
1809+
if elem == 0 {
1810+
return Vec { buf: RawVec::with_capacity_zeroed(n), len: n };
1811+
}
1812+
unsafe {
1813+
let mut v = Vec::with_capacity(n);
1814+
ptr::write_bytes(v.as_mut_ptr(), elem as u8, n);
1815+
v.set_len(n);
1816+
v
1817+
}
1818+
}
1819+
}
1820+
18061821
impl SpecFromElem for u8 {
18071822
#[inline]
18081823
fn from_elem(elem: u8, n: usize) -> Vec<u8> {
@@ -1847,7 +1862,6 @@ macro_rules! impl_is_zero {
18471862
};
18481863
}
18491864

1850-
impl_is_zero!(i8, |x| x == 0);
18511865
impl_is_zero!(i16, |x| x == 0);
18521866
impl_is_zero!(i32, |x| x == 0);
18531867
impl_is_zero!(i64, |x| x == 0);

0 commit comments

Comments
 (0)