// Benchmark runner (T-03) — the T-01 clock probe main evolved into the full
// v0.2 performance runner per the plan ("演进为正式运行器"; the probe output
// is preserved in git history and docs/evidence/clock-probe-2026-09-13.log,
// no --probe mode is kept).
//
// Contract (see moon.pkg for run commands and the target-file mapping):
// - load the T-02 generated sample set — `samples` / `sample_strata` /
// `sample_set_hash`, same package (see samples.mbt); strata are loaded
// via the declared stratum inventory check below, so all three T-02
// bindings are consumed;
// - measurement scope (v2 2026-09-13 revision, controller ruling): the
// corpus is still FULLY loaded (sample_set_hash provenance unchanged),
// but each timed round parses a declared STRATIFIED STRIDE SUBSAMPLE of
// it — indices i*BENCH_STRIDE over the stratum-grouped corpus array
// cover every stratum proportionally to the generator's allocation.
// Rationale: the engine measures ~37.5 ms/parse (native --release) and
// ~13.8 ms/parse (js --release) on this corpus, so a 10k full round
// (~375 s / ~138 s) is not a feasible measurement unit; the per-round
// iteration count is a declared measurement parameter (sample_count=),
// not part of the loading contract;
// - default run (no args): WARMUP_ROUNDS untimed warmup passes, then
// TIMED_ROUNDS timed passes; each pass = one sequential parse() over
// the stride subsample (default 10000/20 = 500 samples; smoke 10000/50
// = 200); ops_per_sec[round] = sample_count / round_seconds; the
// reported value is the MEDIAN of the per-round ops_per_sec, and
// ns_per_parse = 1e9 / median_ops_per_sec (same-source dual metric,
// self-consistent);
// - every parse result is consumed into a deterministic checksum that is
// compared across rounds and printed (samples_checksum=, folded over
// the parsed subsample) so dead-code elimination cannot drop parses
// and round data is validated;
// - `-- --smoke`: the SMOKE_STRIDE subsample, same warmup/timed
// structure, compared against the calibrated coarse threshold
// SMOKE_NS_PER_PARSE_LIMIT (pinned in T-06); if the median
// ns_per_parse exceeds the limit the FULL report is printed FIRST and
// only then abort() ends the process non-zero — the report is always
// already on stdout when the exit code turns non-zero; the normal path
// exits 0;
// - `-- --profile` (T-05, controller ruling a: permanent bench-infra
// instrumentation): per-domain hot-path split on the PROFILE_STRIDE
// subsample. One untimed warmup pass, then PROFILE_TIMED_REPS timed
// reps; each rep times parse_browser / parse_os / parse_device and a
// full parse() separately through the SAME single clock seam, so the
// per-domain shares of a full parse are directly measurable. The
// template-replacement cost is reported as
// full − (browser + os + device): an UPPER-BOUND estimate (each
// single-domain pass pays its own loop overhead once, and cross-pass
// noise can push the difference negative — reported as measured).
// An untimed rule-index pass (parse with with_rule_index=true) reports
// per-domain miss counts and winning-rule index statistics, i.e. how
// many regex trials each domain typically needs before its first match
// (a miss means the domain scanned ALL its rules). Every pass folds a
// checksum consumed into the report (profile-rep / profile-checksum
// lines) so dead-code elimination cannot drop work and cross-rep drift
// is detected. If both --profile and --smoke are given, --profile
// takes precedence (the combination is not a defined mode).
// - ALL clock access stays inside the single seam `clock_pair_diff_us`
// (moonbitlang/core/bench monotonic clock pair; per-target dispatch
// lives inside core/bench, per-backend file selection inside moon.pkg
// options(targets:)). Statistics below have ZERO backend branching —
// the only per-backend artifact in this package is backend_label()
// from clock_{native,js,wasm}.mbt.
///|
/// Fixed round structure; declared in every report's bench-config line.
const WARMUP_ROUNDS : Int = 2
///|
/// Timed rounds k (odd, so the median is an exact measured round).
const TIMED_ROUNDS : Int = 7
///|
/// Default-mode stride over the fully loaded corpus: every round parses
/// indices 0, 20, 40, ... → 10000/20 = 500 samples per round (declared as
/// sample_count= in the bench-config line).
const BENCH_STRIDE : Int = 20
///|
/// Smoke-mode stride: indices 0, 50, 100, ... → 10000/50 = 200 samples.
const SMOKE_STRIDE : Int = 50
///|
/// Calibrated coarse smoke threshold: 150 ms per parse (T-06, pinned
/// 2026-09-13 from the B2 baseline). Derivation: T-04 native
/// median-of-medians 23.64 ops/s = 42,299,995.40 ns/parse; x3 ≈ 126.9 ms;
/// rounded up to 150 ms so the buffer additionally covers the hardware
/// difference between this host (Windows 10 19045) and the CI runner
/// (ubuntu-latest) plus the native noise band (T-04 measured up to 11.85%
/// cross-run deviation). Sanity: T-05 measured smoke-mode ≈44.33 ms/parse
/// → ≈3.4x headroom, so the normal path exits 0. If a CI run ever misfires
/// here, return to THIS constant and recalibrate from a fresh baseline —
/// do not tune the engine for the threshold.
const SMOKE_NS_PER_PARSE_LIMIT : Double = 150_000_000.0
///|
/// Profile-mode stride (T-05): indices 0, 50, 100, ... → 10000/50 = 200
/// samples per pass. One parse is ~40 ms on native, so 200 samples give
/// multi-second passes (well above clock noise) while a whole profile run
/// stays around one minute.
const PROFILE_STRIDE : Int = 50
///|
/// Profile-mode untimed warmup passes (compiles the lazily initialized
/// rule set and warms caches; the last pass anchors the checksums).
const PROFILE_WARMUP_PASSES : Int = 1
///|
/// Profile-mode timed repetitions per domain (odd, so the median is an
/// exactly measured rep).
const PROFILE_TIMED_REPS : Int = 3
///|
/// Single-point timing seam: run `work` once between two monotonic clock
/// reads and return the elapsed microseconds. The ONLY place in this
/// package that names a clock API (T-01's read-pair seam evolved to time a
/// unit of work; same @core_bench.monotonic_clock_start/end pair).
fn clock_pair_diff_us(work : () -> Unit) -> Double {
let t0 = @core_bench.monotonic_clock_start()
work()
@core_bench.monotonic_clock_end(t0)
}
///|
/// One sequential parse pass over `inputs` — one benchmark round of work.
/// Folds a deterministic checksum from every result (browser/os/device
/// family lengths; +1 per Err) so every parse is consumed and dead-code
/// elimination cannot skip work. Deterministic: identical inputs give an
/// identical checksum, and main compares it across rounds.
fn parse_pass(inputs : Array[String]) -> Int {
let mut checksum = 0
for ua in inputs {
match @ua_parser.parse(ua) {
Ok(info) => {
checksum = checksum + info.browser.family.length()
checksum = checksum + info.os.family.length()
checksum = checksum + info.device.family.length()
}
Err(_) => checksum = checksum + 1
}
}
checksum
}
///|
/// Browser-domain-only pass (T-05 --profile): same fold structure as
/// parse_pass so every call is consumed and dead-code elimination cannot
/// skip work.
fn browser_pass(inputs : Array[String]) -> Int {
let mut checksum = 0
for ua in inputs {
checksum = checksum + @ua_parser.parse_browser(ua).family.length()
}
checksum
}
///|
/// OS-domain-only pass (T-05 --profile); see browser_pass.
fn os_only_pass(inputs : Array[String]) -> Int {
let mut checksum = 0
for ua in inputs {
checksum = checksum + @ua_parser.parse_os(ua).family.length()
}
checksum
}
///|
/// Device-domain-only pass (T-05 --profile); see browser_pass.
fn device_only_pass(inputs : Array[String]) -> Int {
let mut checksum = 0
for ua in inputs {
checksum = checksum + @ua_parser.parse_device(ua).family.length()
}
checksum
}
///|
/// Stratified stride subsample of the fully loaded corpus: indices
/// i*stride (i = 0, 1, 2, ...) cover the whole stratum-grouped array, so
/// every stratum appears proportionally to the generator's allocation.
/// Default stride 20 → 500 samples/round; smoke/profile stride 50 → 200.
fn stride_subsample(inputs : Array[String], stride : Int) -> Array[String] {
let out : Array[String] = []
for i in 0.. Double {
let sorted : Array[Double] = []
for v in values {
sorted.push(v)
}
sorted.sort()
sorted[sorted.length() / 2]
}
///|
/// Median of a non-empty Int array (rule-index statistics in --profile).
/// Caller must guarantee non-emptiness (guarded at every call site).
fn median_int(values : Array[Int]) -> Int {
let sorted : Array[Int] = []
for v in values {
sorted.push(v)
}
sorted.sort()
sorted[sorted.length() / 2]
}
///|
/// Maximum of a non-empty Int array. Caller must guarantee non-emptiness
/// (guarded at every call site).
fn max_int(values : Array[Int]) -> Int {
let mut m = values[0]
for v in values {
if v > m {
m = v
}
}
m
}
///|
/// Format a non-negative Double with exactly 2 decimal places in plain
/// decimal form (never exponent form) so every key=value token in the
/// report stays greppable and keeps the required >=2 decimals of
/// precision.
fn fmt_fixed2(v : Double) -> String {
let scaled = (v * 100.0).floor().to_int64()
let whole = (scaled / 100L).to_string()
let frac = scaled % 100L
let frac_txt = if frac < 10L { "0\{frac}" } else { "\{frac}" }
"\{whole}.\{frac_txt}"
}
///|
/// Sanity-check the declared stratum inventory of the T-02 sample set:
/// `samples` and `sample_strata` are parallel arrays (same-name same-type
/// contract, see samples.mbt); scan them in parallel and return the number
/// of distinct strata actually seen, so the runner provably consumes
/// `sample_strata` alongside `samples`.
fn strata_inventory_check(inputs : Array[String], strata : Array[String]) -> Int {
let seen : Array[String] = []
let limit = if inputs.length() < strata.length() {
inputs.length()
} else {
strata.length()
}
for i in 0.. Unit {
let ns_per_parse = 1_000_000_000.0 / median_ops
println(
"bench-config mode=\{mode} backend=\{backend_label()} corpus_size=\{corpus_size} sample_count=\{sample_count} stride=\{stride} warmup_rounds=\{WARMUP_ROUNDS} timed_rounds=\{TIMED_ROUNDS} strata=\{strata_seen} smoke_threshold_ns_per_parse=\{fmt_fixed2(SMOKE_NS_PER_PARSE_LIMIT)} (calibrated, T-06)",
)
let mut i = 0
for ops in rounds {
println(
"bench-round round=\{i} ops_per_sec=\{fmt_fixed2(ops)} ns_per_parse=\{fmt_fixed2(1_000_000_000.0 / ops)}",
)
i = i + 1
}
println(
"bench-result backend=\{backend_label()} ops_per_sec=\{fmt_fixed2(median_ops)} ns_per_parse=\{fmt_fixed2(ns_per_parse)} sample_set_hash=\{sample_set_hash} samples_checksum=\{checksum} rounds_consistent=\{rounds_consistent}",
)
}
///|
/// One profile-rulestats line: per-domain miss count and winning-rule
/// index statistics over the profile subsample. A miss means the domain
/// scanned ALL of its rules; a win at index i means i+1 regex trials.
fn print_index_stats(
domain : String,
indices : Array[Int],
misses : Int,
samples : Int,
) -> Unit {
let matched = samples - misses
let rate = if samples > 0 {
matched.to_double() * 100.0 / samples.to_double()
} else {
0.0
}
let avg = if indices.length() > 0 {
let mut s = 0
for v in indices {
s = s + v
}
fmt_fixed2(s.to_double() / indices.length().to_double())
} else {
"-"
}
let med = if indices.length() > 0 {
"\{median_int(indices)}"
} else {
"-"
}
let max = if indices.length() > 0 { "\{max_int(indices)}" } else { "-" }
println(
"profile-rulestats domain=\{domain} samples=\{samples} matches=\{matched} misses=\{misses} match_rate_pct=\{fmt_fixed2(rate)} index_avg=\{avg} index_median=\{med} index_max=\{max}",
)
}
///|
/// T-05 --profile mode: per-domain hot-path split. See the file-header
/// contract comment. All timing goes through the single clock seam
/// clock_pair_diff_us; per-rep checksums guard against dead-code
/// elimination and cross-rep drift; the rule-index pass additionally
/// cross-checks that with_rule_index=true parsing produces the same
/// families (index checksum == full checksum).
fn profile_main() -> Unit {
let inputs = stride_subsample(samples, PROFILE_STRIDE)
let n = inputs.length()
let strata_seen = strata_inventory_check(samples, sample_strata)
// Warmup: untimed passes; the last pass anchors the expected checksums.
let mut full_sum = parse_pass(inputs)
for _ in 1.. 0.0 { med_f } else { 1.0 }
println(
"profile-median browser_ns_per_call=\{fmt_fixed2(med_b)} os_ns_per_call=\{fmt_fixed2(med_o)} device_ns_per_call=\{fmt_fixed2(med_d)} full_ns_per_call=\{fmt_fixed2(med_f)}",
)
println(
"profile-share browser_pct=\{fmt_fixed2(med_b * 100.0 / share_denom)} os_pct=\{fmt_fixed2(med_o * 100.0 / share_denom)} device_pct=\{fmt_fixed2(med_d * 100.0 / share_denom)} template_est_pct=\{fmt_fixed2(template_est * 100.0 / share_denom)} template_est_ns_per_call=\{fmt_fixed2(template_est)} (template = full - (browser+os+device), upper bound; noise can make it negative)",
)
// Untimed rule-index pass: winning rule index per domain with
// with_rule_index=true. Families are unaffected by the flag, so the
// folded checksum must equal the default full-parse checksum.
let bidx : Array[Int] = []
let oidx : Array[Int] = []
let didx : Array[Int] = []
let mut bmiss = 0
let mut omiss = 0
let mut dmiss = 0
let mut idx_sum = 0
for ua in inputs {
match @ua_parser.parse(ua, with_rule_index=true) {
Ok(info) => {
idx_sum = idx_sum + info.browser.family.length()
idx_sum = idx_sum + info.os.family.length()
idx_sum = idx_sum + info.device.family.length()
match info.browser.rule_index {
Some(i) => bidx.push(i)
None => bmiss = bmiss + 1
}
match info.os.rule_index {
Some(i) => oidx.push(i)
None => omiss = omiss + 1
}
match info.device.rule_index {
Some(i) => didx.push(i)
None => dmiss = dmiss + 1
}
}
Err(_) => idx_sum = idx_sum + 1
}
}
print_index_stats("browser", bidx, bmiss, n)
print_index_stats("os", oidx, omiss, n)
print_index_stats("device", didx, dmiss, n)
let domain_sums_match = browser_sum + os_sum + device_sum == full_sum
println(
"profile-checksum samples_checksum=\{full_sum} browser_checksum=\{browser_sum} os_checksum=\{os_sum} device_checksum=\{device_sum} index_checksum=\{idx_sum} domain_sums_match=\{domain_sums_match} index_matches_full=\{idx_sum == full_sum} reps_consistent=\{reps_consistent}",
)
}
///|
fn main {
let args = @env.args()
let smoke = args.contains("--smoke")
let profile = args.contains("--profile")
if profile {
// T-05 --profile takes precedence over --smoke (mutually exclusive
// measurement modes; the combination is not a defined mode).
profile_main()
return
}
let stride = if smoke { SMOKE_STRIDE } else { BENCH_STRIDE }
// The T-02 corpus is fully loaded; each round parses the declared stride
// subsample of it.
let inputs = stride_subsample(samples, stride)
let n = inputs.length()
let mode = if smoke { "smoke" } else { "full" }
let strata_seen = strata_inventory_check(samples, sample_strata)
// Warmup: fixed untimed passes over the same work.
let mut checksum = parse_pass(inputs)
for _ in 1.. SMOKE_NS_PER_PARSE_LIMIT {
println(
"smoke-verdict result=fail ns_per_parse=\{fmt_fixed2(ns)} limit=\{fmt_fixed2(SMOKE_NS_PER_PARSE_LIMIT)} (calibrated threshold, T-06); aborting non-zero after the full report above",
)
abort("smoke threshold exceeded: ns_per_parse above SMOKE_NS_PER_PARSE_LIMIT")
}
println(
"smoke-verdict result=pass ns_per_parse=\{fmt_fixed2(ns)} limit=\{fmt_fixed2(SMOKE_NS_PER_PARSE_LIMIT)} (calibrated threshold, T-06)",
)
}
}