1
1
#![ feature( test) ]
2
2
3
3
extern crate test;
4
- #[ macro_use]
5
- extern crate lazy_static;
6
4
7
5
use fnv:: FnvHasher ;
8
6
use std:: hash:: BuildHasherDefault ;
9
7
use std:: hash:: Hash ;
8
+ use std:: sync:: LazyLock ;
10
9
type FnvBuilder = BuildHasherDefault < FnvHasher > ;
11
10
12
11
use test:: black_box;
@@ -16,14 +15,10 @@ use indexmap::IndexMap;
16
15
17
16
use std:: collections:: HashMap ;
18
17
19
- use rand:: rngs:: SmallRng ;
20
- use rand:: seq:: SliceRandom ;
21
- use rand:: SeedableRng ;
22
-
23
18
/// Use a consistently seeded Rng for benchmark stability
24
- fn small_rng ( ) -> SmallRng {
19
+ fn small_rng ( ) -> fastrand :: Rng {
25
20
let seed = u64:: from_le_bytes ( * b"indexmap" ) ;
26
- SmallRng :: seed_from_u64 ( seed)
21
+ fastrand :: Rng :: with_seed ( seed)
27
22
}
28
23
29
24
#[ bench]
@@ -280,7 +275,7 @@ where
280
275
{
281
276
let mut v = Vec :: from_iter ( iter) ;
282
277
let mut rng = small_rng ( ) ;
283
- v . shuffle ( & mut rng ) ;
278
+ rng . shuffle ( & mut v ) ;
284
279
v
285
280
}
286
281
@@ -357,53 +352,45 @@ const LOOKUP_MAP_SIZE: u32 = 100_000_u32;
357
352
const LOOKUP_SAMPLE_SIZE : u32 = 5000 ;
358
353
const SORT_MAP_SIZE : usize = 10_000 ;
359
354
360
- // use lazy_static so that comparison benchmarks use the exact same inputs
361
- lazy_static ! {
362
- static ref KEYS : Vec <u32 > = shuffled_keys( 0 ..LOOKUP_MAP_SIZE ) ;
363
- }
355
+ // use (lazy) statics so that comparison benchmarks use the exact same inputs
364
356
365
- lazy_static ! {
366
- static ref HMAP_100K : HashMap <u32 , u32 > = {
367
- let c = LOOKUP_MAP_SIZE ;
368
- let mut map = HashMap :: with_capacity( c as usize ) ;
369
- let keys = & * KEYS ;
370
- for & key in keys {
371
- map. insert( key, key) ;
372
- }
373
- map
374
- } ;
375
- }
357
+ static KEYS : LazyLock < Vec < u32 > > = LazyLock :: new ( || shuffled_keys ( 0 ..LOOKUP_MAP_SIZE ) ) ;
376
358
377
- lazy_static ! {
378
- static ref IMAP_100K : IndexMap <u32 , u32 > = {
379
- let c = LOOKUP_MAP_SIZE ;
380
- let mut map = IndexMap :: with_capacity( c as usize ) ;
381
- let keys = & * KEYS ;
382
- for & key in keys {
383
- map. insert( key, key) ;
384
- }
385
- map
386
- } ;
387
- }
359
+ static HMAP_100K : LazyLock < HashMap < u32 , u32 > > = LazyLock :: new ( || {
360
+ let c = LOOKUP_MAP_SIZE ;
361
+ let mut map = HashMap :: with_capacity ( c as usize ) ;
362
+ let keys = & * KEYS ;
363
+ for & key in keys {
364
+ map. insert ( key, key) ;
365
+ }
366
+ map
367
+ } ) ;
388
368
389
- lazy_static ! {
390
- static ref IMAP_SORT_U32 : IndexMap <u32 , u32 > = {
391
- let mut map = IndexMap :: with_capacity( SORT_MAP_SIZE ) ;
392
- for & key in & KEYS [ ..SORT_MAP_SIZE ] {
393
- map. insert( key, key) ;
394
- }
395
- map
396
- } ;
397
- }
398
- lazy_static ! {
399
- static ref IMAP_SORT_S : IndexMap <String , String > = {
400
- let mut map = IndexMap :: with_capacity( SORT_MAP_SIZE ) ;
401
- for & key in & KEYS [ ..SORT_MAP_SIZE ] {
402
- map. insert( format!( "{:^16x}" , & key) , String :: new( ) ) ;
403
- }
404
- map
405
- } ;
406
- }
369
+ static IMAP_100K : LazyLock < IndexMap < u32 , u32 > > = LazyLock :: new ( || {
370
+ let c = LOOKUP_MAP_SIZE ;
371
+ let mut map = IndexMap :: with_capacity ( c as usize ) ;
372
+ let keys = & * KEYS ;
373
+ for & key in keys {
374
+ map. insert ( key, key) ;
375
+ }
376
+ map
377
+ } ) ;
378
+
379
+ static IMAP_SORT_U32 : LazyLock < IndexMap < u32 , u32 > > = LazyLock :: new ( || {
380
+ let mut map = IndexMap :: with_capacity ( SORT_MAP_SIZE ) ;
381
+ for & key in & KEYS [ ..SORT_MAP_SIZE ] {
382
+ map. insert ( key, key) ;
383
+ }
384
+ map
385
+ } ) ;
386
+
387
+ static IMAP_SORT_S : LazyLock < IndexMap < String , String > > = LazyLock :: new ( || {
388
+ let mut map = IndexMap :: with_capacity ( SORT_MAP_SIZE ) ;
389
+ for & key in & KEYS [ ..SORT_MAP_SIZE ] {
390
+ map. insert ( format ! ( "{:^16x}" , & key) , String :: new ( ) ) ;
391
+ }
392
+ map
393
+ } ) ;
407
394
408
395
#[ bench]
409
396
fn lookup_hashmap_100_000_multi ( b : & mut Bencher ) {
@@ -523,7 +510,7 @@ fn hashmap_merge_shuffle(b: &mut Bencher) {
523
510
b. iter ( || {
524
511
let mut merged = first_map. clone ( ) ;
525
512
v. extend ( second_map. iter ( ) . map ( |( & k, & v) | ( k, v) ) ) ;
526
- v . shuffle ( & mut rng ) ;
513
+ rng . shuffle ( & mut v ) ;
527
514
merged. extend ( v. drain ( ..) ) ;
528
515
529
516
merged
@@ -550,7 +537,7 @@ fn indexmap_merge_shuffle(b: &mut Bencher) {
550
537
b. iter ( || {
551
538
let mut merged = first_map. clone ( ) ;
552
539
v. extend ( second_map. iter ( ) . map ( |( & k, & v) | ( k, v) ) ) ;
553
- v . shuffle ( & mut rng ) ;
540
+ rng . shuffle ( & mut v ) ;
554
541
merged. extend ( v. drain ( ..) ) ;
555
542
556
543
merged
@@ -562,7 +549,7 @@ fn swap_remove_indexmap_100_000(b: &mut Bencher) {
562
549
let map = IMAP_100K . clone ( ) ;
563
550
let mut keys = Vec :: from_iter ( map. keys ( ) . copied ( ) ) ;
564
551
let mut rng = small_rng ( ) ;
565
- keys . shuffle ( & mut rng ) ;
552
+ rng . shuffle ( & mut keys ) ;
566
553
567
554
b. iter ( || {
568
555
let mut map = map. clone ( ) ;
@@ -579,7 +566,7 @@ fn shift_remove_indexmap_100_000_few(b: &mut Bencher) {
579
566
let map = IMAP_100K . clone ( ) ;
580
567
let mut keys = Vec :: from_iter ( map. keys ( ) . copied ( ) ) ;
581
568
let mut rng = small_rng ( ) ;
582
- keys . shuffle ( & mut rng ) ;
569
+ rng . shuffle ( & mut keys ) ;
583
570
keys. truncate ( 50 ) ;
584
571
585
572
b. iter ( || {
@@ -600,7 +587,7 @@ fn shift_remove_indexmap_2_000_full(b: &mut Bencher) {
600
587
map. insert ( key, key) ;
601
588
}
602
589
let mut rng = small_rng ( ) ;
603
- keys . shuffle ( & mut rng ) ;
590
+ rng . shuffle ( & mut keys ) ;
604
591
605
592
b. iter ( || {
606
593
let mut map = map. clone ( ) ;
0 commit comments