Skip to content

benchmark

stable

High-resolution timing, iteration benchmarking, throughput measurement, and Markdown/CSV report generation for performance profiling.

use plugin benchmark::{Bench.new, Bench.start, Bench.stop, …}
18 functions Utilities
/ filter jk navigate Esc clear
Functions (18)
  1. Bench.new Create a named benchmark timer
  2. Bench.start Record the start time
  3. Bench.stop Stop and return the elapsed table
  4. Bench.reset Clear start and elapsed state
  5. Bench.run_iterations Time n iterations, return min/avg/max
  6. BenchSuite.new Create a suite of named benchmarks
  7. BenchSuite.add Register a benchmark entry
  8. BenchSuite.run_all Run all entries, return a results table
  9. BenchSuite.compare_all Run all and add a relative speedup field
  10. now_ns Read current Unix time in nanoseconds
  11. format_duration Format nanoseconds as a human-readable string
  12. compare Compare two benchmark results
  13. memory_usage Read current process memory in bytes
  14. throughput Measure ops/sec and MB/sec
  15. percentiles Compute p50/p90/p95/p99 from samples
  16. warmup Run empty iterations to warm the CPU
  17. report_markdown Format a results table as Markdown
  18. 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)
enespt-br