Benchmarks¶
The repo ships two parallel bench harnesses that compare the two codegen
paths — the direct-emit codegen (default) and the AST walker
(:emit<ast>, see API) — on a
fixed set of representative templates:
specs/bench/render-spec.raku— BDD-Behave spec, tagged:tag<benchmark>so it is skipped by the default test run and driven separately viabehave --benchmark specs/bench/.t/0790-bench.rakutest—prove6-style harness, skipped unlessHAML_RUN_BENCH=1is set in the environment.
Both files share the same template cases and the same render setup, so either entry point produces a comparable measurement.
Run¶
From the project root, driving the BDD-Behave spec:
1 | |
Driving the prove6 harness:
1 | |
Both harnesses honor HAML_BENCH_ITERS to override the iteration count
(default 5000 for the BDD spec, 100 for the prove6 test):
1 2 | |
Output¶
The prove6 harness prints one TAP diagnostic per case:
1 2 3 4 | |
The BDD-Behave benchmark mode renders comparable per-case tables driven
by the benchmark 'ast' { ... } / benchmark 'direct' { ... } blocks
inside the spec.
Each case is warmed once for both paths before the timed loop, so the per-template precompile/EVAL cost is excluded from the timings — what's being measured is steady-state render speed.
Cases¶
The cases are declared in specs/bench/render-spec.raku
(mirrored by t/0790-bench.rakutest). Each entry is a (name, src, locals)
record. Add a case by appending to the list — the harnesses pick it up
automatically.
Caveats¶
- The numbers are wall-clock and depend on machine load. Run a few times if the comparison is close.
- The harness times
HAML.render(:src, ...)end-to-end. The first render for each path warms internal caches; subsequent renders reuse the cached closure, so the times reflect the steady-state cost, not first-render cost. :emit<direct>covers the same template-level features as the AST renderer (trim modifiers,remove-whitespace, preserved tags with children, tab-offset propagation). The only path it does not yet drive is streaming (HAML.render-supply), which stays on the AST renderer regardless of:emit. See API: Feature parity with the AST renderer.