4
4
extern crate smallvec;
5
5
extern crate test;
6
6
7
- use smallvec:: SmallVec ;
8
7
use self :: test:: Bencher ;
8
+ use smallvec:: { ExtendFromSlice , SmallVec } ;
9
9
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 ;
16
12
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 ;
24
20
}
25
21
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 )
31
25
}
32
26
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
+ }
40
46
}
41
47
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 ( )
48
51
}
49
52
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
+ }
56
72
}
57
73
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
+ }
65
83
}
66
84
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
+ }
74
103
}
75
104
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
+
79
131
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
+ }
82
136
vec
83
137
} ) ;
84
138
}
85
139
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
+
89
146
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
+ }
93
155
vec
94
156
} ) ;
95
157
}
96
158
97
- #[ bench]
98
- fn bench_pushpop ( b : & mut Bencher ) {
159
+ fn gen_remove < V : Vector < u64 > > ( n : usize , b : & mut Bencher ) {
99
160
#[ 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) ;
103
163
}
104
164
105
165
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)
109
170
}
110
- vec
111
171
} ) ;
112
172
}
113
173
114
- #[ bench]
115
- fn bench_macro_from_elem ( b : & mut Bencher ) {
174
+ fn gen_extend < V : Vector < u64 > > ( n : u64 , b : & mut Bencher ) {
116
175
b. iter ( || {
117
- let vec: SmallVec < [ u64 ; 16 ] > = smallvec ! [ 42 ; 100 ] ;
176
+ let mut vec = V :: new ( ) ;
177
+ vec. extend ( 0 ..n) ;
118
178
vec
119
179
} ) ;
120
180
}
121
181
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 ( ) ;
124
184
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) ;
130
186
vec
131
187
} ) ;
132
188
}
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
- }
139
189
190
+ fn gen_extend_from_slice < V : Vector < u64 > > ( n : u64 , b : & mut Bencher ) {
191
+ let v: Vec < u64 > = ( 0 ..n) . collect ( ) ;
140
192
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) ;
145
195
vec
146
196
} ) ;
147
197
}
148
198
149
- #[ bench]
150
- fn bench_insert_vec ( b : & mut Bencher ) {
199
+ fn gen_pushpop < V : Vector < u64 > > ( b : & mut Bencher ) {
151
200
#[ 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 ( )
154
204
}
155
205
156
206
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) ;
160
210
}
161
211
vec
162
212
} ) ;
163
213
}
164
214
165
- #[ bench]
166
- fn bench_extend_vec ( b : & mut Bencher ) {
215
+ fn gen_from_elem < V : Vector < u64 > > ( n : usize , b : & mut Bencher ) {
167
216
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) ;
170
218
vec
171
219
} ) ;
172
220
}
173
221
174
222
#[ 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
+ }
182
232
183
- #[ bench]
184
- fn bench_extend_from_slice_vec ( b : & mut Bencher ) {
185
- let v: Vec < u64 > = ( 0 ..100 ) . collect ( ) ;
186
233
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 _ ) ;
189
237
vec
190
238
} ) ;
191
239
}
192
240
193
241
#[ 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 ( ) ;
201
244
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) ;
206
248
vec
207
249
} ) ;
208
250
}
209
251
210
252
#[ bench]
211
- fn bench_macro_from_elem_vec ( b : & mut Bencher ) {
253
+ fn bench_macro_from_list ( b : & mut Bencher ) {
212
254
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
+ ] ;
214
260
vec
215
261
} ) ;
216
262
}
@@ -221,7 +267,7 @@ fn bench_macro_from_list_vec(b: &mut Bencher) {
221
267
let vec: Vec < u64 > = vec ! [
222
268
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 20 , 24 , 32 , 36 , 0x40 , 0x80 ,
223
269
0x100 , 0x200 , 0x400 , 0x800 , 0x1000 , 0x2000 , 0x4000 , 0x8000 , 0x10000 , 0x20000 , 0x40000 ,
224
- 0x80000 , 0x100000
270
+ 0x80000 , 0x100000 ,
225
271
] ;
226
272
vec
227
273
} ) ;
0 commit comments