XPerf
LanguagesZig

zperf evidence policy

Gate

A zperf rule may be documented / treated as a speed error (cperf/jsperf-style escalate) only if both exist under packages/zperf/evidence/:

  1. <RULE>.md — claim, harness, Zig version / optimize mode, limits
  2. <RULE>.jsonl — ≥1 before/after line with fields rule, case, role, zig, optimize, median_ms, ops, ratio, ts

Otherwise keep the rules.zig severity (warning / info / hint / off) and treat as review prompt, not a “must fix for speed” CI gate.

Having JSONL is necessary, not sufficient. Escalate only when wall-clock clearly agrees and the failure mode matches the rule. Modest ratios, env-dependent I/O, or optimizer-elided benches stay non-error.

CLI today may still fail the process on any finding; this policy is the keep / escalate contract until presets land.

Current map

As of 2026-10-22: measured with Zig 0.17.0 -Ofast, median of 9, harness examples/bench/evidence_fill.zig.

G3/r4 (2026-10-22): several rules demoted to default off after OK-idiom mass on mature Zig corpora (see corpus.md; gate definitions in AGENT.md). The evidence JSONL for these rules stays valid; do not escalate to error without re-validating G4 on the default-on set.

Rulerules.zig sevEvidenceMeasured ratioEscalate?
zp-alloc-hotoffzp-alloc-hot~1.4× GPA vs arena retainno (modest; prefer zp-create-destroy-hot / zp-fixed-size-alloc-hot for fixed sizes)
zp-append-without-reserveoffzp-append-without-reserve~2.1×no (info)
zp-page-allocator-smallwarningzp-page-allocator-small~341× page vs GPAcandidate error
zp-print-hotoffzp-print-hot~6e4× print vs quietno — env I/O (like jsperf's jp-console-hot)
zp-unbuffered-iooffzp-unbuffered-io~49× empty vs 4KiBcandidate error
zp-aos-single-fieldoffzp-aos-single-field~6.6× AoS vs SoAno (review prompt)
zp-bool-arrayoffzp-bool-array~30× bool[] vs bitsetno (info)
zp-static-string-mapinfozp-static-string-map~2.5×no (info)
zp-runtime-div-hotoffzp-runtime-div-hot~12× mod vs maskno (review prompt)
zp-queue-ordered-removewarningzp-queue-ordered-remove~466× orderedRemove vs ringcandidate error
zp-shift-on-readwarningzp-shift-on-read~17×candidate error
zp-per-packet-allocoffzp-per-packet-allocshared zp-alloc-hot ~1.4×no (same as zp-alloc-hot)
zp-invariant-float-divhintzp-invariant-float-div~2.0×stays hint
zp-map-put-without-ensureoffzp-map-put-without-ensure~2.8×no (info)
zp-arena-reset-free-allwarningzp-arena-reset-free-all~3.2× free_all vs retainborderline warning
zp-create-destroy-hotinfozp-create-destroy-hot~11×candidate error
zp-fixed-size-alloc-hotinfozp-fixed-size-alloc-hot~8.5×candidate error
zp-open-file-hothintzp-open-file-hot~2134× open onceno (hint; path may change)
zp-clock-hothintzp-clock-hot~42× sample onceno (hint; a fresh timestamp has nothing to hoist)
zp-json-hothintzp-json-hot~2683× parse onceno (hint; a changing payload cannot be hoisted)
zp-alloc-print-hothintzp-alloc-print-hot~50× GPA print once; arena ~12×no (hint; a changing value cannot be hoisted)

Not measured / N/A this pass

RuleStatusWhy
zp-debug-allocatorN/A (static-only)Build-mode allocator selection; not one-binary before/after
zp-large-struct-by-valueinconclusiveReleaseFast elided by-value vs ptr microbench (~50 ns total) — do not cite
zp-missing-freeN/A (correctness)Missing free/deinit — leak/UB, not speed
zp-broad-runtime-safetypending measureBroad @setRuntimeSafety(false) — only meaningful under ReleaseSafe
zp-packable-boolspending measurePackable bools — density claim; no wall JSONL yet
zp-usize-index-fieldpending measureusize index fields — density; no wall JSONL yet
zp-catch-unreachable-allocN/A (correctness)catch unreachable on alloc — UB on OOM
zp-oversized-enum-tagN/A (static size)Oversized enum tag — ABI/size; no wall JSONL
zp-optional-scalar-fieldpending measureOptional scalar padding — density; no wall JSONL yet
zp-catch-unreachable-ioN/A (correctness)catch unreachable on I/O

Regenerating

bash packages/zperf/scripts/regen-evidence.sh

Re-run after Zig minor upgrades; update matching .md medians if ratios move materially.

Candidate errors (policy, not CLI presets yet)

Strong agreement in these measurements: zp-page-allocator-small, zp-queue-ordered-remove, zp-shift-on-read, zp-create-destroy-hot, zp-fixed-size-alloc-hot (zp-unbuffered-io demoted off after G3 OK-idiom).

Keep as warning/info until --preset lands; do not invent error in CI without G4 + preset. Default-on after r4: zp-page-allocator-small, zp-broad-runtime-safety, zp-static-string-map, zp-queue-ordered-remove, zp-shift-on-read, zp-invariant-float-div, zp-arena-reset-free-all, zp-create-destroy-hot, zp-fixed-size-alloc-hot.