44extern crate smallvec;
55extern crate test;
66
7- use smallvec:: SmallVec ;
87use self :: test:: Bencher ;
8+ use smallvec:: { ExtendFromSlice , SmallVec } ;
99
10- #[ bench]
11- fn bench_push ( b : & mut Bencher ) {
12- #[ inline( never) ]
13- fn push_noinline ( vec : & mut SmallVec < [ u64 ; 16 ] > , x : u64 ) {
14- vec. push ( x)
15- }
10+ const VEC_SIZE : usize = 16 ;
11+ const SPILLED_SIZE : usize = 100 ;
1612
17- b . iter ( || {
18- let mut vec : SmallVec < [ u64 ; 16 ] > = SmallVec :: new ( ) ;
19- for x in 0 .. 100 {
20- push_noinline ( & mut vec , x ) ;
21- }
22- vec
23- } ) ;
13+ trait Vector < T > : for < ' a > From < & ' a [ T ] > + Extend < T > + ExtendFromSlice < T > {
14+ fn new ( ) -> Self ;
15+ fn push ( & mut self , val : T ) ;
16+ fn pop ( & mut self ) -> Option < T > ;
17+ fn remove ( & mut self , p : usize ) -> T ;
18+ fn insert ( & mut self , n : usize , val : T ) ;
19+ fn from_elem ( val : T , n : usize ) -> Self ;
2420}
2521
26- #[ bench]
27- fn bench_insert ( b : & mut Bencher ) {
28- #[ inline( never) ]
29- fn insert_noinline ( vec : & mut SmallVec < [ u64 ; 16 ] > , x : u64 ) {
30- vec. insert ( 0 , x)
22+ impl < T : Copy > Vector < T > for Vec < T > {
23+ fn new ( ) -> Self {
24+ Self :: with_capacity ( VEC_SIZE )
3125 }
3226
33- b. iter ( || {
34- let mut vec: SmallVec < [ u64 ; 16 ] > = SmallVec :: new ( ) ;
35- for x in 0 ..100 {
36- insert_noinline ( & mut vec, x) ;
37- }
38- vec
39- } ) ;
27+ fn push ( & mut self , val : T ) {
28+ self . push ( val)
29+ }
30+
31+ fn pop ( & mut self ) -> Option < T > {
32+ self . pop ( )
33+ }
34+
35+ fn remove ( & mut self , p : usize ) -> T {
36+ self . remove ( p)
37+ }
38+
39+ fn insert ( & mut self , n : usize , val : T ) {
40+ self . insert ( n, val)
41+ }
42+
43+ fn from_elem ( val : T , n : usize ) -> Self {
44+ vec ! [ val; n]
45+ }
4046}
4147
42- #[ bench]
43- fn bench_insert_many ( b : & mut Bencher ) {
44- #[ inline( never) ]
45- fn insert_many_noinline < I : IntoIterator < Item =u64 > > (
46- vec : & mut SmallVec < [ u64 ; 16 ] > , index : usize , iterable : I ) {
47- vec. insert_many ( index, iterable)
48+ impl < T : Copy > Vector < T > for SmallVec < [ T ; VEC_SIZE ] > {
49+ fn new ( ) -> Self {
50+ Self :: new ( )
4851 }
4952
50- b. iter ( || {
51- let mut vec: SmallVec < [ u64 ; 16 ] > = SmallVec :: new ( ) ;
52- insert_many_noinline ( & mut vec, 0 , 0 ..100 ) ;
53- insert_many_noinline ( & mut vec, 0 , 0 ..100 ) ;
54- vec
55- } ) ;
53+ fn push ( & mut self , val : T ) {
54+ self . push ( val)
55+ }
56+
57+ fn pop ( & mut self ) -> Option < T > {
58+ self . pop ( )
59+ }
60+
61+ fn remove ( & mut self , p : usize ) -> T {
62+ self . remove ( p)
63+ }
64+
65+ fn insert ( & mut self , n : usize , val : T ) {
66+ self . insert ( n, val)
67+ }
68+
69+ fn from_elem ( val : T , n : usize ) -> Self {
70+ smallvec ! [ val; n]
71+ }
5672}
5773
58- #[ bench]
59- fn bench_extend ( b : & mut Bencher ) {
60- b. iter ( || {
61- let mut vec: SmallVec < [ u64 ; 16 ] > = SmallVec :: new ( ) ;
62- vec. extend ( 0 ..100 ) ;
63- vec
64- } ) ;
74+ macro_rules! make_benches {
75+ ( $typ: ty { $( $b_name: ident => $g_name: ident( $( $args: expr) ,* ) , ) * } ) => {
76+ $(
77+ #[ bench]
78+ fn $b_name( b: & mut Bencher ) {
79+ $g_name:: <$typ>( $( $args, ) * b)
80+ }
81+ ) *
82+ }
6583}
6684
67- #[ bench]
68- fn bench_from_slice ( b : & mut Bencher ) {
69- let v: Vec < u64 > = ( 0 ..100 ) . collect ( ) ;
70- b. iter ( || {
71- let vec: SmallVec < [ u64 ; 16 ] > = SmallVec :: from_slice ( & v) ;
72- vec
73- } ) ;
85+ make_benches ! {
86+ SmallVec <[ u64 ; VEC_SIZE ] > {
87+ bench_push => gen_push( SPILLED_SIZE as _) ,
88+ bench_push_small => gen_push( VEC_SIZE as _) ,
89+ bench_insert => gen_insert( SPILLED_SIZE as _) ,
90+ bench_insert_small => gen_insert( VEC_SIZE as _) ,
91+ bench_remove => gen_remove( SPILLED_SIZE as _) ,
92+ bench_remove_small => gen_remove( VEC_SIZE as _) ,
93+ bench_extend => gen_extend( SPILLED_SIZE as _) ,
94+ bench_extend_small => gen_extend( VEC_SIZE as _) ,
95+ bench_from_slice => gen_from_slice( SPILLED_SIZE as _) ,
96+ bench_from_slice_small => gen_from_slice( VEC_SIZE as _) ,
97+ bench_extend_from_slice => gen_extend_from_slice( SPILLED_SIZE as _) ,
98+ bench_extend_from_slice_small => gen_extend_from_slice( VEC_SIZE as _) ,
99+ bench_macro_from_elem => gen_from_elem( SPILLED_SIZE as _) ,
100+ bench_macro_from_elem_small => gen_from_elem( VEC_SIZE as _) ,
101+ bench_pushpop => gen_pushpop( ) ,
102+ }
74103}
75104
76- #[ bench]
77- fn bench_extend_from_slice ( b : & mut Bencher ) {
78- let v: Vec < u64 > = ( 0 ..100 ) . collect ( ) ;
105+ make_benches ! {
106+ Vec <u64 > {
107+ bench_push_vec => gen_push( SPILLED_SIZE as _) ,
108+ bench_push_vec_small => gen_push( VEC_SIZE as _) ,
109+ bench_insert_vec => gen_insert( SPILLED_SIZE as _) ,
110+ bench_insert_vec_small => gen_insert( VEC_SIZE as _) ,
111+ bench_remove_vec => gen_remove( SPILLED_SIZE as _) ,
112+ bench_remove_vec_small => gen_remove( VEC_SIZE as _) ,
113+ bench_extend_vec => gen_extend( SPILLED_SIZE as _) ,
114+ bench_extend_vec_small => gen_extend( VEC_SIZE as _) ,
115+ bench_from_slice_vec => gen_from_slice( SPILLED_SIZE as _) ,
116+ bench_from_slice_vec_small => gen_from_slice( VEC_SIZE as _) ,
117+ bench_extend_from_slice_vec => gen_extend_from_slice( SPILLED_SIZE as _) ,
118+ bench_extend_from_slice_vec_small => gen_extend_from_slice( VEC_SIZE as _) ,
119+ bench_macro_from_elem_vec => gen_from_elem( SPILLED_SIZE as _) ,
120+ bench_macro_from_elem_vec_small => gen_from_elem( VEC_SIZE as _) ,
121+ bench_pushpop_vec => gen_pushpop( ) ,
122+ }
123+ }
124+
125+ fn gen_push < V : Vector < u64 > > ( n : u64 , b : & mut Bencher ) {
126+ #[ inline( never) ]
127+ fn push_noinline < V : Vector < u64 > > ( vec : & mut V , x : u64 ) {
128+ vec. push ( x) ;
129+ }
130+
79131 b. iter ( || {
80- let mut vec: SmallVec < [ u64 ; 16 ] > = SmallVec :: new ( ) ;
81- vec. extend_from_slice ( & v) ;
132+ let mut vec = V :: new ( ) ;
133+ for x in 0 ..n {
134+ push_noinline ( & mut vec, x) ;
135+ }
82136 vec
83137 } ) ;
84138}
85139
86- #[ bench]
87- fn bench_insert_from_slice ( b : & mut Bencher ) {
88- let v: Vec < u64 > = ( 0 ..100 ) . collect ( ) ;
140+ fn gen_insert < V : Vector < u64 > > ( n : u64 , b : & mut Bencher ) {
141+ #[ inline( never) ]
142+ fn insert_noinline < V : Vector < u64 > > ( vec : & mut V , p : usize , x : u64 ) {
143+ vec. insert ( p, x)
144+ }
145+
89146 b. iter ( || {
90- let mut vec: SmallVec < [ u64 ; 16 ] > = SmallVec :: new ( ) ;
91- vec. insert_from_slice ( 0 , & v) ;
92- vec. insert_from_slice ( 0 , & v) ;
147+ let mut vec = V :: new ( ) ;
148+ // Add one element, with each iteration we insert one before the end.
149+ // This means that we benchmark the insertion operation and not the
150+ // time it takes to `ptr::copy` the data.
151+ vec. push ( 0 ) ;
152+ for x in 0 ..n {
153+ insert_noinline ( & mut vec, x as _ , x) ;
154+ }
93155 vec
94156 } ) ;
95157}
96158
97- #[ bench]
98- fn bench_pushpop ( b : & mut Bencher ) {
159+ fn gen_remove < V : Vector < u64 > > ( n : usize , b : & mut Bencher ) {
99160 #[ inline( never) ]
100- fn pushpop_noinline ( vec : & mut SmallVec < [ u64 ; 16 ] > , x : u64 ) {
101- vec. push ( x) ;
102- vec. pop ( ) ;
161+ fn remove_noinline < V : Vector < u64 > > ( vec : & mut V , p : usize ) {
162+ vec. remove ( p) ;
103163 }
104164
105165 b. iter ( || {
106- let mut vec: SmallVec < [ u64 ; 16 ] > = SmallVec :: new ( ) ;
107- for x in 0 ..100 {
108- pushpop_noinline ( & mut vec, x) ;
166+ let mut vec = V :: from_elem ( 0 , n as _ ) ;
167+
168+ for x in ( 0 ..n - 1 ) . rev ( ) {
169+ remove_noinline ( & mut vec, x)
109170 }
110- vec
111171 } ) ;
112172}
113173
114- #[ bench]
115- fn bench_macro_from_elem ( b : & mut Bencher ) {
174+ fn gen_extend < V : Vector < u64 > > ( n : u64 , b : & mut Bencher ) {
116175 b. iter ( || {
117- let vec: SmallVec < [ u64 ; 16 ] > = smallvec ! [ 42 ; 100 ] ;
176+ let mut vec = V :: new ( ) ;
177+ vec. extend ( 0 ..n) ;
118178 vec
119179 } ) ;
120180}
121181
122- # [ bench ]
123- fn bench_macro_from_list ( b : & mut Bencher ) {
182+ fn gen_from_slice < V : Vector < u64 > > ( n : u64 , b : & mut Bencher ) {
183+ let v : Vec < u64 > = ( 0 ..n ) . collect ( ) ;
124184 b. iter ( || {
125- let vec: SmallVec < [ u64 ; 16 ] > = smallvec ! [
126- 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 20 , 24 , 32 , 36 , 0x40 , 0x80 ,
127- 0x100 , 0x200 , 0x400 , 0x800 , 0x1000 , 0x2000 , 0x4000 , 0x8000 , 0x10000 , 0x20000 , 0x40000 ,
128- 0x80000 , 0x100000
129- ] ;
185+ let vec = V :: from ( & v) ;
130186 vec
131187 } ) ;
132188}
133- #[ bench]
134- fn bench_push_vec ( b : & mut Bencher ) {
135- #[ inline( never) ]
136- fn push_noinline ( vec : & mut Vec < u64 > , x : u64 ) {
137- vec. push ( x)
138- }
139189
190+ fn gen_extend_from_slice < V : Vector < u64 > > ( n : u64 , b : & mut Bencher ) {
191+ let v: Vec < u64 > = ( 0 ..n) . collect ( ) ;
140192 b. iter ( || {
141- let mut vec: Vec < u64 > = Vec :: with_capacity ( 16 ) ;
142- for x in 0 ..100 {
143- push_noinline ( & mut vec, x) ;
144- }
193+ let mut vec = V :: new ( ) ;
194+ vec. extend_from_slice ( & v) ;
145195 vec
146196 } ) ;
147197}
148198
149- #[ bench]
150- fn bench_insert_vec ( b : & mut Bencher ) {
199+ fn gen_pushpop < V : Vector < u64 > > ( b : & mut Bencher ) {
151200 #[ inline( never) ]
152- fn insert_noinline ( vec : & mut Vec < u64 > , x : u64 ) {
153- vec. insert ( 0 , x)
201+ fn pushpop_noinline < V : Vector < u64 > > ( vec : & mut V , x : u64 ) -> Option < u64 > {
202+ vec. push ( x) ;
203+ vec. pop ( )
154204 }
155205
156206 b. iter ( || {
157- let mut vec: Vec < u64 > = Vec :: with_capacity ( 16 ) ;
158- for x in 0 ..100 {
159- insert_noinline ( & mut vec, x) ;
207+ let mut vec = V :: new ( ) ;
208+ for x in 0 ..SPILLED_SIZE as _ {
209+ pushpop_noinline ( & mut vec, x) ;
160210 }
161211 vec
162212 } ) ;
163213}
164214
165- #[ bench]
166- fn bench_extend_vec ( b : & mut Bencher ) {
215+ fn gen_from_elem < V : Vector < u64 > > ( n : usize , b : & mut Bencher ) {
167216 b. iter ( || {
168- let mut vec: Vec < u64 > = Vec :: with_capacity ( 16 ) ;
169- vec. extend ( 0 ..100 ) ;
217+ let vec = V :: from_elem ( 42 , n) ;
170218 vec
171219 } ) ;
172220}
173221
174222#[ bench]
175- fn bench_from_slice_vec ( b : & mut Bencher ) {
176- let v: Vec < u64 > = ( 0 ..100 ) . collect ( ) ;
177- b. iter ( || {
178- let vec: Vec < u64 > = Vec :: from ( & v[ ..] ) ;
179- vec
180- } ) ;
181- }
223+ fn bench_insert_many ( b : & mut Bencher ) {
224+ #[ inline( never) ]
225+ fn insert_many_noinline < I : IntoIterator < Item = u64 > > (
226+ vec : & mut SmallVec < [ u64 ; VEC_SIZE ] > ,
227+ index : usize ,
228+ iterable : I ,
229+ ) {
230+ vec. insert_many ( index, iterable)
231+ }
182232
183- #[ bench]
184- fn bench_extend_from_slice_vec ( b : & mut Bencher ) {
185- let v: Vec < u64 > = ( 0 ..100 ) . collect ( ) ;
186233 b. iter ( || {
187- let mut vec: Vec < u64 > = Vec :: with_capacity ( 16 ) ;
188- vec. extend_from_slice ( & v) ;
234+ let mut vec = SmallVec :: < [ u64 ; VEC_SIZE ] > :: new ( ) ;
235+ insert_many_noinline ( & mut vec, 0 , 0 ..SPILLED_SIZE as _ ) ;
236+ insert_many_noinline ( & mut vec, 0 , 0 ..SPILLED_SIZE as _ ) ;
189237 vec
190238 } ) ;
191239}
192240
193241#[ bench]
194- fn bench_pushpop_vec ( b : & mut Bencher ) {
195- #[ inline( never) ]
196- fn pushpop_noinline ( vec : & mut Vec < u64 > , x : u64 ) {
197- vec. push ( x) ;
198- vec. pop ( ) ;
199- }
200-
242+ fn bench_insert_from_slice ( b : & mut Bencher ) {
243+ let v: Vec < u64 > = ( 0 ..SPILLED_SIZE as _ ) . collect ( ) ;
201244 b. iter ( || {
202- let mut vec: Vec < u64 > = Vec :: with_capacity ( 16 ) ;
203- for x in 0 ..100 {
204- pushpop_noinline ( & mut vec, x) ;
205- }
245+ let mut vec = SmallVec :: < [ u64 ; VEC_SIZE ] > :: new ( ) ;
246+ vec. insert_from_slice ( 0 , & v) ;
247+ vec. insert_from_slice ( 0 , & v) ;
206248 vec
207249 } ) ;
208250}
209251
210252#[ bench]
211- fn bench_macro_from_elem_vec ( b : & mut Bencher ) {
253+ fn bench_macro_from_list ( b : & mut Bencher ) {
212254 b. iter ( || {
213- let vec: Vec < u64 > = vec ! [ 42 ; 100 ] ;
255+ let vec: SmallVec < [ u64 ; 16 ] > = smallvec ! [
256+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 20 , 24 , 32 , 36 , 0x40 , 0x80 ,
257+ 0x100 , 0x200 , 0x400 , 0x800 , 0x1000 , 0x2000 , 0x4000 , 0x8000 , 0x10000 , 0x20000 , 0x40000 ,
258+ 0x80000 , 0x100000 ,
259+ ] ;
214260 vec
215261 } ) ;
216262}
@@ -221,7 +267,7 @@ fn bench_macro_from_list_vec(b: &mut Bencher) {
221267 let vec: Vec < u64 > = vec ! [
222268 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 20 , 24 , 32 , 36 , 0x40 , 0x80 ,
223269 0x100 , 0x200 , 0x400 , 0x800 , 0x1000 , 0x2000 , 0x4000 , 0x8000 , 0x10000 , 0x20000 , 0x40000 ,
224- 0x80000 , 0x100000
270+ 0x80000 , 0x100000 ,
225271 ] ;
226272 vec
227273 } ) ;
0 commit comments