Skip to content

Commit eb71c35

Browse files
authored
Rollup merge of rust-lang#52859 - ljedrz:smallvec_true_extend, r=Mark-Simulacrum
Use Vec::extend in SmallVec::extend when applicable As calculated in rust-lang#52738, `Vec::extend` is much faster than `push`ing to it in a loop. We can take advantage of this method in `SmallVec` too - at least in cases when its underlying object is an `AccumulateVec::Heap`. ~~This approach also accidentally improves the `push` loop of the `AccumulateVec::Array` variant, because it doesn't utilize `SmallVec::push` which performs `self.reserve(1)` with every iteration; this is unnecessary, because we're already reserving the whole space we will be needing by performing `self.reserve(iter.size_hint().0)` at the beginning.~~
2 parents 6767886 + ca52648 commit eb71c35

File tree

1 file changed

+128
-4
lines changed

1 file changed

+128
-4
lines changed

src/librustc_data_structures/small_vec.rs

Lines changed: 128 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,18 @@ impl<A: Array> FromIterator<A::Element> for SmallVec<A> {
169169

170170
impl<A: Array> Extend<A::Element> for SmallVec<A> {
171171
fn extend<I: IntoIterator<Item=A::Element>>(&mut self, iter: I) {
172-
let iter = iter.into_iter();
173-
self.reserve(iter.size_hint().0);
174-
for el in iter {
175-
self.push(el);
172+
if self.is_array() {
173+
let iter = iter.into_iter();
174+
self.reserve(iter.size_hint().0);
175+
176+
for el in iter {
177+
self.push(el);
178+
}
179+
} else {
180+
match self.0 {
181+
AccumulateVec::Heap(ref mut vec) => vec.extend(iter),
182+
_ => unreachable!()
183+
}
176184
}
177185
}
178186
}
@@ -213,3 +221,119 @@ impl<A> Decodable for SmallVec<A>
213221
})
214222
}
215223
}
224+
225+
#[cfg(test)]
226+
mod tests {
227+
extern crate test;
228+
use self::test::Bencher;
229+
230+
use super::*;
231+
232+
#[bench]
233+
fn fill_small_vec_1_10_with_cap(b: &mut Bencher) {
234+
b.iter(|| {
235+
let mut sv: SmallVec<[usize; 1]> = SmallVec::with_capacity(10);
236+
237+
sv.extend(0..10);
238+
})
239+
}
240+
241+
#[bench]
242+
fn fill_small_vec_1_10_wo_cap(b: &mut Bencher) {
243+
b.iter(|| {
244+
let mut sv: SmallVec<[usize; 1]> = SmallVec::new();
245+
246+
sv.extend(0..10);
247+
})
248+
}
249+
250+
#[bench]
251+
fn fill_small_vec_8_10_with_cap(b: &mut Bencher) {
252+
b.iter(|| {
253+
let mut sv: SmallVec<[usize; 8]> = SmallVec::with_capacity(10);
254+
255+
sv.extend(0..10);
256+
})
257+
}
258+
259+
#[bench]
260+
fn fill_small_vec_8_10_wo_cap(b: &mut Bencher) {
261+
b.iter(|| {
262+
let mut sv: SmallVec<[usize; 8]> = SmallVec::new();
263+
264+
sv.extend(0..10);
265+
})
266+
}
267+
268+
#[bench]
269+
fn fill_small_vec_32_10_with_cap(b: &mut Bencher) {
270+
b.iter(|| {
271+
let mut sv: SmallVec<[usize; 32]> = SmallVec::with_capacity(10);
272+
273+
sv.extend(0..10);
274+
})
275+
}
276+
277+
#[bench]
278+
fn fill_small_vec_32_10_wo_cap(b: &mut Bencher) {
279+
b.iter(|| {
280+
let mut sv: SmallVec<[usize; 32]> = SmallVec::new();
281+
282+
sv.extend(0..10);
283+
})
284+
}
285+
286+
#[bench]
287+
fn fill_small_vec_1_50_with_cap(b: &mut Bencher) {
288+
b.iter(|| {
289+
let mut sv: SmallVec<[usize; 1]> = SmallVec::with_capacity(50);
290+
291+
sv.extend(0..50);
292+
})
293+
}
294+
295+
#[bench]
296+
fn fill_small_vec_1_50_wo_cap(b: &mut Bencher) {
297+
b.iter(|| {
298+
let mut sv: SmallVec<[usize; 1]> = SmallVec::new();
299+
300+
sv.extend(0..50);
301+
})
302+
}
303+
304+
#[bench]
305+
fn fill_small_vec_8_50_with_cap(b: &mut Bencher) {
306+
b.iter(|| {
307+
let mut sv: SmallVec<[usize; 8]> = SmallVec::with_capacity(50);
308+
309+
sv.extend(0..50);
310+
})
311+
}
312+
313+
#[bench]
314+
fn fill_small_vec_8_50_wo_cap(b: &mut Bencher) {
315+
b.iter(|| {
316+
let mut sv: SmallVec<[usize; 8]> = SmallVec::new();
317+
318+
sv.extend(0..50);
319+
})
320+
}
321+
322+
#[bench]
323+
fn fill_small_vec_32_50_with_cap(b: &mut Bencher) {
324+
b.iter(|| {
325+
let mut sv: SmallVec<[usize; 32]> = SmallVec::with_capacity(50);
326+
327+
sv.extend(0..50);
328+
})
329+
}
330+
331+
#[bench]
332+
fn fill_small_vec_32_50_wo_cap(b: &mut Bencher) {
333+
b.iter(|| {
334+
let mut sv: SmallVec<[usize; 32]> = SmallVec::new();
335+
336+
sv.extend(0..50);
337+
})
338+
}
339+
}

0 commit comments

Comments
 (0)