2
2
// Hasher: std default (SipHash) and crate default (foldhash).
3
3
// Int key distribution: low bit heavy, top bit heavy, and random.
4
4
// Task: basic functionality: insert, insert_erase, lookup, lookup_fail, iter
5
- #![ feature( test) ]
6
-
7
- extern crate test;
8
-
9
- use test:: { black_box, Bencher } ;
10
5
6
+ use criterion:: { black_box, criterion_group, criterion_main, Criterion } ;
11
7
use hashbrown:: DefaultHashBuilder ;
12
8
use hashbrown:: { HashMap , HashSet } ;
13
9
use std:: {
@@ -78,15 +74,16 @@ macro_rules! bench_suite {
78
74
79
75
macro_rules! bench_insert {
80
76
( $name: ident, $maptype: ident, $keydist: expr) => {
81
- #[ bench]
82
- fn $name( b: & mut Bencher ) {
77
+ fn $name( c: & mut Criterion ) {
83
78
let mut m = $maptype:: with_capacity_and_hasher( SIZE , Default :: default ( ) ) ;
84
- b. iter( || {
85
- m. clear( ) ;
86
- for i in ( $keydist) . take( SIZE ) {
87
- m. insert( i, ( DropType ( i) , [ i; 20 ] ) ) ;
88
- }
89
- black_box( & mut m) ;
79
+ c. bench_function( stringify!( $name) , |b| {
80
+ b. iter( || {
81
+ m. clear( ) ;
82
+ for i in ( $keydist) . take( SIZE ) {
83
+ m. insert( i, ( DropType ( i) , [ i; 20 ] ) ) ;
84
+ }
85
+ black_box( & mut m) ;
86
+ } ) ;
90
87
} ) ;
91
88
eprintln!( "{}" , SIDE_EFFECT . load( atomic:: Ordering :: SeqCst ) ) ;
92
89
}
@@ -105,15 +102,16 @@ bench_suite!(
105
102
106
103
macro_rules! bench_grow_insert {
107
104
( $name: ident, $maptype: ident, $keydist: expr) => {
108
- #[ bench]
109
- fn $name( b: & mut Bencher ) {
110
- b. iter( || {
111
- let mut m = $maptype:: default ( ) ;
112
- for i in ( $keydist) . take( SIZE ) {
113
- m. insert( i, DropType ( i) ) ;
114
- }
115
- black_box( & mut m) ;
116
- } )
105
+ fn $name( c: & mut Criterion ) {
106
+ c. bench_function( stringify!( $name) , |b| {
107
+ b. iter( || {
108
+ let mut m = $maptype:: default ( ) ;
109
+ for i in ( $keydist) . take( SIZE ) {
110
+ m. insert( i, DropType ( i) ) ;
111
+ }
112
+ black_box( & mut m) ;
113
+ } ) ;
114
+ } ) ;
117
115
}
118
116
} ;
119
117
}
@@ -130,24 +128,25 @@ bench_suite!(
130
128
131
129
macro_rules! bench_insert_erase {
132
130
( $name: ident, $maptype: ident, $keydist: expr) => {
133
- #[ bench]
134
- fn $name( b: & mut Bencher ) {
131
+ fn $name( c: & mut Criterion ) {
135
132
let mut base = $maptype:: default ( ) ;
136
133
for i in ( $keydist) . take( SIZE ) {
137
134
base. insert( i, DropType ( i) ) ;
138
135
}
139
136
let skip = $keydist. skip( SIZE ) ;
140
- b. iter( || {
141
- let mut m = base. clone( ) ;
142
- let mut add_iter = skip. clone( ) ;
143
- let mut remove_iter = $keydist;
144
- // While keeping the size constant,
145
- // replace the first keydist with the second.
146
- for ( add, remove) in ( & mut add_iter) . zip( & mut remove_iter) . take( SIZE ) {
147
- m. insert( add, DropType ( add) ) ;
148
- black_box( m. remove( & remove) ) ;
149
- }
150
- black_box( m) ;
137
+ c. bench_function( stringify!( $name) , |b| {
138
+ b. iter( || {
139
+ let mut m = base. clone( ) ;
140
+ let mut add_iter = skip. clone( ) ;
141
+ let mut remove_iter = $keydist;
142
+ // While keeping the size constant,
143
+ // replace the first keydist with the second.
144
+ for ( add, remove) in ( & mut add_iter) . zip( & mut remove_iter) . take( SIZE ) {
145
+ m. insert( add, DropType ( add) ) ;
146
+ black_box( m. remove( & remove) ) ;
147
+ }
148
+ black_box( m) ;
149
+ } ) ;
151
150
} ) ;
152
151
eprintln!( "{}" , SIDE_EFFECT . load( atomic:: Ordering :: SeqCst ) ) ;
153
152
}
@@ -166,17 +165,18 @@ bench_suite!(
166
165
167
166
macro_rules! bench_lookup {
168
167
( $name: ident, $maptype: ident, $keydist: expr) => {
169
- #[ bench]
170
- fn $name( b: & mut Bencher ) {
168
+ fn $name( c: & mut Criterion ) {
171
169
let mut m = $maptype:: default ( ) ;
172
170
for i in $keydist. take( SIZE ) {
173
171
m. insert( i, DropType ( i) ) ;
174
172
}
175
173
176
- b. iter( || {
177
- for i in $keydist. take( SIZE ) {
178
- black_box( m. get( & i) ) ;
179
- }
174
+ c. bench_function( stringify!( $name) , |b| {
175
+ b. iter( || {
176
+ for i in $keydist. take( SIZE ) {
177
+ black_box( m. get( & i) ) ;
178
+ }
179
+ } ) ;
180
180
} ) ;
181
181
eprintln!( "{}" , SIDE_EFFECT . load( atomic:: Ordering :: SeqCst ) ) ;
182
182
}
@@ -195,19 +195,20 @@ bench_suite!(
195
195
196
196
macro_rules! bench_lookup_fail {
197
197
( $name: ident, $maptype: ident, $keydist: expr) => {
198
- #[ bench]
199
- fn $name( b: & mut Bencher ) {
198
+ fn $name( c: & mut Criterion ) {
200
199
let mut m = $maptype:: default ( ) ;
201
200
let mut iter = $keydist;
202
201
for i in ( & mut iter) . take( SIZE ) {
203
202
m. insert( i, DropType ( i) ) ;
204
203
}
205
204
206
- b. iter( || {
207
- for i in ( & mut iter) . take( SIZE ) {
208
- black_box( m. get( & i) ) ;
209
- }
210
- } )
205
+ c. bench_function( stringify!( $name) , |b| {
206
+ b. iter( || {
207
+ for i in ( & mut iter) . take( SIZE ) {
208
+ black_box( m. get( & i) ) ;
209
+ }
210
+ } ) ;
211
+ } ) ;
211
212
}
212
213
} ;
213
214
}
@@ -224,18 +225,19 @@ bench_suite!(
224
225
225
226
macro_rules! bench_iter {
226
227
( $name: ident, $maptype: ident, $keydist: expr) => {
227
- #[ bench]
228
- fn $name( b: & mut Bencher ) {
228
+ fn $name( c: & mut Criterion ) {
229
229
let mut m = $maptype:: default ( ) ;
230
230
for i in ( $keydist) . take( SIZE ) {
231
231
m. insert( i, DropType ( i) ) ;
232
232
}
233
233
234
- b. iter( || {
235
- for i in & m {
236
- black_box( i) ;
237
- }
238
- } )
234
+ c. bench_function( stringify!( $name) , |b| {
235
+ b. iter( || {
236
+ for i in & m {
237
+ black_box( i) ;
238
+ }
239
+ } ) ;
240
+ } ) ;
239
241
}
240
242
} ;
241
243
}
@@ -250,80 +252,132 @@ bench_suite!(
250
252
iter_std_random
251
253
) ;
252
254
253
- #[ bench]
254
- fn clone_small ( b : & mut Bencher ) {
255
+ fn clone_small ( c : & mut Criterion ) {
255
256
let mut m = HashMap :: new ( ) ;
256
257
for i in 0 ..10 {
257
258
m. insert ( i, DropType ( i) ) ;
258
259
}
259
260
260
- b. iter ( || {
261
- black_box ( m. clone ( ) ) ;
262
- } )
261
+ c. bench_function ( "clone_small" , |b| {
262
+ b. iter ( || {
263
+ black_box ( m. clone ( ) ) ;
264
+ } ) ;
265
+ } ) ;
263
266
}
264
267
265
- #[ bench]
266
- fn clone_from_small ( b : & mut Bencher ) {
268
+ fn clone_from_small ( c : & mut Criterion ) {
267
269
let mut m = HashMap :: new ( ) ;
268
270
let mut m2 = HashMap :: new ( ) ;
269
271
for i in 0 ..10 {
270
272
m. insert ( i, DropType ( i) ) ;
271
273
}
272
274
273
- b. iter ( || {
274
- m2. clone_from ( & m) ;
275
- black_box ( & mut m2) ;
276
- } )
275
+ c. bench_function ( "clone_from_small" , |b| {
276
+ b. iter ( || {
277
+ m2. clone_from ( & m) ;
278
+ black_box ( & mut m2) ;
279
+ } ) ;
280
+ } ) ;
277
281
}
278
282
279
- #[ bench]
280
- fn clone_large ( b : & mut Bencher ) {
283
+ fn clone_large ( c : & mut Criterion ) {
281
284
let mut m = HashMap :: new ( ) ;
282
285
for i in 0 ..1000 {
283
286
m. insert ( i, DropType ( i) ) ;
284
287
}
285
288
286
- b. iter ( || {
287
- black_box ( m. clone ( ) ) ;
288
- } )
289
+ c. bench_function ( "clone_large" , |b| {
290
+ b. iter ( || {
291
+ black_box ( m. clone ( ) ) ;
292
+ } ) ;
293
+ } ) ;
289
294
}
290
295
291
- #[ bench]
292
- fn clone_from_large ( b : & mut Bencher ) {
296
+ fn clone_from_large ( c : & mut Criterion ) {
293
297
let mut m = HashMap :: new ( ) ;
294
298
let mut m2 = HashMap :: new ( ) ;
295
299
for i in 0 ..1000 {
296
300
m. insert ( i, DropType ( i) ) ;
297
301
}
298
302
299
- b. iter ( || {
300
- m2. clone_from ( & m) ;
301
- black_box ( & mut m2) ;
302
- } )
303
+ c. bench_function ( "clone_from_large" , |b| {
304
+ b. iter ( || {
305
+ m2. clone_from ( & m) ;
306
+ black_box ( & mut m2) ;
307
+ } ) ;
308
+ } ) ;
303
309
}
304
310
305
- # [ bench ]
306
- fn rehash_in_place ( b : & mut Bencher ) {
307
- b. iter ( || {
308
- let mut set = HashSet :: new ( ) ;
311
+ fn rehash_in_place ( c : & mut Criterion ) {
312
+ c . bench_function ( "rehash_in_place" , |b| {
313
+ b. iter ( || {
314
+ let mut set = HashSet :: new ( ) ;
309
315
310
- // Each loop triggers one rehash
311
- for _ in 0 ..10 {
312
- for i in 0 ..223 {
313
- set. insert ( i) ;
314
- }
316
+ // Each loop triggers one rehash
317
+ for _ in 0 ..10 {
318
+ for i in 0 ..223 {
319
+ set. insert ( i) ;
320
+ }
315
321
316
- assert_eq ! (
317
- set. capacity( ) ,
318
- 224 ,
319
- "The set must be at or close to capacity to trigger a re hashing "
320
- ) ;
322
+ assert_eq ! (
323
+ set. capacity( ) ,
324
+ 224 ,
325
+ "The set must be at or close to capacity to trigger a rehashing "
326
+ ) ;
321
327
322
- for i in 100 ..1400 {
323
- set. remove ( & ( i - 100 ) ) ;
324
- set. insert ( i) ;
328
+ for i in 100 ..1400 {
329
+ set. remove ( & ( i - 100 ) ) ;
330
+ set. insert ( i) ;
331
+ }
332
+ set. clear ( ) ;
325
333
}
326
- set. clear ( ) ;
327
- }
334
+ } ) ;
328
335
} ) ;
329
336
}
337
+
338
+ criterion_group ! (
339
+ benches,
340
+ insert_foldhash_serial,
341
+ insert_std_serial,
342
+ insert_foldhash_highbits,
343
+ insert_std_highbits,
344
+ insert_foldhash_random,
345
+ insert_std_random,
346
+ grow_insert_foldhash_serial,
347
+ grow_insert_std_serial,
348
+ grow_insert_foldhash_highbits,
349
+ grow_insert_std_highbits,
350
+ grow_insert_foldhash_random,
351
+ grow_insert_std_random,
352
+ insert_erase_foldhash_serial,
353
+ insert_erase_std_serial,
354
+ insert_erase_foldhash_highbits,
355
+ insert_erase_std_highbits,
356
+ insert_erase_foldhash_random,
357
+ insert_erase_std_random,
358
+ lookup_foldhash_serial,
359
+ lookup_std_serial,
360
+ lookup_foldhash_highbits,
361
+ lookup_std_highbits,
362
+ lookup_foldhash_random,
363
+ lookup_std_random,
364
+ lookup_fail_foldhash_serial,
365
+ lookup_fail_std_serial,
366
+ lookup_fail_foldhash_highbits,
367
+ lookup_fail_std_highbits,
368
+ lookup_fail_foldhash_random,
369
+ lookup_fail_std_random,
370
+ iter_foldhash_serial,
371
+ iter_std_serial,
372
+ iter_foldhash_highbits,
373
+ iter_std_highbits,
374
+ iter_foldhash_random,
375
+ iter_std_random,
376
+ clone_small,
377
+ clone_from_small,
378
+ clone_large,
379
+ clone_from_large,
380
+ rehash_in_place
381
+ ) ;
382
+
383
+ criterion_main ! ( benches) ;
0 commit comments