use apache_datasketches::tuple::ArrayOfDoublesSketchBuilder;
use std::time::{Duration, Instant};
const LG_K: u8 = 12;
const NUM_VALUES: u8 = 3;
const HOT_KEY_SPACE: u64 = 1 << 10;
const VALUES: [f64; 3] = [1.0, 2.0, 3.0];
fn report(label: &str, items: u64, elapsed: Duration, estimate: f64) {
let nanos = elapsed.as_secs_f64() * 1e9;
let per_op = nanos / items as f64;
let rate = items as f64 / elapsed.as_secs_f64() / 1e6;
println!(
"{label:9} {items:>12} items {:>8.3} s {per_op:>7.2} ns/op {rate:>8.1} M/s \
(estimate {estimate:.0})",
elapsed.as_secs_f64()
);
}
fn bench_distinct(items: u64) {
let mut sketch = ArrayOfDoublesSketchBuilder::new()
.lg_k(LG_K)
.num_values(NUM_VALUES)
.build()
.expect("builder rejected fixed valid parameters");
let start = Instant::now();
for key in 0..items {
sketch
.update_u64(key, &VALUES)
.expect("update rejected a correctly-sized value slice");
}
let elapsed = start.elapsed();
report("distinct", items, elapsed, sketch.get_estimate());
}
fn bench_hot(items: u64) {
let mut sketch = ArrayOfDoublesSketchBuilder::new()
.lg_k(LG_K)
.num_values(NUM_VALUES)
.build()
.expect("builder rejected fixed valid parameters");
let start = Instant::now();
for i in 0..items {
sketch
.update_u64(i % HOT_KEY_SPACE, &VALUES)
.expect("update rejected a correctly-sized value slice");
}
let elapsed = start.elapsed();
report("hot", items, elapsed, sketch.get_estimate());
}
fn main() {
let items: u64 = std::env::args()
.nth(1)
.map(|arg| arg.parse().expect("item count must be a positive integer"))
.unwrap_or(10_000_000);
println!("lg_k={LG_K} num_values={NUM_VALUES} items={items}");
bench_distinct(items);
bench_hot(items);
}