~ntietz/rust-hashmap-overhead

rust-hashmap-overhead/src/main.rs -rw-r--r-- 2.1 KiB
456c2b2aNicole Tietz-Sokolskaya Link to blog post 1 year, 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use rand::{thread_rng, Fill, Rng};
use std::collections::{BTreeMap, HashMap};

use blog_alloc::{alloc, Stats, TrackingAllocator};

#[global_allocator]
static ALLOC: TrackingAllocator = TrackingAllocator;

pub fn run_and_track<T>(name: &str, size: usize, f: impl FnOnce() -> T) {
    alloc::reset();

    let t = f();

    let Stats {
        alloc,
        dealloc,
        diff,
    } = alloc::stats();
    println!("{name},{size},{alloc},{dealloc},{diff}");

    drop(t);
}

#[derive(Clone, Copy)]
pub struct DummyData {
    pub data: [u8; 100],
}

/// Generates lists of random elements with the length specified.
pub fn generate_keys_values(len: usize) -> Vec<(u64, DummyData)> {
    let mut rng = thread_rng();

    let mut pairs = Vec::with_capacity(len);

    for _ in 0..len {
        let mut data: [u8; 100] = [0; 100];
        data.try_fill(&mut rng).expect("filling data should work");
        let val = DummyData { data };

        let key = rng.gen();

        pairs.push((key, val));
    }

    pairs
}

fn main() {
    let large_pairs = generate_keys_values(1_000_000);
    println!("generated data");
    println!();

    let mut sizes: Vec<usize> = vec![0, 10, 100, 1_000];
    for size in (10_000..=1_000_000).step_by(10_000) {
        sizes.push(size);
    }

    println!("name,size,alloced,dealloced,diff");
    for size in sizes {
        run_and_track("hashmap", size, || {
            let mut m = HashMap::<u64, DummyData>::new();

            for (key, val) in &large_pairs[..size] {
                m.insert(*key, *val);
            }

            m
        });

        run_and_track("btreemap", size, || {
            let mut m = BTreeMap::<u64, DummyData>::new();

            for (key, val) in &large_pairs[..size] {
                m.insert(*key, *val);
            }

            m
        });

        run_and_track("vec-pair", size, || {
            let mut k: Vec<u64> = Vec::with_capacity(size);
            let mut v: Vec<DummyData> = Vec::with_capacity(size);

            for (key, val) in &large_pairs[..size] {
                k.push(*key);
                v.push(*val);
            }

            (k, v)
        });
    }
}