about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-06-26 13:57:31 -0700
committerGitHub <noreply@github.com>2020-06-26 13:57:31 -0700
commit23b0776a594a0728a7706521c5193245de2ea823 (patch)
tree06e88616646e49ae05a600232443f342088a937c /src/liballoc
parentf13d09abe1d7a02007ac8591dc409c8d820b903a (diff)
parentf66bcc5459d4a720b31eaeac3149f19799118d72 (diff)
downloadrust-23b0776a594a0728a7706521c5193245de2ea823.tar.gz
rust-23b0776a594a0728a7706521c5193245de2ea823.zip
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.
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 1265d0e56b5..c2cf64393ad 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -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 @@ 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);