Skip to main content

subms_hyperloglog/
recipe.rs

1//! `SubMsRecipe` impl. Behind the `harness` feature.
2
3use subms::{
4    SubMsBenchParams, SubMsLcg, SubMsPerfHarness, SubMsRecipe, SubMsStageKind, SubMsTimer,
5};
6
7use crate::HyperLogLog;
8
9/// Stages: `add`, `estimate`.
10pub struct HyperLogLogRecipe;
11
12impl SubMsRecipe for HyperLogLogRecipe {
13    fn name(&self) -> &str {
14        "hyperloglog"
15    }
16
17    fn run(&self, h: &mut SubMsPerfHarness, params: &SubMsBenchParams) {
18        let entries = params.entries;
19        let warmup = params.warmup;
20        let seed = params.seed;
21        let mut hll = HyperLogLog::new(14);
22
23        // Warm-up
24        let mut rng = SubMsLcg::new(seed);
25        for _ in 0..warmup {
26            hll.add(&format!("warm{}", rng.next_u32()));
27        }
28
29        let s_add = h.stage("add", entries).with_kind(SubMsStageKind::HotPath);
30        let mut rng = SubMsLcg::new(seed.wrapping_add(1));
31        for _ in 0..entries {
32            let key = format!("k{}", rng.next_u32());
33            let t0 = SubMsTimer::tick();
34            hll.add(&key);
35            s_add.record(t0.elapsed_ns());
36        }
37
38        let s_est = h.stage("estimate", 100).with_kind(SubMsStageKind::HotPath);
39        for _ in 0..100 {
40            let t0 = SubMsTimer::tick();
41            let _ = hll.estimate();
42            s_est.record(t0.elapsed_ns());
43        }
44
45        h.add_meta("precision", "14");
46        h.add_meta("registers", &hll.register_count().to_string());
47        h.add_meta("estimate", &(hll.estimate() as u64).to_string());
48    }
49}