Skip to main content

bench_overhead/
bench_overhead.rs

1//! Per-allocation overhead micro-benchmark.
2//!
3//! Runs a tight allocate/deallocate loop and reports the average
4//! nanoseconds per allocation observed end-to-end. The number
5//! includes the cost of `System` itself; the `ModAlloc` overhead is
6//! the difference between this number and a System-only baseline.
7//!
8//! REPS section 6 sets a target of <50ns of `ModAlloc` overhead per
9//! allocation on x86_64. This bench is a sanity-check, not a
10//! rigorous benchmark; for precise measurement, prefer a tool that
11//! controls CPU pinning and isolates noise.
12//!
13//! Run with: `cargo run --release --example bench_overhead`
14
15use std::time::Instant;
16
17use mod_alloc::ModAlloc;
18
19#[global_allocator]
20static GLOBAL: ModAlloc = ModAlloc::new();
21
22const WARMUP: usize = 50_000;
23const N: usize = 1_000_000;
24const SIZE: usize = 64;
25
26fn main() {
27    for _ in 0..WARMUP {
28        let v: Vec<u8> = Vec::with_capacity(SIZE);
29        std::hint::black_box(&v);
30    }
31
32    GLOBAL.reset();
33    let start = Instant::now();
34    for _ in 0..N {
35        let v: Vec<u8> = Vec::with_capacity(SIZE);
36        std::hint::black_box(&v);
37    }
38    let elapsed = start.elapsed();
39
40    let snap = GLOBAL.snapshot();
41    let per_cycle_ns = elapsed.as_nanos() as f64 / N as f64;
42
43    println!("bench_overhead:");
44    println!("  iterations:           {N}");
45    println!("  allocation size:      {SIZE} bytes");
46    println!("  elapsed:              {elapsed:?}");
47    println!("  per alloc+dealloc:    {per_cycle_ns:.1} ns");
48    println!();
49    println!("counter snapshot after run:");
50    println!("  alloc_count:   {}", snap.alloc_count);
51    println!("  total_bytes:   {}", snap.total_bytes);
52    println!("  current_bytes: {}", snap.current_bytes);
53    println!("  peak_bytes:    {}", snap.peak_bytes);
54}