Skip to main content

bench_min_rotational_hamming/
bench_min_rotational_hamming.rs

1//! Micro-benchmark for `min_rotational_hamming_distance`.
2//!
3//! Mirrors the three scenarios in the Scala twin's ComparingBench:
4//!   * rotation  — best case, distance 0 (`a` vs a rotation of `a`)
5//!   * oneOff    — mid case, distance 1
6//!   * reversed  — worst case, distance close to `n`
7//!
8//! Run with: `cargo run --release --example bench_min_rotational_hamming`.
9
10use std::hint::black_box;
11use std::time::Instant;
12
13use ring_seq::AsCircular;
14
15fn rotated(a: &[u32], k: usize) -> Vec<u32> {
16    let n = a.len();
17    (0..n).map(|i| a[(i + k) % n]).collect()
18}
19
20fn one_off(a: &[u32]) -> Vec<u32> {
21    let mut v = a.to_vec();
22    if !v.is_empty() {
23        v[0] = v[0].wrapping_add(1);
24    }
25    v
26}
27
28fn reversed(a: &[u32]) -> Vec<u32> {
29    let mut v = a.to_vec();
30    v.reverse();
31    v
32}
33
34fn bench_case(label: &str, n: usize, iters: u64, a: &[u32], b: &[u32]) {
35    // warm-up
36    for _ in 0..(iters / 10).max(1) {
37        black_box(a.circular().min_rotational_hamming_distance(black_box(b)));
38    }
39    let start = Instant::now();
40    let mut acc: usize = 0;
41    for _ in 0..iters {
42        acc = acc.wrapping_add(black_box(
43            a.circular().min_rotational_hamming_distance(black_box(b)),
44        ));
45    }
46    let elapsed = start.elapsed();
47    let ns_per_op = elapsed.as_nanos() as f64 / iters as f64;
48    println!(
49        "{:<10} n={:<5} iters={:<10} total={:>10.3?} ns/op={:>12.0} (acc={})",
50        label, n, iters, elapsed, ns_per_op, acc
51    );
52}
53
54fn iters_for(n: usize) -> u64 {
55    match n {
56        16 => 1_000_000,
57        256 => 10_000,
58        4096 => 50,
59        _ => 1_000,
60    }
61}
62
63fn main() {
64    for &n in &[16usize, 256, 4096] {
65        let base: Vec<u32> = (0..n as u32).collect();
66        let rot = rotated(&base, n / 3);
67        let off = one_off(&base);
68        let rev = reversed(&base);
69        let iters = iters_for(n);
70
71        bench_case("rotation", n, iters, &base, &rot);
72        bench_case("oneOff  ", n, iters, &base, &off);
73        bench_case("reversed", n, iters, &base, &rev);
74        println!();
75    }
76}