From 22bbcd28a7a9f268bf06712b25d66bf6913f5a79 Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Tue, 23 Aug 2016 11:38:28 -0700 Subject: [PATCH 1/4] Implement extend_slice and insert_slice with memcpy optimization --- lib.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/lib.rs b/lib.rs index e44c1f7..95c4eaf 100644 --- a/lib.rs +++ b/lib.rs @@ -477,6 +477,29 @@ impl SmallVec { } } +impl SmallVec where A::Item: Copy { + pub fn insert_slice(&mut self, index: usize, slice: &[A::Item]) { + self.reserve(slice.len()); + + let len = self.len; + assert!(index <= len); + + unsafe { + let slice_ptr = slice.as_ptr(); + let ptr = self.as_mut_ptr().offset(index as isize); + ptr::copy(ptr, ptr.offset(slice.len() as isize), len - index); + ptr::copy(slice_ptr, ptr, slice.len()); + self.set_len(len + slice.len()); + } + } + + #[inline] + pub fn extend_slice(&mut self, slice: &[A::Item]) { + let len = self.len(); + self.insert_slice(len, slice); + } +} + impl ops::Deref for SmallVec { type Target = [A::Item]; #[inline] @@ -1068,6 +1091,28 @@ pub mod tests { v.grow(5); } + #[test] + fn test_insert_slice() { + let mut v: SmallVec<[u8; 8]> = SmallVec::new(); + for x in 0..4 { + v.push(x); + } + assert_eq!(v.len(), 4); + v.insert_slice(1, &[5, 6]); + assert_eq!(&v.iter().map(|v| *v).collect::>(), &[0, 5, 6, 1, 2, 3]); + } + + #[test] + fn test_extend_slice() { + let mut v: SmallVec<[u8; 8]> = SmallVec::new(); + for x in 0..4 { + v.push(x); + } + assert_eq!(v.len(), 4); + v.extend_slice(&[5, 6]); + assert_eq!(&v.iter().map(|v| *v).collect::>(), &[0, 1, 2, 3, 5, 6]); + } + #[test] #[should_panic] fn test_drop_panic_smallvec() { From e6e67cd049d497f01e45887501cd39a6fca7fe02 Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Wed, 24 Aug 2016 10:03:50 -0700 Subject: [PATCH 2/4] Rename to extend_from_slice and insert_from_slice --- lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib.rs b/lib.rs index 95c4eaf..762b838 100644 --- a/lib.rs +++ b/lib.rs @@ -478,7 +478,7 @@ impl SmallVec { } impl SmallVec where A::Item: Copy { - pub fn insert_slice(&mut self, index: usize, slice: &[A::Item]) { + pub fn insert_from_slice(&mut self, index: usize, slice: &[A::Item]) { self.reserve(slice.len()); let len = self.len; @@ -494,9 +494,9 @@ impl SmallVec where A::Item: Copy { } #[inline] - pub fn extend_slice(&mut self, slice: &[A::Item]) { + pub fn extend_from_slice(&mut self, slice: &[A::Item]) { let len = self.len(); - self.insert_slice(len, slice); + self.insert_from_slice(len, slice); } } @@ -1092,24 +1092,24 @@ pub mod tests { } #[test] - fn test_insert_slice() { + fn test_insert_from_slice() { let mut v: SmallVec<[u8; 8]> = SmallVec::new(); for x in 0..4 { v.push(x); } assert_eq!(v.len(), 4); - v.insert_slice(1, &[5, 6]); + v.insert_from_slice(1, &[5, 6]); assert_eq!(&v.iter().map(|v| *v).collect::>(), &[0, 5, 6, 1, 2, 3]); } #[test] - fn test_extend_slice() { + fn test_extend_from_slice() { let mut v: SmallVec<[u8; 8]> = SmallVec::new(); for x in 0..4 { v.push(x); } assert_eq!(v.len(), 4); - v.extend_slice(&[5, 6]); + v.extend_from_slice(&[5, 6]); assert_eq!(&v.iter().map(|v| *v).collect::>(), &[0, 1, 2, 3, 5, 6]); } From 0fe867e33cbd6e77da2a7657efd908a1ef2259fc Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Sat, 27 Aug 2016 14:03:06 -0700 Subject: [PATCH 3/4] Add benchmark for extend_from_slice --- benches/bench.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/benches/bench.rs b/benches/bench.rs index c571b85..aee5c47 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -63,6 +63,15 @@ fn bench_extend(b: &mut Bencher) { }); } +#[bench] +fn bench_extend_from_slice(b: &mut Bencher) { + let v: Vec = (0..100).collect(); + b.iter(|| { + let mut vec: SmallVec<[u64; 16]> = SmallVec::new(); + vec.extend_from_slice(&v); + }); +} + #[bench] fn bench_pushpop(b: &mut Bencher) { #[inline(never)] From aef21138179cf7b8a3306429f0c06628a40da15e Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Mon, 12 Sep 2016 01:10:25 -0700 Subject: [PATCH 4/4] Add bench insert_from_slice --- benches/bench.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/benches/bench.rs b/benches/bench.rs index aee5c47..661b0d9 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -69,6 +69,18 @@ fn bench_extend_from_slice(b: &mut Bencher) { b.iter(|| { let mut vec: SmallVec<[u64; 16]> = SmallVec::new(); vec.extend_from_slice(&v); + vec + }); +} + +#[bench] +fn bench_insert_from_slice(b: &mut Bencher) { + let v: Vec = (0..100).collect(); + b.iter(|| { + let mut vec: SmallVec<[u64; 16]> = SmallVec::new(); + vec.insert_from_slice(0, &v); + vec.insert_from_slice(0, &v); + vec }); }