Skip to main content

bench/
bench.rs

1//! Dependency-free micro-benchmarks for the hot paths.
2//!
3//! Run with `cargo run --release --example bench`. The numbers are wall-clock
4//! timings of a fixed workload, printed as nanoseconds-per-operation; they
5//! are meant to catch regressions on a given machine, not to be compared
6//! across machines. CI runs this in release mode.
7
8use std::hint::black_box;
9use std::time::Instant;
10
11use tzcraft::{CivilDateTime, Date, Duration, Ticks, TimeOfDay};
12
13fn bench<F: FnMut()>(name: &str, iters: u64, mut f: F) {
14    // Warm up the CPU caches and let the branch predictor settle.
15    for _ in 0..10_000 {
16        f();
17    }
18    let start = Instant::now();
19    for _ in 0..iters {
20        f();
21    }
22    let elapsed = start.elapsed().as_nanos();
23    let per_op = elapsed / iters as u128;
24    println!("{name:<40} {per_op:>8} ns/op");
25}
26
27fn main() {
28    let d = Date::from_ymd(2024, 6, 15).unwrap();
29    let t = TimeOfDay::from_hms_nano(8, 30, 0, 123_456_789).unwrap();
30    let dt = CivilDateTime::new(d, t);
31    let ticks = Ticks::from_rfc3339("2024-06-15T08:30:00.123456789Z").unwrap();
32    let span = Duration::from_nanos(123_456_789_123);
33    let mut out = [0u8; 64];
34
35    bench("date civil projection (parts)", 1_000_000, || {
36        black_box(black_box(d).parts());
37    });
38    bench("date weekday", 1_000_000, || {
39        black_box(black_box(d).weekday());
40    });
41    bench("ticks -> civil utc", 1_000_000, || {
42        let _ = black_box(black_box(ticks).to_civil_utc());
43    });
44    bench("ticks -> unix seconds", 1_000_000, || {
45        let _ = black_box(black_box(ticks).to_unix_seconds());
46    });
47    bench("civil -> ticks utc", 1_000_000, || {
48        let _ = black_box(black_box(dt).to_ticks_utc());
49    });
50    bench("ticks checked_add duration", 1_000_000, || {
51        let _ = black_box(black_box(ticks).checked_add(black_box(span)));
52    });
53    bench("parse RFC 3339", 200_000, || {
54        let _ = black_box(Ticks::from_rfc3339("2024-06-15T08:30:00.123456789Z"));
55    });
56    bench("format RFC 3339 (buffer)", 200_000, || {
57        let _ = black_box(black_box(ticks).write_rfc3339(&mut out, tzcraft::FractionDigits::Auto));
58    });
59    bench("format strftime (buffer)", 200_000, || {
60        let _ = black_box(black_box(ticks).write_format("%Y-%m-%d %H:%M:%S%.f", &mut out));
61    });
62    bench("parse ISO 8601 duration", 200_000, || {
63        let _ = black_box(Duration::from_iso8601("P1DT2H3M4.5S"));
64    });
65}