1
+ use rand:: prelude:: * ;
1
2
use std:: iter:: { repeat, FromIterator } ;
2
- use test:: Bencher ;
3
+ use test:: { black_box , Bencher } ;
3
4
4
5
#[ bench]
5
6
fn bench_new ( b : & mut Bencher ) {
6
7
b. iter ( || {
7
8
let v: Vec < u32 > = Vec :: new ( ) ;
8
9
assert_eq ! ( v. len( ) , 0 ) ;
9
10
assert_eq ! ( v. capacity( ) , 0 ) ;
11
+ v
10
12
} )
11
13
}
12
14
@@ -17,6 +19,7 @@ fn do_bench_with_capacity(b: &mut Bencher, src_len: usize) {
17
19
let v: Vec < u32 > = Vec :: with_capacity ( src_len) ;
18
20
assert_eq ! ( v. len( ) , 0 ) ;
19
21
assert_eq ! ( v. capacity( ) , src_len) ;
22
+ v
20
23
} )
21
24
}
22
25
@@ -47,6 +50,7 @@ fn do_bench_from_fn(b: &mut Bencher, src_len: usize) {
47
50
let dst = ( 0 ..src_len) . collect :: < Vec < _ > > ( ) ;
48
51
assert_eq ! ( dst. len( ) , src_len) ;
49
52
assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
53
+ dst
50
54
} )
51
55
}
52
56
@@ -77,6 +81,7 @@ fn do_bench_from_elem(b: &mut Bencher, src_len: usize) {
77
81
let dst: Vec < usize > = repeat ( 5 ) . take ( src_len) . collect ( ) ;
78
82
assert_eq ! ( dst. len( ) , src_len) ;
79
83
assert ! ( dst. iter( ) . all( |x| * x == 5 ) ) ;
84
+ dst
80
85
} )
81
86
}
82
87
@@ -109,6 +114,7 @@ fn do_bench_from_slice(b: &mut Bencher, src_len: usize) {
109
114
let dst = src. clone ( ) [ ..] . to_vec ( ) ;
110
115
assert_eq ! ( dst. len( ) , src_len) ;
111
116
assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
117
+ dst
112
118
} ) ;
113
119
}
114
120
@@ -141,6 +147,7 @@ fn do_bench_from_iter(b: &mut Bencher, src_len: usize) {
141
147
let dst: Vec < _ > = FromIterator :: from_iter ( src. clone ( ) ) ;
142
148
assert_eq ! ( dst. len( ) , src_len) ;
143
149
assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
150
+ dst
144
151
} ) ;
145
152
}
146
153
@@ -175,6 +182,7 @@ fn do_bench_extend(b: &mut Bencher, dst_len: usize, src_len: usize) {
175
182
dst. extend ( src. clone ( ) ) ;
176
183
assert_eq ! ( dst. len( ) , dst_len + src_len) ;
177
184
assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
185
+ dst
178
186
} ) ;
179
187
}
180
188
@@ -224,9 +232,24 @@ fn do_bench_push_all(b: &mut Bencher, dst_len: usize, src_len: usize) {
224
232
dst. extend_from_slice ( & src) ;
225
233
assert_eq ! ( dst. len( ) , dst_len + src_len) ;
226
234
assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
235
+ dst
227
236
} ) ;
228
237
}
229
238
239
+ #[ bench]
240
+ fn bench_extend_recycle ( b : & mut Bencher ) {
241
+ let mut data = vec ! [ 0 ; 1000 ] ;
242
+
243
+ b. iter ( || {
244
+ let tmp = std:: mem:: replace ( & mut data, Vec :: new ( ) ) ;
245
+ let mut to_extend = black_box ( Vec :: new ( ) ) ;
246
+ to_extend. extend ( tmp. into_iter ( ) ) ;
247
+ std:: mem:: replace ( & mut data, black_box ( to_extend) ) ;
248
+ } ) ;
249
+
250
+ black_box ( data) ;
251
+ }
252
+
230
253
#[ bench]
231
254
fn bench_push_all_0000_0000 ( b : & mut Bencher ) {
232
255
do_bench_push_all ( b, 0 , 0 )
@@ -273,6 +296,7 @@ fn do_bench_push_all_move(b: &mut Bencher, dst_len: usize, src_len: usize) {
273
296
dst. extend ( src. clone ( ) ) ;
274
297
assert_eq ! ( dst. len( ) , dst_len + src_len) ;
275
298
assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
299
+ dst
276
300
} ) ;
277
301
}
278
302
@@ -320,6 +344,7 @@ fn do_bench_clone(b: &mut Bencher, src_len: usize) {
320
344
let dst = src. clone ( ) ;
321
345
assert_eq ! ( dst. len( ) , src_len) ;
322
346
assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
347
+ dst
323
348
} ) ;
324
349
}
325
350
@@ -354,10 +379,10 @@ fn do_bench_clone_from(b: &mut Bencher, times: usize, dst_len: usize, src_len: u
354
379
355
380
for _ in 0 ..times {
356
381
dst. clone_from ( & src) ;
357
-
358
382
assert_eq ! ( dst. len( ) , src_len) ;
359
383
assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | dst_len + i == * x) ) ;
360
384
}
385
+ dst
361
386
} ) ;
362
387
}
363
388
@@ -480,3 +505,223 @@ fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
480
505
fn bench_clone_from_10_1000_0100 ( b : & mut Bencher ) {
481
506
do_bench_clone_from ( b, 10 , 1000 , 100 )
482
507
}
508
+
509
+ macro_rules! bench_in_place {
510
+ (
511
+ $( $fname: ident, $type: ty , $count: expr, $init: expr) ;*
512
+ ) => {
513
+ $(
514
+ #[ bench]
515
+ fn $fname( b: & mut Bencher ) {
516
+ b. iter( || {
517
+ let src: Vec <$type> = black_box( vec![ $init; $count] ) ;
518
+ let mut sink = src. into_iter( )
519
+ . enumerate( )
520
+ . map( |( idx, e) | { ( idx as $type) ^ e } ) . collect:: <Vec <$type>>( ) ;
521
+ black_box( sink. as_mut_ptr( ) )
522
+ } ) ;
523
+ }
524
+ ) +
525
+ } ;
526
+ }
527
+
528
+ bench_in_place ! [
529
+ bench_in_place_xxu8_i0_0010, u8 , 10 , 0 ;
530
+ bench_in_place_xxu8_i0_0100, u8 , 100 , 0 ;
531
+ bench_in_place_xxu8_i0_1000, u8 , 1000 , 0 ;
532
+ bench_in_place_xxu8_i1_0010, u8 , 10 , 1 ;
533
+ bench_in_place_xxu8_i1_0100, u8 , 100 , 1 ;
534
+ bench_in_place_xxu8_i1_1000, u8 , 1000 , 1 ;
535
+ bench_in_place_xu32_i0_0010, u32 , 10 , 0 ;
536
+ bench_in_place_xu32_i0_0100, u32 , 100 , 0 ;
537
+ bench_in_place_xu32_i0_1000, u32 , 1000 , 0 ;
538
+ bench_in_place_xu32_i1_0010, u32 , 10 , 1 ;
539
+ bench_in_place_xu32_i1_0100, u32 , 100 , 1 ;
540
+ bench_in_place_xu32_i1_1000, u32 , 1000 , 1 ;
541
+ bench_in_place_u128_i0_0010, u128 , 10 , 0 ;
542
+ bench_in_place_u128_i0_0100, u128 , 100 , 0 ;
543
+ bench_in_place_u128_i0_1000, u128 , 1000 , 0 ;
544
+ bench_in_place_u128_i1_0010, u128 , 10 , 1 ;
545
+ bench_in_place_u128_i1_0100, u128 , 100 , 1 ;
546
+ bench_in_place_u128_i1_1000, u128 , 1000 , 1
547
+ ] ;
548
+
549
+ #[ bench]
550
+ fn bench_in_place_recycle ( b : & mut test:: Bencher ) {
551
+ let mut data = vec ! [ 0 ; 1000 ] ;
552
+
553
+ b. iter ( || {
554
+ let tmp = std:: mem:: replace ( & mut data, Vec :: new ( ) ) ;
555
+ std:: mem:: replace (
556
+ & mut data,
557
+ black_box (
558
+ tmp. into_iter ( )
559
+ . enumerate ( )
560
+ . map ( |( idx, e) | idx. wrapping_add ( e) )
561
+ . fuse ( )
562
+ . peekable ( )
563
+ . collect :: < Vec < usize > > ( ) ,
564
+ ) ,
565
+ ) ;
566
+ } ) ;
567
+ }
568
+
569
+ #[ bench]
570
+ fn bench_in_place_zip_recycle ( b : & mut test:: Bencher ) {
571
+ let mut data = vec ! [ 0u8 ; 1000 ] ;
572
+ let mut rng = rand:: thread_rng ( ) ;
573
+ let mut subst = vec ! [ 0u8 ; 1000 ] ;
574
+ rng. fill_bytes ( & mut subst[ ..] ) ;
575
+
576
+ b. iter ( || {
577
+ let tmp = std:: mem:: replace ( & mut data, Vec :: new ( ) ) ;
578
+ let mangled = tmp
579
+ . into_iter ( )
580
+ . zip ( subst. iter ( ) . copied ( ) )
581
+ . enumerate ( )
582
+ . map ( |( i, ( d, s) ) | d. wrapping_add ( i as u8 ) ^ s)
583
+ . collect :: < Vec < _ > > ( ) ;
584
+ assert_eq ! ( mangled. len( ) , 1000 ) ;
585
+ std:: mem:: replace ( & mut data, black_box ( mangled) ) ;
586
+ } ) ;
587
+ }
588
+
589
+ #[ bench]
590
+ fn bench_in_place_zip_iter_mut ( b : & mut test:: Bencher ) {
591
+ let mut data = vec ! [ 0u8 ; 256 ] ;
592
+ let mut rng = rand:: thread_rng ( ) ;
593
+ let mut subst = vec ! [ 0u8 ; 1000 ] ;
594
+ rng. fill_bytes ( & mut subst[ ..] ) ;
595
+
596
+ b. iter ( || {
597
+ data. iter_mut ( ) . enumerate ( ) . for_each ( |( i, d) | {
598
+ * d = d. wrapping_add ( i as u8 ) ^ subst[ i] ;
599
+ } ) ;
600
+ } ) ;
601
+
602
+ black_box ( data) ;
603
+ }
604
+
605
+ #[ derive( Clone ) ]
606
+ struct Droppable ( usize ) ;
607
+
608
+ impl Drop for Droppable {
609
+ fn drop ( & mut self ) {
610
+ black_box ( self ) ;
611
+ }
612
+ }
613
+
614
+ #[ bench]
615
+ fn bench_in_place_collect_droppable ( b : & mut test:: Bencher ) {
616
+ let v: Vec < Droppable > = std:: iter:: repeat_with ( || Droppable ( 0 ) ) . take ( 1000 ) . collect ( ) ;
617
+ b. iter ( || {
618
+ v. clone ( )
619
+ . into_iter ( )
620
+ . skip ( 100 )
621
+ . enumerate ( )
622
+ . map ( |( i, e) | Droppable ( i ^ e. 0 ) )
623
+ . collect :: < Vec < _ > > ( )
624
+ } )
625
+ }
626
+
627
+ #[ bench]
628
+ fn bench_chain_collect ( b : & mut test:: Bencher ) {
629
+ let data = black_box ( [ 0 ; LEN ] ) ;
630
+ b. iter ( || data. iter ( ) . cloned ( ) . chain ( [ 1 ] . iter ( ) . cloned ( ) ) . collect :: < Vec < _ > > ( ) ) ;
631
+ }
632
+
633
+ #[ bench]
634
+ fn bench_chain_chain_collect ( b : & mut test:: Bencher ) {
635
+ let data = black_box ( [ 0 ; LEN ] ) ;
636
+ b. iter ( || {
637
+ data. iter ( )
638
+ . cloned ( )
639
+ . chain ( [ 1 ] . iter ( ) . cloned ( ) )
640
+ . chain ( [ 2 ] . iter ( ) . cloned ( ) )
641
+ . collect :: < Vec < _ > > ( )
642
+ } ) ;
643
+ }
644
+
645
+ #[ bench]
646
+ fn bench_nest_chain_chain_collect ( b : & mut test:: Bencher ) {
647
+ let data = black_box ( [ 0 ; LEN ] ) ;
648
+ b. iter ( || {
649
+ data. iter ( ) . cloned ( ) . chain ( [ 1 ] . iter ( ) . chain ( [ 2 ] . iter ( ) ) . cloned ( ) ) . collect :: < Vec < _ > > ( )
650
+ } ) ;
651
+ }
652
+
653
+ pub fn example_plain_slow ( l : & [ u32 ] ) -> Vec < u32 > {
654
+ let mut result = Vec :: with_capacity ( l. len ( ) ) ;
655
+ result. extend ( l. iter ( ) . rev ( ) ) ;
656
+ result
657
+ }
658
+
659
+ pub fn map_fast ( l : & [ ( u32 , u32 ) ] ) -> Vec < u32 > {
660
+ let mut result = Vec :: with_capacity ( l. len ( ) ) ;
661
+ for i in 0 ..l. len ( ) {
662
+ unsafe {
663
+ * result. get_unchecked_mut ( i) = l[ i] . 0 ;
664
+ result. set_len ( i) ;
665
+ }
666
+ }
667
+ result
668
+ }
669
+
670
+ const LEN : usize = 16384 ;
671
+
672
+ #[ bench]
673
+ fn bench_range_map_collect ( b : & mut test:: Bencher ) {
674
+ b. iter ( || ( 0 ..LEN ) . map ( |_| u32:: default ( ) ) . collect :: < Vec < _ > > ( ) ) ;
675
+ }
676
+
677
+ #[ bench]
678
+ fn bench_chain_extend_ref ( b : & mut test:: Bencher ) {
679
+ let data = black_box ( [ 0 ; LEN ] ) ;
680
+ b. iter ( || {
681
+ let mut v = Vec :: < u32 > :: with_capacity ( data. len ( ) + 1 ) ;
682
+ v. extend ( data. iter ( ) . chain ( [ 1 ] . iter ( ) ) ) ;
683
+ v
684
+ } ) ;
685
+ }
686
+
687
+ #[ bench]
688
+ fn bench_chain_extend_value ( b : & mut test:: Bencher ) {
689
+ let data = black_box ( [ 0 ; LEN ] ) ;
690
+ b. iter ( || {
691
+ let mut v = Vec :: < u32 > :: with_capacity ( data. len ( ) + 1 ) ;
692
+ v. extend ( data. iter ( ) . cloned ( ) . chain ( Some ( 1 ) ) ) ;
693
+ v
694
+ } ) ;
695
+ }
696
+
697
+ #[ bench]
698
+ fn bench_rev_1 ( b : & mut test:: Bencher ) {
699
+ let data = black_box ( [ 0 ; LEN ] ) ;
700
+ b. iter ( || {
701
+ let mut v = Vec :: < u32 > :: new ( ) ;
702
+ v. extend ( data. iter ( ) . rev ( ) ) ;
703
+ v
704
+ } ) ;
705
+ }
706
+
707
+ #[ bench]
708
+ fn bench_rev_2 ( b : & mut test:: Bencher ) {
709
+ let data = black_box ( [ 0 ; LEN ] ) ;
710
+ b. iter ( || example_plain_slow ( & data) ) ;
711
+ }
712
+
713
+ #[ bench]
714
+ fn bench_map_regular ( b : & mut test:: Bencher ) {
715
+ let data = black_box ( [ ( 0 , 0 ) ; LEN ] ) ;
716
+ b. iter ( || {
717
+ let mut v = Vec :: < u32 > :: new ( ) ;
718
+ v. extend ( data. iter ( ) . map ( |t| t. 1 ) ) ;
719
+ v
720
+ } ) ;
721
+ }
722
+
723
+ #[ bench]
724
+ fn bench_map_fast ( b : & mut test:: Bencher ) {
725
+ let data = black_box ( [ ( 0 , 0 ) ; LEN ] ) ;
726
+ b. iter ( || map_fast ( & data) ) ;
727
+ }
0 commit comments