mirror of
https://github.com/openharmony/third_party_rust_rust-smallvec.git
synced 2026-07-18 21:05:34 -04:00
bench and optimize from_slice
This adds "bench_from_slice(_vec)(_small)" benches, renaming the previous versions to "bench_from_iter*" (because they were using `From<&[T]>`, which calls `FromIterator` internally) and optimizes the `from_slice` constructor considerably. Before: ``` test bench_from_slice ... bench: 42 ns/iter (+/- 0) test bench_from_slice_small ... bench: 12 ns/iter (+/- 0) ``` After: ``` test bench_from_slice ... bench: 27 ns/iter (+/- 0) test bench_from_slice_small ... bench: 8 ns/iter (+/- 0) ```
This commit is contained in:
+22
-1
@@ -17,6 +17,7 @@ trait Vector<T>: for<'a> From<&'a [T]> + Extend<T> + ExtendFromSlice<T> {
|
||||
fn remove(&mut self, p: usize) -> T;
|
||||
fn insert(&mut self, n: usize, val: T);
|
||||
fn from_elem(val: T, n: usize) -> Self;
|
||||
fn from_elems(val: &[T]) -> Self;
|
||||
}
|
||||
|
||||
impl<T: Copy> Vector<T> for Vec<T> {
|
||||
@@ -43,6 +44,10 @@ impl<T: Copy> Vector<T> for Vec<T> {
|
||||
fn from_elem(val: T, n: usize) -> Self {
|
||||
vec![val; n]
|
||||
}
|
||||
|
||||
fn from_elems(val: &[T]) -> Self {
|
||||
val.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> Vector<T> for SmallVec<[T; VEC_SIZE]> {
|
||||
@@ -69,6 +74,10 @@ impl<T: Copy> Vector<T> for SmallVec<[T; VEC_SIZE]> {
|
||||
fn from_elem(val: T, n: usize) -> Self {
|
||||
smallvec![val; n]
|
||||
}
|
||||
|
||||
fn from_elems(val: &[T]) -> Self {
|
||||
SmallVec::from_slice(val)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! make_benches {
|
||||
@@ -92,6 +101,8 @@ make_benches! {
|
||||
bench_remove_small => gen_remove(VEC_SIZE as _),
|
||||
bench_extend => gen_extend(SPILLED_SIZE as _),
|
||||
bench_extend_small => gen_extend(VEC_SIZE as _),
|
||||
bench_from_iter => gen_from_iter(SPILLED_SIZE as _),
|
||||
bench_from_iter_small => gen_from_iter(VEC_SIZE as _),
|
||||
bench_from_slice => gen_from_slice(SPILLED_SIZE as _),
|
||||
bench_from_slice_small => gen_from_slice(VEC_SIZE as _),
|
||||
bench_extend_from_slice => gen_extend_from_slice(SPILLED_SIZE as _),
|
||||
@@ -112,6 +123,8 @@ make_benches! {
|
||||
bench_remove_vec_small => gen_remove(VEC_SIZE as _),
|
||||
bench_extend_vec => gen_extend(SPILLED_SIZE as _),
|
||||
bench_extend_vec_small => gen_extend(VEC_SIZE as _),
|
||||
bench_from_iter_vec => gen_from_iter(SPILLED_SIZE as _),
|
||||
bench_from_iter_vec_small => gen_from_iter(VEC_SIZE as _),
|
||||
bench_from_slice_vec => gen_from_slice(SPILLED_SIZE as _),
|
||||
bench_from_slice_vec_small => gen_from_slice(VEC_SIZE as _),
|
||||
bench_extend_from_slice_vec => gen_extend_from_slice(SPILLED_SIZE as _),
|
||||
@@ -179,7 +192,7 @@ fn gen_extend<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
||||
});
|
||||
}
|
||||
|
||||
fn gen_from_slice<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
||||
fn gen_from_iter<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
||||
let v: Vec<u64> = (0..n).collect();
|
||||
b.iter(|| {
|
||||
let vec = V::from(&v);
|
||||
@@ -187,6 +200,14 @@ fn gen_from_slice<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
||||
});
|
||||
}
|
||||
|
||||
fn gen_from_slice<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
||||
let v: Vec<u64> = (0..n).collect();
|
||||
b.iter(|| {
|
||||
let vec = V::from_elems(&v);
|
||||
vec
|
||||
});
|
||||
}
|
||||
|
||||
fn gen_extend_from_slice<V: Vector<u64>>(n: u64, b: &mut Bencher) {
|
||||
let v: Vec<u64> = (0..n).collect();
|
||||
b.iter(|| {
|
||||
|
||||
@@ -946,9 +946,25 @@ impl<A: Array> SmallVec<A> where A::Item: Copy {
|
||||
///
|
||||
/// For slices of `Copy` types, this is more efficient than `SmallVec::from(slice)`.
|
||||
pub fn from_slice(slice: &[A::Item]) -> Self {
|
||||
let mut vec = Self::new();
|
||||
vec.extend_from_slice(slice);
|
||||
vec
|
||||
let len = slice.len();
|
||||
if len <= A::size() {
|
||||
SmallVec {
|
||||
capacity: len,
|
||||
data: SmallVecData::from_inline(unsafe {
|
||||
let mut data: A = mem::uninitialized();
|
||||
ptr::copy_nonoverlapping(slice.as_ptr(), data.ptr_mut(), len);
|
||||
data
|
||||
})
|
||||
}
|
||||
} else {
|
||||
let mut b = slice.to_vec();
|
||||
let ptr = b.as_mut_ptr();
|
||||
mem::forget(b);
|
||||
SmallVec {
|
||||
capacity: len,
|
||||
data: SmallVecData::from_heap(ptr, len),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy elements from a slice into the vector at position `index`, shifting any following
|
||||
|
||||
Reference in New Issue
Block a user