subms_hyperloglog/
recipe.rs1use subms::{
4 SubMsBenchParams, SubMsLcg, SubMsPerfHarness, SubMsRecipe, SubMsStageKind, SubMsTimer,
5};
6
7use crate::HyperLogLog;
8
9pub struct HyperLogLogRecipe;
11
12const ESTIMATE_SAMPLES: usize = 2_000;
17
18const ESTIMATE_WARM: usize = 64;
22
23impl SubMsRecipe for HyperLogLogRecipe {
24 fn name(&self) -> &str {
25 "hyperloglog"
26 }
27
28 fn run(&self, h: &mut SubMsPerfHarness, params: &SubMsBenchParams) {
29 let entries = params.entries;
30 let warmup = params.warmup;
31 let seed = params.seed;
32 let mut hll = HyperLogLog::new(14);
33
34 let mut rng = SubMsLcg::new(seed);
36 for _ in 0..warmup {
37 hll.add(&format!("warm{}", rng.next_u32()));
38 }
39
40 let s_add = h.stage("add", entries).with_kind(SubMsStageKind::HotPath);
41 let mut rng = SubMsLcg::new(seed.wrapping_add(1));
42 for _ in 0..entries {
43 let key = format!("k{}", rng.next_u32());
44 let t0 = SubMsTimer::tick();
45 hll.add(&key);
46 s_add.record(t0.elapsed_ns());
47 }
48
49 for _ in 0..ESTIMATE_WARM {
50 std::hint::black_box(hll.estimate());
51 }
52 let s_est = h
53 .stage("estimate", ESTIMATE_SAMPLES)
54 .with_kind(SubMsStageKind::HotPath);
55 for _ in 0..ESTIMATE_SAMPLES {
56 let t0 = SubMsTimer::tick();
57 std::hint::black_box(hll.estimate());
60 s_est.record(t0.elapsed_ns());
61 }
62
63 h.add_meta("precision", "14");
64 h.add_meta("registers", &hll.register_count().to_string());
65 h.add_meta("estimate", &(hll.estimate() as u64).to_string());
66 }
67}