Skip to main content

bench/
bench.rs

1//! Throughput benchmark for every scheme in `id-forge`.
2//!
3//! Single-threaded. Uses `std::time::Instant` — no Criterion, no
4//! external dependency. Intended for quick smoke-grade measurements
5//! and regression checks against the [`REPS`] performance targets, not
6//! statistically rigorous reporting.
7//!
8//! Run with:
9//!
10//! ```text
11//! cargo run --release --example bench
12//! ```
13//!
14//! [`REPS`]: ../../REPS.md
15
16use id_forge::{nanoid, snowflake::Snowflake, ulid::Ulid, uuid::Uuid};
17use std::time::Instant;
18
19fn bench<R>(name: &str, iters: usize, mut f: impl FnMut() -> R) {
20    for _ in 0..(iters / 10).max(1) {
21        let _ = f();
22    }
23    let start = Instant::now();
24    for _ in 0..iters {
25        let _ = f();
26    }
27    let elapsed = start.elapsed();
28    let per_op_ns = elapsed.as_nanos() as f64 / iters as f64;
29    let throughput = 1_000_000_000.0 / per_op_ns;
30    println!("{name:<32} {iters:>9} iters  {per_op_ns:>8.1} ns/op   {throughput:>10.0} ops/s");
31}
32
33fn main() {
34    println!("id-forge throughput (single thread, release build)");
35    println!("---------------------------------------------------");
36
37    let iters = 1_000_000;
38    bench("Uuid::v4", iters, Uuid::v4);
39    bench("Uuid::v7", iters, Uuid::v7);
40    bench("Ulid::new", iters, Ulid::new);
41
42    let sf = Snowflake::new(1);
43    bench("Snowflake::next_id", iters, || sf.next_id());
44
45    bench("nanoid::generate", iters / 5, nanoid::generate);
46    bench("nanoid::with_length(8)", iters / 5, || {
47        nanoid::with_length(8)
48    });
49    bench("nanoid::custom(16, hex)", iters / 5, || {
50        nanoid::custom(16, b"0123456789abcdef")
51    });
52    bench("nanoid::custom(21, 17-char)", iters / 5, || {
53        nanoid::custom(21, b"ABCDEFGHIJKLMNOPQ")
54    });
55}