bench_min_rotational_hamming/
bench_min_rotational_hamming.rs1#![allow(clippy::incompatible_msrv)]
14
15use std::hint::black_box;
16use std::time::Instant;
17
18use ring_seq::AsCircular;
19
20fn rotated(a: &[u32], k: usize) -> Vec<u32> {
21 let n = a.len();
22 (0..n).map(|i| a[(i + k) % n]).collect()
23}
24
25fn one_off(a: &[u32]) -> Vec<u32> {
26 let mut v = a.to_vec();
27 if !v.is_empty() {
28 v[0] = v[0].wrapping_add(1);
29 }
30 v
31}
32
33fn reversed(a: &[u32]) -> Vec<u32> {
34 let mut v = a.to_vec();
35 v.reverse();
36 v
37}
38
39fn bench_case(label: &str, n: usize, iters: u64, a: &[u32], b: &[u32]) {
40 for _ in 0..(iters / 10).max(1) {
42 black_box(a.circular().min_rotational_hamming_distance(black_box(b)));
43 }
44 let start = Instant::now();
45 let mut acc: usize = 0;
46 for _ in 0..iters {
47 acc = acc.wrapping_add(black_box(
48 a.circular().min_rotational_hamming_distance(black_box(b)),
49 ));
50 }
51 let elapsed = start.elapsed();
52 let ns_per_op = elapsed.as_nanos() as f64 / iters as f64;
53 println!(
54 "{:<10} n={:<5} iters={:<10} total={:>10.3?} ns/op={:>12.0} (acc={})",
55 label, n, iters, elapsed, ns_per_op, acc
56 );
57}
58
59fn iters_for(n: usize) -> u64 {
60 match n {
61 16 => 1_000_000,
62 256 => 10_000,
63 4096 => 50,
64 _ => 1_000,
65 }
66}
67
68fn main() {
69 for &n in &[16usize, 256, 4096] {
70 let base: Vec<u32> = (0..n as u32).collect();
71 let rot = rotated(&base, n / 3);
72 let off = one_off(&base);
73 let rev = reversed(&base);
74 let iters = iters_for(n);
75
76 bench_case("rotation", n, iters, &base, &rot);
77 bench_case("oneOff ", n, iters, &base, &off);
78 bench_case("reversed", n, iters, &base, &rev);
79 println!();
80 }
81}