1+ use rand:: prelude:: * ;
12use std:: iter:: { repeat, FromIterator } ;
2- use test:: Bencher ;
3+ use test:: { black_box , Bencher } ;
34
45#[ bench]
56fn bench_new ( b : & mut Bencher ) {
67 b. iter ( || {
78 let v: Vec < u32 > = Vec :: new ( ) ;
89 assert_eq ! ( v. len( ) , 0 ) ;
910 assert_eq ! ( v. capacity( ) , 0 ) ;
11+ v
1012 } )
1113}
1214
@@ -17,6 +19,7 @@ fn do_bench_with_capacity(b: &mut Bencher, src_len: usize) {
1719 let v: Vec < u32 > = Vec :: with_capacity ( src_len) ;
1820 assert_eq ! ( v. len( ) , 0 ) ;
1921 assert_eq ! ( v. capacity( ) , src_len) ;
22+ v
2023 } )
2124}
2225
@@ -47,6 +50,7 @@ fn do_bench_from_fn(b: &mut Bencher, src_len: usize) {
4750 let dst = ( 0 ..src_len) . collect :: < Vec < _ > > ( ) ;
4851 assert_eq ! ( dst. len( ) , src_len) ;
4952 assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
53+ dst
5054 } )
5155}
5256
@@ -77,6 +81,7 @@ fn do_bench_from_elem(b: &mut Bencher, src_len: usize) {
7781 let dst: Vec < usize > = repeat ( 5 ) . take ( src_len) . collect ( ) ;
7882 assert_eq ! ( dst. len( ) , src_len) ;
7983 assert ! ( dst. iter( ) . all( |x| * x == 5 ) ) ;
84+ dst
8085 } )
8186}
8287
@@ -109,6 +114,7 @@ fn do_bench_from_slice(b: &mut Bencher, src_len: usize) {
109114 let dst = src. clone ( ) [ ..] . to_vec ( ) ;
110115 assert_eq ! ( dst. len( ) , src_len) ;
111116 assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
117+ dst
112118 } ) ;
113119}
114120
@@ -141,6 +147,7 @@ fn do_bench_from_iter(b: &mut Bencher, src_len: usize) {
141147 let dst: Vec < _ > = FromIterator :: from_iter ( src. clone ( ) ) ;
142148 assert_eq ! ( dst. len( ) , src_len) ;
143149 assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
150+ dst
144151 } ) ;
145152}
146153
@@ -175,6 +182,7 @@ fn do_bench_extend(b: &mut Bencher, dst_len: usize, src_len: usize) {
175182 dst. extend ( src. clone ( ) ) ;
176183 assert_eq ! ( dst. len( ) , dst_len + src_len) ;
177184 assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
185+ dst
178186 } ) ;
179187}
180188
@@ -224,9 +232,24 @@ fn do_bench_push_all(b: &mut Bencher, dst_len: usize, src_len: usize) {
224232 dst. extend_from_slice ( & src) ;
225233 assert_eq ! ( dst. len( ) , dst_len + src_len) ;
226234 assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
235+ dst
227236 } ) ;
228237}
229238
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+
230253#[ bench]
231254fn bench_push_all_0000_0000 ( b : & mut Bencher ) {
232255 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) {
273296 dst. extend ( src. clone ( ) ) ;
274297 assert_eq ! ( dst. len( ) , dst_len + src_len) ;
275298 assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
299+ dst
276300 } ) ;
277301}
278302
@@ -320,6 +344,7 @@ fn do_bench_clone(b: &mut Bencher, src_len: usize) {
320344 let dst = src. clone ( ) ;
321345 assert_eq ! ( dst. len( ) , src_len) ;
322346 assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | i == * x) ) ;
347+ dst
323348 } ) ;
324349}
325350
@@ -354,10 +379,10 @@ fn do_bench_clone_from(b: &mut Bencher, times: usize, dst_len: usize, src_len: u
354379
355380 for _ in 0 ..times {
356381 dst. clone_from ( & src) ;
357-
358382 assert_eq ! ( dst. len( ) , src_len) ;
359383 assert ! ( dst. iter( ) . enumerate( ) . all( |( i, x) | dst_len + i == * x) ) ;
360384 }
385+ dst
361386 } ) ;
362387}
363388
@@ -480,3 +505,223 @@ fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
480505fn bench_clone_from_10_1000_0100 ( b : & mut Bencher ) {
481506 do_bench_clone_from ( b, 10 , 1000 , 100 )
482507}
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