diff --git a/benches/bench.rs b/benches/bench.rs index ad73226..b52ee15 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -96,6 +96,8 @@ make_benches! { SmallVec<[u64; VEC_SIZE]> { bench_push => gen_push(SPILLED_SIZE as _), bench_push_small => gen_push(VEC_SIZE as _), + bench_insert_push => gen_insert_push(SPILLED_SIZE as _), + bench_insert_push_small => gen_insert_push(VEC_SIZE as _), bench_insert => gen_insert(SPILLED_SIZE as _), bench_insert_small => gen_insert(VEC_SIZE as _), bench_remove => gen_remove(SPILLED_SIZE as _), @@ -118,6 +120,8 @@ make_benches! { Vec { bench_push_vec => gen_push(SPILLED_SIZE as _), bench_push_vec_small => gen_push(VEC_SIZE as _), + bench_insert_push_vec => gen_insert_push(SPILLED_SIZE as _), + bench_insert_push_vec_small => gen_insert_push(VEC_SIZE as _), bench_insert_vec => gen_insert(SPILLED_SIZE as _), bench_insert_vec_small => gen_insert(VEC_SIZE as _), bench_remove_vec => gen_remove(SPILLED_SIZE as _), @@ -151,6 +155,21 @@ fn gen_push>(n: u64, b: &mut Bencher) { }); } +fn gen_insert_push>(n: u64, b: &mut Bencher) { + #[inline(never)] + fn insert_push_noinline>(vec: &mut V, x: u64) { + vec.insert(x as usize, x); + } + + b.iter(|| { + let mut vec = V::new(); + for x in 0..n { + insert_push_noinline(&mut vec, x); + } + vec + }); +} + fn gen_insert>(n: u64, b: &mut Bencher) { #[inline(never)] fn insert_noinline>(vec: &mut V, p: usize, x: u64) { diff --git a/src/lib.rs b/src/lib.rs index d721789..64b45de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1068,17 +1068,22 @@ impl SmallVec { /// Insert an element at position `index`, shifting all elements after it to the right. /// - /// Panics if `index` is out of bounds. + /// Panics if `index > len`. pub fn insert(&mut self, index: usize, element: A::Item) { self.reserve(1); unsafe { let (mut ptr, len_ptr, _) = self.triple_mut(); let len = *len_ptr; - assert!(index <= len); - *len_ptr = len + 1; ptr = ptr.add(index); - ptr::copy(ptr, ptr.add(1), len - index); + if index < len { + ptr::copy(ptr, ptr.add(1), len - index); + } else if index == len { + // No elements need shifting. + } else { + panic!("index exceeds length"); + } + *len_ptr = len + 1; ptr::write(ptr, element); } }