Lcl · Core · Packages · Libraries


Bench

namespace Bench

Micro-benchmark harness for Lcl

Register suites and cases, then Bench::run times every case. Each body is compiled once and run in batches through repeat; the batch size calibrates itself (doubling) until one batch takes at least min_ms, and the row reports the median and minimum ns/iteration over batches batches, the copy-on-write clones per iteration and the live-value delta per batch (both from Interp::stats), and the change against a recorded baseline. Needs lcl-time for the monotonic clock.

Each batch runs the body inside a lambda created after the suite’s Bench::setup body, so setup bindings (let items ..., helper procs) are captured and visible, and everything the body itself binds dies with the batch – the live-value column only sees what the body leaks. A body that accumulates should start from a fresh var each iteration, as in the example.

Examples:

>> Bench::reset
>> Bench::suite "lists" { Bench::case "push!" { var l (); List::push! l 1 } }
>> Bench::run #{min_ms 1 batches 1 quiet 1}
0
>> has? [Bench::results] "lists/push!"
1

proc Bench::suite name body

Register a suite. body calls Bench::setup, Bench::case and Bench::expect_faster.

proc Bench::setup body

Code evaluated once before each case of the current suite (and outside the timed region); its bindings are visible to bodies.

proc Bench::case name body

Register a timed case in the current suite.

proc Bench::expect_faster fast slow (factor 1)

Assert, after measuring, that case fast runs at least factor times faster than case slow (same suite, median ns/iter). Failures make Bench::run return 1.

proc Bench::baseline d

Register baseline numbers: a dict of “suite/case” -> #{ns N}. A baseline file is a script that calls this; load it before Bench::run and rows show their change against it.

proc Bench::results

Results of the last Bench::run: “suite/case” -> #{ns median min clones_x10 live n}.

proc Bench::run (opts #{})

Time every registered case and print one row each.

opts keys: filter (substring of “suite/case”), min_ms (per-batch target, default 200), batches (default 5), profile (print a Time::profile table under each row), save (write a baseline file for the results), quiet. Returns 0, or 1 when an expect_faster assertion failed.

proc Bench::reset

Forget every registered suite, baseline and result.