benchmark
stableHigh-resolution timing, iteration benchmarking, throughput measurement, and Markdown/CSV report generation for performance profiling.
use plugin benchmark::{Bench.new, Bench.start, Bench.stop, …} Functions (18)
- Bench.new Create a named benchmark timer
- Bench.start Record the start time
- Bench.stop Stop and return the elapsed table
- Bench.reset Clear start and elapsed state
- Bench.run_iterations Time n iterations, return min/avg/max
- BenchSuite.new Create a suite of named benchmarks
- BenchSuite.add Register a benchmark entry
- BenchSuite.run_all Run all entries, return a results table
- BenchSuite.compare_all Run all and add a relative speedup field
- now_ns Read current Unix time in nanoseconds
- format_duration Format nanoseconds as a human-readable string
- compare Compare two benchmark results
- memory_usage Read current process memory in bytes
- throughput Measure ops/sec and MB/sec
- percentiles Compute p50/p90/p95/p99 from samples
- warmup Run empty iterations to warm the CPU
- report_markdown Format a results table as Markdown
- report_csv Format a results table as CSV
Overview
The benchmark plugin measures how fast your code runs. Its core concept is the
handle-backed timer: Bench.new(name) returns a Bench handle whose
.start() / .stop() calls bracket the code under test and report elapsed time
down to the nanosecond. For comparing many candidates at once, BenchSuite
collects named entries and runs them together, producing a uniform results
table. A set of free functions rounds out the toolkit — reading the wall clock
(now_ns), formatting durations, sampling percentiles, estimating throughput,
and rendering results as Markdown or CSV.
Reach for this plugin whenever you want repeatable, structured timing data
instead of ad-hoc print timestamps: micro-benchmarks, regression checks, or
generating a report table to paste into a PR.
Common patterns
Bracket a block of code with a single timer and print a human-readable duration:
use plugin benchmark::{Bench, format_duration}
let b = Bench.new("hash_table_fill")
b.start()
let i = 0
while i < 100000 {
let i = i + 1
}
let r = b.stop()
print("{r["name"]}: {format_duration(r["elapsed_ns"])}")
Warm up the CPU, run a suite of competing implementations, and emit a Markdown report:
use plugin benchmark::{BenchSuite, warmup, report_markdown}
warmup(10000)
let suite = BenchSuite.new()
suite.add("encode_v1", 1000)
suite.add("encode_v2", 1000)
let results = suite.run_all()
print(report_markdown(results))
Compare two measured results and report the speedup:
use plugin benchmark::{Bench, compare}
let a = Bench.new("baseline")
a.start()
let a_result = a.stop()
let b = Bench.new("optimized")
b.start()
let b_result = b.stop()
let cmp = compare(a_result, b_result)
print("{cmp["faster"]} is {cmp["speedup_ratio"]}x faster ({cmp["diff_ns"]}ns)")
Create a named benchmark timer
Creates a named benchmark timer and returns a Bench handle. The name is
echoed back in the table returned by stop(), which makes it easy to label
results. Call .start() before the code under test and .stop() after.
use plugin benchmark::{Bench}
let b = Bench.new("json_parse")
b.start()
// ... code to measure ...
let result = b.stop()
print("elapsed: {result["elapsed_ms"]}ms")
Record the start time
Records the current Instant as the timer's start point and clears any
previously recorded elapsed value. Calling start() again restarts the timer
from scratch.
use plugin benchmark::{Bench}
let b = Bench.new("retry")
b.start()
// ... attempt one ...
b.start() // discard the first run and time again
// ... attempt two ...
let r = b.stop()
print("{r["elapsed_ms"]}ms")
Stop and return the elapsed table
Stops the timer and returns a table with elapsed_ns (integer nanoseconds),
elapsed_ms (float milliseconds), and name. Errors if the timer was never
started.
use plugin benchmark::{Bench, format_duration}
let b = Bench.new("loop")
b.start()
let i = 0
while i < 100000 {
let i = i + 1
}
let r = b.stop()
print(format_duration(r["elapsed_ns"]))
Clear start and elapsed state
Clears both the start point and any recorded elapsed value, returning the timer to its initial state so it can be reused for a fresh measurement.
use plugin benchmark::{Bench}
let b = Bench.new("reused")
b.start()
let first = b.stop()
b.reset()
b.start()
let second = b.stop()
print("{first["elapsed_ms"]}ms then {second["elapsed_ms"]}ms")
Time n iterations, return min/avg/max
Runs n timing iterations and returns a table with total_ns, avg_ns,
min_ns, max_ns, and iterations. Useful for getting min/avg/max spread
from repeated measurements. Errors if n is 0.
use plugin benchmark::{Bench}
let b = Bench.new("micro")
let stats = b.run_iterations(1000)
print("avg={stats["avg_ns"]}ns min={stats["min_ns"]}ns max={stats["max_ns"]}ns")
Create a suite of named benchmarks
Creates an empty benchmark suite that can hold multiple named entries and run them all together, returning a uniform results table for every entry.
use plugin benchmark::{BenchSuite, report_markdown}
let suite = BenchSuite.new()
suite.add("task_a", 1000)
suite.add("task_b", 1000)
let results = suite.run_all()
print(report_markdown(results))
Register a benchmark entry
Registers a benchmark entry with the given name and number of iterations.
Entries run in the order they were added when run_all() or compare_all()
is called.
use plugin benchmark::{BenchSuite}
let suite = BenchSuite.new()
suite.add("small_input", 500)
suite.add("large_input", 5000)
let results = suite.run_all()
print(results[0]["name"])
Run all entries, return a results table
Runs every registered entry and returns a table of rows. Each row is a table
with name, total_ns, avg_ns, min_ns, max_ns, and iterations. The
shape matches what report_markdown and report_csv expect.
use plugin benchmark::{BenchSuite, report_csv}
let suite = BenchSuite.new()
suite.add("alpha", 1000)
suite.add("beta", 1000)
let results = suite.run_all()
print(report_csv(results))
Run all and add a relative speedup field
Runs every entry like run_all, then appends a relative field to each row —
the entry's avg_ns divided by the fastest entry's avg_ns. A value of 1.0
marks the fastest entry; larger values are proportionally slower.
use plugin benchmark::{BenchSuite}
let suite = BenchSuite.new()
suite.add("alpha", 500)
suite.add("beta", 500)
let cmp = suite.compare_all()
print("alpha is {cmp[0]["relative"]}x the fastest")
Read current Unix time in nanoseconds
Returns the current Unix time as nanoseconds since the epoch. Use two calls
around a block of code to measure wall-clock elapsed time manually, without a
Bench handle.
use plugin benchmark::{now_ns, format_duration}
let t0 = now_ns()
// ... work ...
let t1 = now_ns()
print(format_duration(t1 - t0))
Format nanoseconds as a human-readable string
Converts a nanosecond integer to a readable string: "Xns" below a
microsecond, "Xµs" below a millisecond, or "X.XXms" at or above a
millisecond.
use plugin benchmark::{format_duration}
print(format_duration(500))
print(format_duration(12500))
print(format_duration(3200000))
Compare two benchmark results
Compares two benchmark result tables (from stop() or run_iterations()). It
reads the first of elapsed_ns, avg_ns, or total_ns it finds in each
table. Returns a table with faster ("a" or "b"), speedup_ratio (float),
and diff_ns (absolute difference).
use plugin benchmark::{Bench, compare}
let a = Bench.new("a")
a.start()
let a_result = a.stop()
let b = Bench.new("b")
b.start()
let b_result = b.stop()
let cmp = compare(a_result, b_result)
print("{cmp["faster"]} is {cmp["speedup_ratio"]}x faster")
Read current process memory in bytes
Returns the current process resident memory in bytes (working set on Windows,
RSS on Linux/macOS). Returns 0 on unsupported platforms. Useful for tracking
allocations before and after a workload.
use plugin benchmark::{memory_usage}
let before = memory_usage()
// ... allocate data ...
let after = memory_usage()
print("used {after - before} bytes")
Measure ops/sec and MB/sec
Times iterations no-op cycles and uses that elapsed time to estimate
throughput. Returns a table with ops_per_sec, mb_per_sec (derived from
bytes_processed), and elapsed_ns.
use plugin benchmark::{throughput}
let result = throughput("encode", 100000, 1048576)
print("{result["ops_per_sec"]} ops/sec")
print("{result["mb_per_sec"]} MB/sec")
Compute p50/p90/p95/p99 from samples
Computes the p50, p90, p95, and p99 percentiles from a flat table of numeric timing samples (nanoseconds). Integer and float values are both accepted. Errors if the table contains no numeric values.
use plugin benchmark::{percentiles}
let samples = [120, 135, 98, 200, 145, 110, 300, 125, 140, 108]
let p = percentiles(samples)
print("p50={p["p50"]} p99={p["p99"]}")
Run empty iterations to warm the CPU
Runs iterations empty no-op cycles to warm up the CPU branch predictor and
caches before a timed benchmark. Call this before start() for more stable,
repeatable results.
use plugin benchmark::{warmup, Bench}
warmup(10000)
let b = Bench.new("hot_path")
b.start()
// ... measured code ...
let r = b.stop()
print("{r["elapsed_ms"]}ms")
Format a results table as Markdown
Formats a results table (from run_all() or any list of rows with the same
fields) as a Markdown table string with columns: Name, Total (ns), Avg (ns),
Min (ns), Max (ns), Iterations. Missing fields default to ? or 0.
use plugin benchmark::{BenchSuite, report_markdown}
let suite = BenchSuite.new()
suite.add("op_a", 1000)
suite.add("op_b", 1000)
let results = suite.run_all()
let md = report_markdown(results)
print(md)
Format a results table as CSV
Formats a results table as a CSV string with the same columns as
report_markdown. The first line is the header row, suitable for saving to a
file or importing into a spreadsheet.
use plugin benchmark::{BenchSuite, report_csv}
let suite = BenchSuite.new()
suite.add("encode", 500)
suite.add("decode", 500)
let results = suite.run_all()
let csv = report_csv(results)
print(csv)