]> git.lizzy.rs Git - rust.git/blob - library/alloc/benches/vec.rs
Try to make Vec benchmarks only run code they are benchmarking
[rust.git] / library / alloc / benches / vec.rs
1 use rand::RngCore;
2 use std::iter::{repeat, FromIterator};
3 use test::{black_box, Bencher};
4
5 #[bench]
6 fn bench_new(b: &mut Bencher) {
7     b.iter(|| Vec::<u32>::new())
8 }
9
10 fn do_bench_with_capacity(b: &mut Bencher, src_len: usize) {
11     b.bytes = src_len as u64;
12
13     b.iter(|| Vec::<u32>::with_capacity(src_len))
14 }
15
16 #[bench]
17 fn bench_with_capacity_0000(b: &mut Bencher) {
18     do_bench_with_capacity(b, 0)
19 }
20
21 #[bench]
22 fn bench_with_capacity_0010(b: &mut Bencher) {
23     do_bench_with_capacity(b, 10)
24 }
25
26 #[bench]
27 fn bench_with_capacity_0100(b: &mut Bencher) {
28     do_bench_with_capacity(b, 100)
29 }
30
31 #[bench]
32 fn bench_with_capacity_1000(b: &mut Bencher) {
33     do_bench_with_capacity(b, 1000)
34 }
35
36 fn do_bench_from_fn(b: &mut Bencher, src_len: usize) {
37     b.bytes = src_len as u64;
38
39     b.iter(|| (0..src_len).collect::<Vec<_>>())
40 }
41
42 #[bench]
43 fn bench_from_fn_0000(b: &mut Bencher) {
44     do_bench_from_fn(b, 0)
45 }
46
47 #[bench]
48 fn bench_from_fn_0010(b: &mut Bencher) {
49     do_bench_from_fn(b, 10)
50 }
51
52 #[bench]
53 fn bench_from_fn_0100(b: &mut Bencher) {
54     do_bench_from_fn(b, 100)
55 }
56
57 #[bench]
58 fn bench_from_fn_1000(b: &mut Bencher) {
59     do_bench_from_fn(b, 1000)
60 }
61
62 fn do_bench_from_elem(b: &mut Bencher, src_len: usize) {
63     b.bytes = src_len as u64;
64
65     b.iter(|| repeat(5).take(src_len).collect::<Vec<usize>>())
66 }
67
68 #[bench]
69 fn bench_from_elem_0000(b: &mut Bencher) {
70     do_bench_from_elem(b, 0)
71 }
72
73 #[bench]
74 fn bench_from_elem_0010(b: &mut Bencher) {
75     do_bench_from_elem(b, 10)
76 }
77
78 #[bench]
79 fn bench_from_elem_0100(b: &mut Bencher) {
80     do_bench_from_elem(b, 100)
81 }
82
83 #[bench]
84 fn bench_from_elem_1000(b: &mut Bencher) {
85     do_bench_from_elem(b, 1000)
86 }
87
88 fn do_bench_from_slice(b: &mut Bencher, src_len: usize) {
89     let src: Vec<_> = FromIterator::from_iter(0..src_len);
90
91     b.bytes = src_len as u64;
92
93     b.iter(|| src.as_slice().to_vec());
94 }
95
96 #[bench]
97 fn bench_from_slice_0000(b: &mut Bencher) {
98     do_bench_from_slice(b, 0)
99 }
100
101 #[bench]
102 fn bench_from_slice_0010(b: &mut Bencher) {
103     do_bench_from_slice(b, 10)
104 }
105
106 #[bench]
107 fn bench_from_slice_0100(b: &mut Bencher) {
108     do_bench_from_slice(b, 100)
109 }
110
111 #[bench]
112 fn bench_from_slice_1000(b: &mut Bencher) {
113     do_bench_from_slice(b, 1000)
114 }
115
116 fn do_bench_from_iter(b: &mut Bencher, src_len: usize) {
117     let src: Vec<_> = FromIterator::from_iter(0..src_len);
118
119     b.bytes = src_len as u64;
120
121     b.iter(|| {
122         let dst: Vec<_> = FromIterator::from_iter(src.iter().cloned());
123         dst
124     });
125 }
126
127 #[bench]
128 fn bench_from_iter_0000(b: &mut Bencher) {
129     do_bench_from_iter(b, 0)
130 }
131
132 #[bench]
133 fn bench_from_iter_0010(b: &mut Bencher) {
134     do_bench_from_iter(b, 10)
135 }
136
137 #[bench]
138 fn bench_from_iter_0100(b: &mut Bencher) {
139     do_bench_from_iter(b, 100)
140 }
141
142 #[bench]
143 fn bench_from_iter_1000(b: &mut Bencher) {
144     do_bench_from_iter(b, 1000)
145 }
146
147 fn do_bench_extend(b: &mut Bencher, dst_len: usize, src_len: usize) {
148     let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
149     let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
150
151     b.bytes = src_len as u64;
152
153     b.iter(|| {
154         let mut dst = dst.clone();
155         dst.extend(src.clone());
156         dst
157     });
158 }
159
160 #[bench]
161 fn bench_extend_0000_0000(b: &mut Bencher) {
162     do_bench_extend(b, 0, 0)
163 }
164
165 #[bench]
166 fn bench_extend_0000_0010(b: &mut Bencher) {
167     do_bench_extend(b, 0, 10)
168 }
169
170 #[bench]
171 fn bench_extend_0000_0100(b: &mut Bencher) {
172     do_bench_extend(b, 0, 100)
173 }
174
175 #[bench]
176 fn bench_extend_0000_1000(b: &mut Bencher) {
177     do_bench_extend(b, 0, 1000)
178 }
179
180 #[bench]
181 fn bench_extend_0010_0010(b: &mut Bencher) {
182     do_bench_extend(b, 10, 10)
183 }
184
185 #[bench]
186 fn bench_extend_0100_0100(b: &mut Bencher) {
187     do_bench_extend(b, 100, 100)
188 }
189
190 #[bench]
191 fn bench_extend_1000_1000(b: &mut Bencher) {
192     do_bench_extend(b, 1000, 1000)
193 }
194
195 fn do_bench_extend_from_slice(b: &mut Bencher, dst_len: usize, src_len: usize) {
196     let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
197     let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
198
199     b.bytes = src_len as u64;
200
201     b.iter(|| {
202         let mut dst = dst.clone();
203         dst.extend_from_slice(&src);
204         dst
205     });
206 }
207
208 #[bench]
209 fn bench_extend_recycle(b: &mut Bencher) {
210     let mut data = vec![0; 1000];
211
212     b.iter(|| {
213         let tmp = std::mem::take(&mut data);
214         let mut to_extend = black_box(Vec::new());
215         to_extend.extend(tmp.into_iter());
216         data = black_box(to_extend);
217     });
218
219     black_box(data);
220 }
221
222 #[bench]
223 fn bench_extend_from_slice_0000_0000(b: &mut Bencher) {
224     do_bench_extend_from_slice(b, 0, 0)
225 }
226
227 #[bench]
228 fn bench_extend_from_slice_0000_0010(b: &mut Bencher) {
229     do_bench_extend_from_slice(b, 0, 10)
230 }
231
232 #[bench]
233 fn bench_extend_from_slice_0000_0100(b: &mut Bencher) {
234     do_bench_extend_from_slice(b, 0, 100)
235 }
236
237 #[bench]
238 fn bench_extend_from_slice_0000_1000(b: &mut Bencher) {
239     do_bench_extend_from_slice(b, 0, 1000)
240 }
241
242 #[bench]
243 fn bench_extend_from_slice_0010_0010(b: &mut Bencher) {
244     do_bench_extend_from_slice(b, 10, 10)
245 }
246
247 #[bench]
248 fn bench_extend_from_slice_0100_0100(b: &mut Bencher) {
249     do_bench_extend_from_slice(b, 100, 100)
250 }
251
252 #[bench]
253 fn bench_extend_from_slice_1000_1000(b: &mut Bencher) {
254     do_bench_extend_from_slice(b, 1000, 1000)
255 }
256
257 fn do_bench_clone(b: &mut Bencher, src_len: usize) {
258     let src: Vec<usize> = FromIterator::from_iter(0..src_len);
259
260     b.bytes = src_len as u64;
261
262     b.iter(|| src.clone());
263 }
264
265 #[bench]
266 fn bench_clone_0000(b: &mut Bencher) {
267     do_bench_clone(b, 0)
268 }
269
270 #[bench]
271 fn bench_clone_0010(b: &mut Bencher) {
272     do_bench_clone(b, 10)
273 }
274
275 #[bench]
276 fn bench_clone_0100(b: &mut Bencher) {
277     do_bench_clone(b, 100)
278 }
279
280 #[bench]
281 fn bench_clone_1000(b: &mut Bencher) {
282     do_bench_clone(b, 1000)
283 }
284
285 fn do_bench_clone_from(b: &mut Bencher, times: usize, dst_len: usize, src_len: usize) {
286     let dst: Vec<_> = FromIterator::from_iter(0..src_len);
287     let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
288
289     b.bytes = (times * src_len) as u64;
290
291     b.iter(|| {
292         let mut dst = dst.clone();
293
294         for _ in 0..times {
295             dst.clone_from(&src);
296             dst = black_box(dst);
297         }
298         dst
299     });
300 }
301
302 #[bench]
303 fn bench_clone_from_01_0000_0000(b: &mut Bencher) {
304     do_bench_clone_from(b, 1, 0, 0)
305 }
306
307 #[bench]
308 fn bench_clone_from_01_0000_0010(b: &mut Bencher) {
309     do_bench_clone_from(b, 1, 0, 10)
310 }
311
312 #[bench]
313 fn bench_clone_from_01_0000_0100(b: &mut Bencher) {
314     do_bench_clone_from(b, 1, 0, 100)
315 }
316
317 #[bench]
318 fn bench_clone_from_01_0000_1000(b: &mut Bencher) {
319     do_bench_clone_from(b, 1, 0, 1000)
320 }
321
322 #[bench]
323 fn bench_clone_from_01_0010_0010(b: &mut Bencher) {
324     do_bench_clone_from(b, 1, 10, 10)
325 }
326
327 #[bench]
328 fn bench_clone_from_01_0100_0100(b: &mut Bencher) {
329     do_bench_clone_from(b, 1, 100, 100)
330 }
331
332 #[bench]
333 fn bench_clone_from_01_1000_1000(b: &mut Bencher) {
334     do_bench_clone_from(b, 1, 1000, 1000)
335 }
336
337 #[bench]
338 fn bench_clone_from_01_0010_0100(b: &mut Bencher) {
339     do_bench_clone_from(b, 1, 10, 100)
340 }
341
342 #[bench]
343 fn bench_clone_from_01_0100_1000(b: &mut Bencher) {
344     do_bench_clone_from(b, 1, 100, 1000)
345 }
346
347 #[bench]
348 fn bench_clone_from_01_0010_0000(b: &mut Bencher) {
349     do_bench_clone_from(b, 1, 10, 0)
350 }
351
352 #[bench]
353 fn bench_clone_from_01_0100_0010(b: &mut Bencher) {
354     do_bench_clone_from(b, 1, 100, 10)
355 }
356
357 #[bench]
358 fn bench_clone_from_01_1000_0100(b: &mut Bencher) {
359     do_bench_clone_from(b, 1, 1000, 100)
360 }
361
362 #[bench]
363 fn bench_clone_from_10_0000_0000(b: &mut Bencher) {
364     do_bench_clone_from(b, 10, 0, 0)
365 }
366
367 #[bench]
368 fn bench_clone_from_10_0000_0010(b: &mut Bencher) {
369     do_bench_clone_from(b, 10, 0, 10)
370 }
371
372 #[bench]
373 fn bench_clone_from_10_0000_0100(b: &mut Bencher) {
374     do_bench_clone_from(b, 10, 0, 100)
375 }
376
377 #[bench]
378 fn bench_clone_from_10_0000_1000(b: &mut Bencher) {
379     do_bench_clone_from(b, 10, 0, 1000)
380 }
381
382 #[bench]
383 fn bench_clone_from_10_0010_0010(b: &mut Bencher) {
384     do_bench_clone_from(b, 10, 10, 10)
385 }
386
387 #[bench]
388 fn bench_clone_from_10_0100_0100(b: &mut Bencher) {
389     do_bench_clone_from(b, 10, 100, 100)
390 }
391
392 #[bench]
393 fn bench_clone_from_10_1000_1000(b: &mut Bencher) {
394     do_bench_clone_from(b, 10, 1000, 1000)
395 }
396
397 #[bench]
398 fn bench_clone_from_10_0010_0100(b: &mut Bencher) {
399     do_bench_clone_from(b, 10, 10, 100)
400 }
401
402 #[bench]
403 fn bench_clone_from_10_0100_1000(b: &mut Bencher) {
404     do_bench_clone_from(b, 10, 100, 1000)
405 }
406
407 #[bench]
408 fn bench_clone_from_10_0010_0000(b: &mut Bencher) {
409     do_bench_clone_from(b, 10, 10, 0)
410 }
411
412 #[bench]
413 fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
414     do_bench_clone_from(b, 10, 100, 10)
415 }
416
417 #[bench]
418 fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
419     do_bench_clone_from(b, 10, 1000, 100)
420 }
421
422 macro_rules! bench_in_place {
423     ($($fname:ident, $type:ty, $count:expr, $init:expr);*) => {
424         $(
425             #[bench]
426             fn $fname(b: &mut Bencher) {
427                 b.iter(|| {
428                     let src: Vec<$type> = black_box(vec![$init; $count]);
429                     src.into_iter()
430                         .enumerate()
431                         .map(|(idx, e)| idx as $type ^ e)
432                         .collect::<Vec<$type>>()
433                 });
434             }
435         )+
436     };
437 }
438
439 bench_in_place![
440     bench_in_place_xxu8_0010_i0,   u8,   10, 0;
441     bench_in_place_xxu8_0100_i0,   u8,  100, 0;
442     bench_in_place_xxu8_1000_i0,   u8, 1000, 0;
443     bench_in_place_xxu8_0010_i1,   u8,   10, 1;
444     bench_in_place_xxu8_0100_i1,   u8,  100, 1;
445     bench_in_place_xxu8_1000_i1,   u8, 1000, 1;
446     bench_in_place_xu32_0010_i0,  u32,   10, 0;
447     bench_in_place_xu32_0100_i0,  u32,  100, 0;
448     bench_in_place_xu32_1000_i0,  u32, 1000, 0;
449     bench_in_place_xu32_0010_i1,  u32,   10, 1;
450     bench_in_place_xu32_0100_i1,  u32,  100, 1;
451     bench_in_place_xu32_1000_i1,  u32, 1000, 1;
452     bench_in_place_u128_0010_i0, u128,   10, 0;
453     bench_in_place_u128_0100_i0, u128,  100, 0;
454     bench_in_place_u128_1000_i0, u128, 1000, 0;
455     bench_in_place_u128_0010_i1, u128,   10, 1;
456     bench_in_place_u128_0100_i1, u128,  100, 1;
457     bench_in_place_u128_1000_i1, u128, 1000, 1
458 ];
459
460 #[bench]
461 fn bench_in_place_recycle(b: &mut Bencher) {
462     let mut data = vec![0; 1000];
463
464     b.iter(|| {
465         let tmp = std::mem::take(&mut data);
466         data = black_box(
467             tmp.into_iter()
468                 .enumerate()
469                 .map(|(idx, e)| idx.wrapping_add(e))
470                 .fuse()
471                 .peekable()
472                 .collect::<Vec<usize>>(),
473         );
474     });
475 }
476
477 #[bench]
478 fn bench_in_place_zip_recycle(b: &mut Bencher) {
479     let mut data = vec![0u8; 1000];
480     let mut rng = rand::thread_rng();
481     let mut subst = vec![0u8; 1000];
482     rng.fill_bytes(&mut subst[..]);
483
484     b.iter(|| {
485         let tmp = std::mem::take(&mut data);
486         let mangled = tmp
487             .into_iter()
488             .zip(subst.iter().copied())
489             .enumerate()
490             .map(|(i, (d, s))| d.wrapping_add(i as u8) ^ s)
491             .collect::<Vec<_>>();
492         data = black_box(mangled);
493     });
494 }
495
496 #[bench]
497 fn bench_in_place_zip_iter_mut(b: &mut Bencher) {
498     let mut data = vec![0u8; 256];
499     let mut rng = rand::thread_rng();
500     let mut subst = vec![0u8; 1000];
501     rng.fill_bytes(&mut subst[..]);
502
503     b.iter(|| {
504         data.iter_mut().enumerate().for_each(|(i, d)| {
505             *d = d.wrapping_add(i as u8) ^ subst[i];
506         });
507     });
508
509     black_box(data);
510 }
511
512 pub fn vec_cast<T, U>(input: Vec<T>) -> Vec<U> {
513     input.into_iter().map(|e| unsafe { std::mem::transmute_copy(&e) }).collect()
514 }
515
516 #[bench]
517 fn bench_transmute(b: &mut Bencher) {
518     let mut vec = vec![10u32; 100];
519     b.bytes = 800; // 2 casts x 4 bytes x 100
520     b.iter(|| {
521         let v = std::mem::take(&mut vec);
522         let v = black_box(vec_cast::<u32, i32>(v));
523         let v = black_box(vec_cast::<i32, u32>(v));
524         vec = v;
525     });
526 }
527
528 #[derive(Clone)]
529 struct Droppable(usize);
530
531 impl Drop for Droppable {
532     fn drop(&mut self) {
533         black_box(self);
534     }
535 }
536
537 #[bench]
538 fn bench_in_place_collect_droppable(b: &mut Bencher) {
539     let v: Vec<Droppable> = std::iter::repeat_with(|| Droppable(0)).take(1000).collect();
540     b.iter(|| {
541         v.clone()
542             .into_iter()
543             .skip(100)
544             .enumerate()
545             .map(|(i, e)| Droppable(i ^ e.0))
546             .collect::<Vec<_>>()
547     })
548 }
549
550 const LEN: usize = 16384;
551
552 #[bench]
553 fn bench_chain_collect(b: &mut Bencher) {
554     let data = black_box([0; LEN]);
555     b.iter(|| data.iter().cloned().chain([1].iter().cloned()).collect::<Vec<_>>());
556 }
557
558 #[bench]
559 fn bench_chain_chain_collect(b: &mut Bencher) {
560     let data = black_box([0; LEN]);
561     b.iter(|| {
562         data.iter()
563             .cloned()
564             .chain([1].iter().cloned())
565             .chain([2].iter().cloned())
566             .collect::<Vec<_>>()
567     });
568 }
569
570 #[bench]
571 fn bench_nest_chain_chain_collect(b: &mut Bencher) {
572     let data = black_box([0; LEN]);
573     b.iter(|| {
574         data.iter().cloned().chain([1].iter().chain([2].iter()).cloned()).collect::<Vec<_>>()
575     });
576 }
577
578 #[bench]
579 fn bench_range_map_collect(b: &mut Bencher) {
580     b.iter(|| (0..LEN).map(|_| u32::default()).collect::<Vec<_>>());
581 }
582
583 #[bench]
584 fn bench_chain_extend_ref(b: &mut Bencher) {
585     let data = black_box([0; LEN]);
586     b.iter(|| {
587         let mut v = Vec::<u32>::with_capacity(data.len() + 1);
588         v.extend(data.iter().chain([1].iter()));
589         v
590     });
591 }
592
593 #[bench]
594 fn bench_chain_extend_value(b: &mut Bencher) {
595     let data = black_box([0; LEN]);
596     b.iter(|| {
597         let mut v = Vec::<u32>::with_capacity(data.len() + 1);
598         v.extend(data.iter().cloned().chain(Some(1)));
599         v
600     });
601 }
602
603 #[bench]
604 fn bench_rev_1(b: &mut Bencher) {
605     let data = black_box([0; LEN]);
606     b.iter(|| {
607         let mut v = Vec::<u32>::new();
608         v.extend(data.iter().rev());
609         v
610     });
611 }
612
613 #[bench]
614 fn bench_rev_2(b: &mut Bencher) {
615     let data = black_box([0; LEN]);
616     b.iter(|| {
617         let mut v = Vec::<u32>::with_capacity(data.len());
618         v.extend(data.iter().rev());
619         v
620     });
621 }
622
623 #[bench]
624 fn bench_map_regular(b: &mut Bencher) {
625     let data = black_box([(0, 0); LEN]);
626     b.iter(|| {
627         let mut v = Vec::<u32>::new();
628         v.extend(data.iter().map(|t| t.1));
629         v
630     });
631 }
632
633 #[bench]
634 fn bench_map_fast(b: &mut Bencher) {
635     let data = black_box([(0, 0); LEN]);
636     b.iter(|| {
637         let mut result = Vec::with_capacity(data.len());
638         for i in 0..data.len() {
639             unsafe {
640                 *result.get_unchecked_mut(i) = data[i].0;
641                 result.set_len(i);
642             }
643         }
644         result
645     });
646 }
647
648 fn random_sorted_fill(mut seed: u32, buf: &mut [u32]) {
649     let mask = if buf.len() < 8192 {
650         0xFF
651     } else if buf.len() < 200_000 {
652         0xFFFF
653     } else {
654         0xFFFF_FFFF
655     };
656
657     for item in buf.iter_mut() {
658         seed ^= seed << 13;
659         seed ^= seed >> 17;
660         seed ^= seed << 5;
661
662         *item = seed & mask;
663     }
664
665     buf.sort();
666 }
667
668 fn bench_vec_dedup_old(b: &mut Bencher, sz: usize) {
669     let mut template = vec![0u32; sz];
670     b.bytes = std::mem::size_of_val(template.as_slice()) as u64;
671     random_sorted_fill(0x43, &mut template);
672
673     let mut vec = template.clone();
674     b.iter(|| {
675         let len = {
676             let (dedup, _) = vec.partition_dedup();
677             dedup.len()
678         };
679         vec.truncate(len);
680
681         black_box(vec.first());
682         vec.clear();
683         vec.extend_from_slice(&template);
684     });
685 }
686
687 fn bench_vec_dedup_new(b: &mut Bencher, sz: usize) {
688     let mut template = vec![0u32; sz];
689     b.bytes = std::mem::size_of_val(template.as_slice()) as u64;
690     random_sorted_fill(0x43, &mut template);
691
692     let mut vec = template.clone();
693     b.iter(|| {
694         vec.dedup();
695         black_box(vec.first());
696         vec.clear();
697         vec.extend_from_slice(&template);
698     });
699 }
700
701 #[bench]
702 fn bench_dedup_old_100(b: &mut Bencher) {
703     bench_vec_dedup_old(b, 100);
704 }
705 #[bench]
706 fn bench_dedup_new_100(b: &mut Bencher) {
707     bench_vec_dedup_new(b, 100);
708 }
709
710 #[bench]
711 fn bench_dedup_old_1000(b: &mut Bencher) {
712     bench_vec_dedup_old(b, 1000);
713 }
714 #[bench]
715 fn bench_dedup_new_1000(b: &mut Bencher) {
716     bench_vec_dedup_new(b, 1000);
717 }
718
719 #[bench]
720 fn bench_dedup_old_10000(b: &mut Bencher) {
721     bench_vec_dedup_old(b, 10000);
722 }
723 #[bench]
724 fn bench_dedup_new_10000(b: &mut Bencher) {
725     bench_vec_dedup_new(b, 10000);
726 }
727
728 #[bench]
729 fn bench_dedup_old_100000(b: &mut Bencher) {
730     bench_vec_dedup_old(b, 100000);
731 }
732 #[bench]
733 fn bench_dedup_new_100000(b: &mut Bencher) {
734     bench_vec_dedup_new(b, 100000);
735 }