1 #![feature(test)]
2 
3 extern crate test;
4 #[macro_use]
5 extern crate lazy_static;
6 
7 use fnv::FnvHasher;
8 use std::hash::BuildHasherDefault;
9 use std::hash::Hash;
10 type FnvBuilder = BuildHasherDefault<FnvHasher>;
11 
12 use test::black_box;
13 use test::Bencher;
14 
15 use indexmap::IndexMap;
16 
17 use std::collections::HashMap;
18 use std::iter::FromIterator;
19 
20 use rand::rngs::SmallRng;
21 use rand::seq::SliceRandom;
22 use rand::SeedableRng;
23 
24 /// Use a consistently seeded Rng for benchmark stability
small_rng() -> SmallRng25 fn small_rng() -> SmallRng {
26     let seed = u64::from_le_bytes(*b"indexmap");
27     SmallRng::seed_from_u64(seed)
28 }
29 
30 #[bench]
new_hashmap(b: &mut Bencher)31 fn new_hashmap(b: &mut Bencher) {
32     b.iter(|| HashMap::<String, String>::new());
33 }
34 
35 #[bench]
new_indexmap(b: &mut Bencher)36 fn new_indexmap(b: &mut Bencher) {
37     b.iter(|| IndexMap::<String, String>::new());
38 }
39 
40 #[bench]
with_capacity_10e5_hashmap(b: &mut Bencher)41 fn with_capacity_10e5_hashmap(b: &mut Bencher) {
42     b.iter(|| HashMap::<String, String>::with_capacity(10_000));
43 }
44 
45 #[bench]
with_capacity_10e5_indexmap(b: &mut Bencher)46 fn with_capacity_10e5_indexmap(b: &mut Bencher) {
47     b.iter(|| IndexMap::<String, String>::with_capacity(10_000));
48 }
49 
50 #[bench]
insert_hashmap_10_000(b: &mut Bencher)51 fn insert_hashmap_10_000(b: &mut Bencher) {
52     let c = 10_000;
53     b.iter(|| {
54         let mut map = HashMap::with_capacity(c);
55         for x in 0..c {
56             map.insert(x, ());
57         }
58         map
59     });
60 }
61 
62 #[bench]
insert_indexmap_10_000(b: &mut Bencher)63 fn insert_indexmap_10_000(b: &mut Bencher) {
64     let c = 10_000;
65     b.iter(|| {
66         let mut map = IndexMap::with_capacity(c);
67         for x in 0..c {
68             map.insert(x, ());
69         }
70         map
71     });
72 }
73 
74 #[bench]
insert_hashmap_string_10_000(b: &mut Bencher)75 fn insert_hashmap_string_10_000(b: &mut Bencher) {
76     let c = 10_000;
77     b.iter(|| {
78         let mut map = HashMap::with_capacity(c);
79         for x in 0..c {
80             map.insert(x.to_string(), ());
81         }
82         map
83     });
84 }
85 
86 #[bench]
insert_indexmap_string_10_000(b: &mut Bencher)87 fn insert_indexmap_string_10_000(b: &mut Bencher) {
88     let c = 10_000;
89     b.iter(|| {
90         let mut map = IndexMap::with_capacity(c);
91         for x in 0..c {
92             map.insert(x.to_string(), ());
93         }
94         map
95     });
96 }
97 
98 #[bench]
insert_hashmap_str_10_000(b: &mut Bencher)99 fn insert_hashmap_str_10_000(b: &mut Bencher) {
100     let c = 10_000;
101     let ss = Vec::from_iter((0..c).map(|x| x.to_string()));
102     b.iter(|| {
103         let mut map = HashMap::with_capacity(c);
104         for key in &ss {
105             map.insert(&key[..], ());
106         }
107         map
108     });
109 }
110 
111 #[bench]
insert_indexmap_str_10_000(b: &mut Bencher)112 fn insert_indexmap_str_10_000(b: &mut Bencher) {
113     let c = 10_000;
114     let ss = Vec::from_iter((0..c).map(|x| x.to_string()));
115     b.iter(|| {
116         let mut map = IndexMap::with_capacity(c);
117         for key in &ss {
118             map.insert(&key[..], ());
119         }
120         map
121     });
122 }
123 
124 #[bench]
insert_hashmap_int_bigvalue_10_000(b: &mut Bencher)125 fn insert_hashmap_int_bigvalue_10_000(b: &mut Bencher) {
126     let c = 10_000;
127     let value = [0u64; 10];
128     b.iter(|| {
129         let mut map = HashMap::with_capacity(c);
130         for i in 0..c {
131             map.insert(i, value);
132         }
133         map
134     });
135 }
136 
137 #[bench]
insert_indexmap_int_bigvalue_10_000(b: &mut Bencher)138 fn insert_indexmap_int_bigvalue_10_000(b: &mut Bencher) {
139     let c = 10_000;
140     let value = [0u64; 10];
141     b.iter(|| {
142         let mut map = IndexMap::with_capacity(c);
143         for i in 0..c {
144             map.insert(i, value);
145         }
146         map
147     });
148 }
149 
150 #[bench]
insert_hashmap_100_000(b: &mut Bencher)151 fn insert_hashmap_100_000(b: &mut Bencher) {
152     let c = 100_000;
153     b.iter(|| {
154         let mut map = HashMap::with_capacity(c);
155         for x in 0..c {
156             map.insert(x, ());
157         }
158         map
159     });
160 }
161 
162 #[bench]
insert_indexmap_100_000(b: &mut Bencher)163 fn insert_indexmap_100_000(b: &mut Bencher) {
164     let c = 100_000;
165     b.iter(|| {
166         let mut map = IndexMap::with_capacity(c);
167         for x in 0..c {
168             map.insert(x, ());
169         }
170         map
171     });
172 }
173 
174 #[bench]
insert_hashmap_150(b: &mut Bencher)175 fn insert_hashmap_150(b: &mut Bencher) {
176     let c = 150;
177     b.iter(|| {
178         let mut map = HashMap::with_capacity(c);
179         for x in 0..c {
180             map.insert(x, ());
181         }
182         map
183     });
184 }
185 
186 #[bench]
insert_indexmap_150(b: &mut Bencher)187 fn insert_indexmap_150(b: &mut Bencher) {
188     let c = 150;
189     b.iter(|| {
190         let mut map = IndexMap::with_capacity(c);
191         for x in 0..c {
192             map.insert(x, ());
193         }
194         map
195     });
196 }
197 
198 #[bench]
entry_hashmap_150(b: &mut Bencher)199 fn entry_hashmap_150(b: &mut Bencher) {
200     let c = 150;
201     b.iter(|| {
202         let mut map = HashMap::with_capacity(c);
203         for x in 0..c {
204             map.entry(x).or_insert(());
205         }
206         map
207     });
208 }
209 
210 #[bench]
entry_indexmap_150(b: &mut Bencher)211 fn entry_indexmap_150(b: &mut Bencher) {
212     let c = 150;
213     b.iter(|| {
214         let mut map = IndexMap::with_capacity(c);
215         for x in 0..c {
216             map.entry(x).or_insert(());
217         }
218         map
219     });
220 }
221 
222 #[bench]
iter_sum_hashmap_10_000(b: &mut Bencher)223 fn iter_sum_hashmap_10_000(b: &mut Bencher) {
224     let c = 10_000;
225     let mut map = HashMap::with_capacity(c);
226     let len = c - c / 10;
227     for x in 0..len {
228         map.insert(x, ());
229     }
230     assert_eq!(map.len(), len);
231     b.iter(|| map.keys().sum::<usize>());
232 }
233 
234 #[bench]
iter_sum_indexmap_10_000(b: &mut Bencher)235 fn iter_sum_indexmap_10_000(b: &mut Bencher) {
236     let c = 10_000;
237     let mut map = IndexMap::with_capacity(c);
238     let len = c - c / 10;
239     for x in 0..len {
240         map.insert(x, ());
241     }
242     assert_eq!(map.len(), len);
243     b.iter(|| map.keys().sum::<usize>());
244 }
245 
246 #[bench]
iter_black_box_hashmap_10_000(b: &mut Bencher)247 fn iter_black_box_hashmap_10_000(b: &mut Bencher) {
248     let c = 10_000;
249     let mut map = HashMap::with_capacity(c);
250     let len = c - c / 10;
251     for x in 0..len {
252         map.insert(x, ());
253     }
254     assert_eq!(map.len(), len);
255     b.iter(|| {
256         for &key in map.keys() {
257             black_box(key);
258         }
259     });
260 }
261 
262 #[bench]
iter_black_box_indexmap_10_000(b: &mut Bencher)263 fn iter_black_box_indexmap_10_000(b: &mut Bencher) {
264     let c = 10_000;
265     let mut map = IndexMap::with_capacity(c);
266     let len = c - c / 10;
267     for x in 0..len {
268         map.insert(x, ());
269     }
270     assert_eq!(map.len(), len);
271     b.iter(|| {
272         for &key in map.keys() {
273             black_box(key);
274         }
275     });
276 }
277 
shuffled_keys<I>(iter: I) -> Vec<I::Item> where I: IntoIterator,278 fn shuffled_keys<I>(iter: I) -> Vec<I::Item>
279 where
280     I: IntoIterator,
281 {
282     let mut v = Vec::from_iter(iter);
283     let mut rng = small_rng();
284     v.shuffle(&mut rng);
285     v
286 }
287 
288 #[bench]
lookup_hashmap_10_000_exist(b: &mut Bencher)289 fn lookup_hashmap_10_000_exist(b: &mut Bencher) {
290     let c = 10_000;
291     let mut map = HashMap::with_capacity(c);
292     let keys = shuffled_keys(0..c);
293     for &key in &keys {
294         map.insert(key, 1);
295     }
296     b.iter(|| {
297         let mut found = 0;
298         for key in 5000..c {
299             found += map.get(&key).is_some() as i32;
300         }
301         found
302     });
303 }
304 
305 #[bench]
lookup_hashmap_10_000_noexist(b: &mut Bencher)306 fn lookup_hashmap_10_000_noexist(b: &mut Bencher) {
307     let c = 10_000;
308     let mut map = HashMap::with_capacity(c);
309     let keys = shuffled_keys(0..c);
310     for &key in &keys {
311         map.insert(key, 1);
312     }
313     b.iter(|| {
314         let mut found = 0;
315         for key in c..15000 {
316             found += map.get(&key).is_some() as i32;
317         }
318         found
319     });
320 }
321 
322 #[bench]
lookup_indexmap_10_000_exist(b: &mut Bencher)323 fn lookup_indexmap_10_000_exist(b: &mut Bencher) {
324     let c = 10_000;
325     let mut map = IndexMap::with_capacity(c);
326     let keys = shuffled_keys(0..c);
327     for &key in &keys {
328         map.insert(key, 1);
329     }
330     b.iter(|| {
331         let mut found = 0;
332         for key in 5000..c {
333             found += map.get(&key).is_some() as i32;
334         }
335         found
336     });
337 }
338 
339 #[bench]
lookup_indexmap_10_000_noexist(b: &mut Bencher)340 fn lookup_indexmap_10_000_noexist(b: &mut Bencher) {
341     let c = 10_000;
342     let mut map = IndexMap::with_capacity(c);
343     let keys = shuffled_keys(0..c);
344     for &key in &keys {
345         map.insert(key, 1);
346     }
347     b.iter(|| {
348         let mut found = 0;
349         for key in c..15000 {
350             found += map.get(&key).is_some() as i32;
351         }
352         found
353     });
354 }
355 
356 // number of items to look up
357 const LOOKUP_MAP_SIZE: u32 = 100_000_u32;
358 const LOOKUP_SAMPLE_SIZE: u32 = 5000;
359 const SORT_MAP_SIZE: usize = 10_000;
360 
361 // use lazy_static so that comparison benchmarks use the exact same inputs
362 lazy_static! {
363     static ref KEYS: Vec<u32> = shuffled_keys(0..LOOKUP_MAP_SIZE);
364 }
365 
366 lazy_static! {
367     static ref HMAP_100K: HashMap<u32, u32> = {
368         let c = LOOKUP_MAP_SIZE;
369         let mut map = HashMap::with_capacity(c as usize);
370         let keys = &*KEYS;
371         for &key in keys {
372             map.insert(key, key);
373         }
374         map
375     };
376 }
377 
378 lazy_static! {
379     static ref IMAP_100K: IndexMap<u32, u32> = {
380         let c = LOOKUP_MAP_SIZE;
381         let mut map = IndexMap::with_capacity(c as usize);
382         let keys = &*KEYS;
383         for &key in keys {
384             map.insert(key, key);
385         }
386         map
387     };
388 }
389 
390 lazy_static! {
391     static ref IMAP_SORT_U32: IndexMap<u32, u32> = {
392         let mut map = IndexMap::with_capacity(SORT_MAP_SIZE);
393         for &key in &KEYS[..SORT_MAP_SIZE] {
394             map.insert(key, key);
395         }
396         map
397     };
398 }
399 lazy_static! {
400     static ref IMAP_SORT_S: IndexMap<String, String> = {
401         let mut map = IndexMap::with_capacity(SORT_MAP_SIZE);
402         for &key in &KEYS[..SORT_MAP_SIZE] {
403             map.insert(format!("{:^16x}", &key), String::new());
404         }
405         map
406     };
407 }
408 
409 #[bench]
lookup_hashmap_100_000_multi(b: &mut Bencher)410 fn lookup_hashmap_100_000_multi(b: &mut Bencher) {
411     let map = &*HMAP_100K;
412     b.iter(|| {
413         let mut found = 0;
414         for key in 0..LOOKUP_SAMPLE_SIZE {
415             found += map.get(&key).is_some() as u32;
416         }
417         found
418     });
419 }
420 
421 #[bench]
lookup_indexmap_100_000_multi(b: &mut Bencher)422 fn lookup_indexmap_100_000_multi(b: &mut Bencher) {
423     let map = &*IMAP_100K;
424     b.iter(|| {
425         let mut found = 0;
426         for key in 0..LOOKUP_SAMPLE_SIZE {
427             found += map.get(&key).is_some() as u32;
428         }
429         found
430     });
431 }
432 
433 // inorder: Test looking up keys in the same order as they were inserted
434 #[bench]
lookup_hashmap_100_000_inorder_multi(b: &mut Bencher)435 fn lookup_hashmap_100_000_inorder_multi(b: &mut Bencher) {
436     let map = &*HMAP_100K;
437     let keys = &*KEYS;
438     b.iter(|| {
439         let mut found = 0;
440         for key in &keys[0..LOOKUP_SAMPLE_SIZE as usize] {
441             found += map.get(key).is_some() as u32;
442         }
443         found
444     });
445 }
446 
447 #[bench]
lookup_indexmap_100_000_inorder_multi(b: &mut Bencher)448 fn lookup_indexmap_100_000_inorder_multi(b: &mut Bencher) {
449     let map = &*IMAP_100K;
450     let keys = &*KEYS;
451     b.iter(|| {
452         let mut found = 0;
453         for key in &keys[0..LOOKUP_SAMPLE_SIZE as usize] {
454             found += map.get(key).is_some() as u32;
455         }
456         found
457     });
458 }
459 
460 #[bench]
lookup_hashmap_100_000_single(b: &mut Bencher)461 fn lookup_hashmap_100_000_single(b: &mut Bencher) {
462     let map = &*HMAP_100K;
463     let mut iter = (0..LOOKUP_MAP_SIZE + LOOKUP_SAMPLE_SIZE).cycle();
464     b.iter(|| {
465         let key = iter.next().unwrap();
466         map.get(&key).is_some()
467     });
468 }
469 
470 #[bench]
lookup_indexmap_100_000_single(b: &mut Bencher)471 fn lookup_indexmap_100_000_single(b: &mut Bencher) {
472     let map = &*IMAP_100K;
473     let mut iter = (0..LOOKUP_MAP_SIZE + LOOKUP_SAMPLE_SIZE).cycle();
474     b.iter(|| {
475         let key = iter.next().unwrap();
476         map.get(&key).is_some()
477     });
478 }
479 
480 const GROW_SIZE: usize = 100_000;
481 type GrowKey = u32;
482 
483 // Test grow/resize without preallocation
484 #[bench]
grow_fnv_hashmap_100_000(b: &mut Bencher)485 fn grow_fnv_hashmap_100_000(b: &mut Bencher) {
486     b.iter(|| {
487         let mut map: HashMap<_, _, FnvBuilder> = HashMap::default();
488         for x in 0..GROW_SIZE {
489             map.insert(x as GrowKey, x as GrowKey);
490         }
491         map
492     });
493 }
494 
495 #[bench]
grow_fnv_indexmap_100_000(b: &mut Bencher)496 fn grow_fnv_indexmap_100_000(b: &mut Bencher) {
497     b.iter(|| {
498         let mut map: IndexMap<_, _, FnvBuilder> = IndexMap::default();
499         for x in 0..GROW_SIZE {
500             map.insert(x as GrowKey, x as GrowKey);
501         }
502         map
503     });
504 }
505 
506 const MERGE: u64 = 10_000;
507 #[bench]
hashmap_merge_simple(b: &mut Bencher)508 fn hashmap_merge_simple(b: &mut Bencher) {
509     let first_map: HashMap<u64, _> = (0..MERGE).map(|i| (i, ())).collect();
510     let second_map: HashMap<u64, _> = (MERGE..MERGE * 2).map(|i| (i, ())).collect();
511     b.iter(|| {
512         let mut merged = first_map.clone();
513         merged.extend(second_map.iter().map(|(&k, &v)| (k, v)));
514         merged
515     });
516 }
517 
518 #[bench]
hashmap_merge_shuffle(b: &mut Bencher)519 fn hashmap_merge_shuffle(b: &mut Bencher) {
520     let first_map: HashMap<u64, _> = (0..MERGE).map(|i| (i, ())).collect();
521     let second_map: HashMap<u64, _> = (MERGE..MERGE * 2).map(|i| (i, ())).collect();
522     let mut v = Vec::new();
523     let mut rng = small_rng();
524     b.iter(|| {
525         let mut merged = first_map.clone();
526         v.extend(second_map.iter().map(|(&k, &v)| (k, v)));
527         v.shuffle(&mut rng);
528         merged.extend(v.drain(..));
529 
530         merged
531     });
532 }
533 
534 #[bench]
indexmap_merge_simple(b: &mut Bencher)535 fn indexmap_merge_simple(b: &mut Bencher) {
536     let first_map: IndexMap<u64, _> = (0..MERGE).map(|i| (i, ())).collect();
537     let second_map: IndexMap<u64, _> = (MERGE..MERGE * 2).map(|i| (i, ())).collect();
538     b.iter(|| {
539         let mut merged = first_map.clone();
540         merged.extend(second_map.iter().map(|(&k, &v)| (k, v)));
541         merged
542     });
543 }
544 
545 #[bench]
indexmap_merge_shuffle(b: &mut Bencher)546 fn indexmap_merge_shuffle(b: &mut Bencher) {
547     let first_map: IndexMap<u64, _> = (0..MERGE).map(|i| (i, ())).collect();
548     let second_map: IndexMap<u64, _> = (MERGE..MERGE * 2).map(|i| (i, ())).collect();
549     let mut v = Vec::new();
550     let mut rng = small_rng();
551     b.iter(|| {
552         let mut merged = first_map.clone();
553         v.extend(second_map.iter().map(|(&k, &v)| (k, v)));
554         v.shuffle(&mut rng);
555         merged.extend(v.drain(..));
556 
557         merged
558     });
559 }
560 
561 #[bench]
swap_remove_indexmap_100_000(b: &mut Bencher)562 fn swap_remove_indexmap_100_000(b: &mut Bencher) {
563     let map = IMAP_100K.clone();
564     let mut keys = Vec::from_iter(map.keys().copied());
565     let mut rng = small_rng();
566     keys.shuffle(&mut rng);
567 
568     b.iter(|| {
569         let mut map = map.clone();
570         for key in &keys {
571             map.swap_remove(key);
572         }
573         assert_eq!(map.len(), 0);
574         map
575     });
576 }
577 
578 #[bench]
shift_remove_indexmap_100_000_few(b: &mut Bencher)579 fn shift_remove_indexmap_100_000_few(b: &mut Bencher) {
580     let map = IMAP_100K.clone();
581     let mut keys = Vec::from_iter(map.keys().copied());
582     let mut rng = small_rng();
583     keys.shuffle(&mut rng);
584     keys.truncate(50);
585 
586     b.iter(|| {
587         let mut map = map.clone();
588         for key in &keys {
589             map.shift_remove(key);
590         }
591         assert_eq!(map.len(), IMAP_100K.len() - keys.len());
592         map
593     });
594 }
595 
596 #[bench]
shift_remove_indexmap_2_000_full(b: &mut Bencher)597 fn shift_remove_indexmap_2_000_full(b: &mut Bencher) {
598     let mut keys = KEYS[..2_000].to_vec();
599     let mut map = IndexMap::with_capacity(keys.len());
600     for &key in &keys {
601         map.insert(key, key);
602     }
603     let mut rng = small_rng();
604     keys.shuffle(&mut rng);
605 
606     b.iter(|| {
607         let mut map = map.clone();
608         for key in &keys {
609             map.shift_remove(key);
610         }
611         assert_eq!(map.len(), 0);
612         map
613     });
614 }
615 
616 #[bench]
pop_indexmap_100_000(b: &mut Bencher)617 fn pop_indexmap_100_000(b: &mut Bencher) {
618     let map = IMAP_100K.clone();
619 
620     b.iter(|| {
621         let mut map = map.clone();
622         while !map.is_empty() {
623             map.pop();
624         }
625         assert_eq!(map.len(), 0);
626         map
627     });
628 }
629 
630 #[bench]
few_retain_indexmap_100_000(b: &mut Bencher)631 fn few_retain_indexmap_100_000(b: &mut Bencher) {
632     let map = IMAP_100K.clone();
633 
634     b.iter(|| {
635         let mut map = map.clone();
636         map.retain(|k, _| *k % 7 == 0);
637         map
638     });
639 }
640 
641 #[bench]
few_retain_hashmap_100_000(b: &mut Bencher)642 fn few_retain_hashmap_100_000(b: &mut Bencher) {
643     let map = HMAP_100K.clone();
644 
645     b.iter(|| {
646         let mut map = map.clone();
647         map.retain(|k, _| *k % 7 == 0);
648         map
649     });
650 }
651 
652 #[bench]
half_retain_indexmap_100_000(b: &mut Bencher)653 fn half_retain_indexmap_100_000(b: &mut Bencher) {
654     let map = IMAP_100K.clone();
655 
656     b.iter(|| {
657         let mut map = map.clone();
658         map.retain(|k, _| *k % 2 == 0);
659         map
660     });
661 }
662 
663 #[bench]
half_retain_hashmap_100_000(b: &mut Bencher)664 fn half_retain_hashmap_100_000(b: &mut Bencher) {
665     let map = HMAP_100K.clone();
666 
667     b.iter(|| {
668         let mut map = map.clone();
669         map.retain(|k, _| *k % 2 == 0);
670         map
671     });
672 }
673 
674 #[bench]
many_retain_indexmap_100_000(b: &mut Bencher)675 fn many_retain_indexmap_100_000(b: &mut Bencher) {
676     let map = IMAP_100K.clone();
677 
678     b.iter(|| {
679         let mut map = map.clone();
680         map.retain(|k, _| *k % 100 != 0);
681         map
682     });
683 }
684 
685 #[bench]
many_retain_hashmap_100_000(b: &mut Bencher)686 fn many_retain_hashmap_100_000(b: &mut Bencher) {
687     let map = HMAP_100K.clone();
688 
689     b.iter(|| {
690         let mut map = map.clone();
691         map.retain(|k, _| *k % 100 != 0);
692         map
693     });
694 }
695 
696 // simple sort impl for comparison
simple_sort<K: Ord + Hash, V>(m: &mut IndexMap<K, V>)697 pub fn simple_sort<K: Ord + Hash, V>(m: &mut IndexMap<K, V>) {
698     let mut ordered: Vec<_> = m.drain(..).collect();
699     ordered.sort_by(|left, right| left.0.cmp(&right.0));
700     m.extend(ordered);
701 }
702 
703 #[bench]
indexmap_sort_s(b: &mut Bencher)704 fn indexmap_sort_s(b: &mut Bencher) {
705     let map = IMAP_SORT_S.clone();
706 
707     // there's a map clone there, but it's still useful to profile this
708     b.iter(|| {
709         let mut map = map.clone();
710         map.sort_keys();
711         map
712     });
713 }
714 
715 #[bench]
indexmap_simple_sort_s(b: &mut Bencher)716 fn indexmap_simple_sort_s(b: &mut Bencher) {
717     let map = IMAP_SORT_S.clone();
718 
719     // there's a map clone there, but it's still useful to profile this
720     b.iter(|| {
721         let mut map = map.clone();
722         simple_sort(&mut map);
723         map
724     });
725 }
726 
727 #[bench]
indexmap_sort_u32(b: &mut Bencher)728 fn indexmap_sort_u32(b: &mut Bencher) {
729     let map = IMAP_SORT_U32.clone();
730 
731     // there's a map clone there, but it's still useful to profile this
732     b.iter(|| {
733         let mut map = map.clone();
734         map.sort_keys();
735         map
736     });
737 }
738 
739 #[bench]
indexmap_simple_sort_u32(b: &mut Bencher)740 fn indexmap_simple_sort_u32(b: &mut Bencher) {
741     let map = IMAP_SORT_U32.clone();
742 
743     // there's a map clone there, but it's still useful to profile this
744     b.iter(|| {
745         let mut map = map.clone();
746         simple_sort(&mut map);
747         map
748     });
749 }
750 
751 // measure the fixed overhead of cloning in sort benchmarks
752 #[bench]
indexmap_clone_for_sort_s(b: &mut Bencher)753 fn indexmap_clone_for_sort_s(b: &mut Bencher) {
754     let map = IMAP_SORT_S.clone();
755 
756     b.iter(|| map.clone());
757 }
758 
759 #[bench]
indexmap_clone_for_sort_u32(b: &mut Bencher)760 fn indexmap_clone_for_sort_u32(b: &mut Bencher) {
761     let map = IMAP_SORT_U32.clone();
762 
763     b.iter(|| map.clone());
764 }
765