about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorIvan Tham <pickfire@riseup.net>2020-06-20 11:07:22 +0800
committerIvan Tham <pickfire@riseup.net>2020-06-20 11:55:01 +0800
commitf66bcc5459d4a720b31eaeac3149f19799118d72 (patch)
treea6c9480f1efc3f19f5b6cdc5da7505e6c3c5c2c3 /src/liballoc
parent2d8bd9b74dc0cf06d881bac645698ccbcf9d9c5e (diff)
downloadrust-f66bcc5459d4a720b31eaeac3149f19799118d72.tar.gz
rust-f66bcc5459d4a720b31eaeac3149f19799118d72.zip
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
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/vec.rs16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index f16cac05ea0..b4a8597656e 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -1803,6 +1803,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> {
@@ -1847,7 +1862,6 @@ macro_rules! impl_is_zero {
     };
 }
 
-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);