Wado
<!-- Auto-generated by: wado doc -f markdown core:benchmark --> <!-- Do not edit this file directly. -->

core:benchmark

Benchmark utilities: lazy headers, timed phases, throughput reports.

Every phase reports a throughput figure (work done per second, higher is better) with the elapsed time retained alongside it. The throughput unit is chosen so the number is meaningful for the workload:

Used by files in benchmark/. A benchmark typically looks like:

use { Benchmark } from "core:benchmark";

test "benchmark" { run(); }

export fn run() with Stdout, MonotonicClock {
    let mut b = Benchmark { name: "count-prime" };
    b.work_per_iter = Option::Some(10_000_000.0);  // numbers screened
    b.unit = "numbers";
    let count = b.run("", || count_primes(10_000_000));
    b.println(`count = {count}`);
}

For multi-phase benchmarks, call run once per phase. A byte-sized input reports MB/s automatically:

let mut b = Benchmark { name: "zlib" };
b.input_size = Option::Some(data.len());  // → MB/s
let compressed = b.run("compress", || zlib_compress(&data));
let _ = b.run("decompress", || inflate_zlib(&compressed).unwrap());

Synopsis

let mut bench = Benchmark { name: "sum" };
bench.target_ms = 0;
let total = bench.run("1..=100", || {
    let mut n = 0;
    for let i of 1..=100 {
        n += i;
    }
    return n;
});
assert total == 5050;

Functions

pub fn format_rate(total_work: f64, elapsed_ns: u64, unit: String) -> String

Format a throughput figure: total_work units done over elapsed_ns nanoseconds, as a per-second rate. The byte unit ("B") renders with KB/MB/GB scaling; any other unit uses SI k/M/G prefixes. A zero elapsed time yields a 0.00 rate instead of dividing by zero.

Structs

pub struct Benchmark

A benchmark run. The driver prints a header on the first measurement, then a labeled line per run() phase reporting throughput (work per second) with the per-iteration time retained alongside it.

name: String

iterations: i32

Number of timed iterations. 0 (the default) auto-calibrates the iteration count so the timed loop runs for about target_ms milliseconds; the total elapsed time is then meaningless (~target_ms) so only the per-iteration figure and throughput are reported. Set a positive value to run a fixed iteration count instead.

target_ms: i32

Wall-clock budget in milliseconds for auto-calibration (used when iterations == 0). The loop grows the iteration count until the timed region reaches this duration. 0 runs exactly one iteration.

warmup: i32

Number of unmeasured warmup runs for fixed mode. -1 (the default) means "auto": 1 warmup if iterations >= 2, otherwise 0. Auto mode always performs one warmup before calibration.

input_size: Option<i32>

Optional input size in bytes, shown in the header (e.g. "631044 bytes"). When set and work_per_iter is unset, throughput is reported as a byte rate (MB/s).

work_per_iter: Option<f64>

Units of work performed per iteration, for the throughput figure. null (the default) means "auto": byte rate from input_size if it is set, otherwise iterations per second. Set this to report a custom work-rate (e.g. 5_000_000.0 conversions per iteration).

unit: String

Unit label for the throughput figure when work_per_iter is set (e.g. "conversions", "px", "numbers"). Ignored when throughput falls back to a byte rate or to ops/s.

pub fn run<T>(&mut self, label: String, mut f: fn mut() -> T) -> T with Stdout, MonotonicClock

Run a single phase and report its throughput.

In auto mode (iterations == 0) the iteration count is calibrated so the timed loop runs for about target_ms milliseconds. In fixed mode (iterations > 0) it performs warmup unmeasured runs (the -1 default auto-derives to 1 when iterations >= 2, otherwise 0) then exactly iterations timed runs. Prints the header on first call. Returns the final timed iteration's value.

label may be empty for an unlabeled single-phase benchmark.

pub fn println(&mut self, msg: String) with Stdout

Print an indented note line. Useful for accumulator values or final counts alongside the timing output.