diff --git a/.claude/rules/api-compatibility.md b/.claude/rules/api-compatibility.md new file mode 100644 index 00000000..ef7692d0 --- /dev/null +++ b/.claude/rules/api-compatibility.md @@ -0,0 +1,18 @@ +--- +paths: + - "src/Heddle/**/*.cs" + - "src/Heddle.Generator/**/*.cs" +--- + +# API design and compatibility + +Details: [coding-standards.md § API](../../docs/spec/common/coding-standards.md#api-design-and-compatibility), [breaking-windows.md](../../docs/spec/common/breaking-windows.md). Anchored in the .NET Framework Design Guidelines. + +- Additive by default: new extensions, opt-in options, overloads. Existing templates and hosts compile and render byte-identically. +- Breaking changes land only in a ratified breaking window (D2), each with a migration note. Candidates go to the register in breaking-windows.md, not into code. +- Every new `TemplateOptions` property goes into the copy constructor (and `Equals`/`GetHashCode` when it keys identity) — missed before (`ProvideLanguageFeatures`); the completeness test enforces this. +- Public API additions carry XML docs + same-change updates to the affected published docs pages (`language-reference.md`, `custom-extensions.md`, `built-in-extensions.md`, `csharp-api.md`). +- Extend via the sanctioned seams (`[ExtensionName]` registry, options, function registry, output profiles, publish/read channel, resolver, encoder) — don't invent parallel mechanisms or new seams for single-implementation internals. +- The generator names no extension: no compare against a built-in name in any form, no `"Heddle.Extensions."` type literal, no `"Heddle"` assembly-name compare, no name-keyed table. Read the binder, the attributes, or the hook. `ExtensionAgnosticismTests` gates it over every file compiled into `Heddle.Generator.dll` — linked shared source included, via an embedded compile-input manifest — by Roslyn syntax walk rather than regex, so `string.Equals`, `case`, `is`, collection lookups and default parameter values are all caught, and by reading static string tables back by value. It is vocabulary-free, so a third-party name is caught too. Every declared row carries a `Why` ending in `permanent` or `retires in Stage N`. +- The generator never predicts a compile-time hook either: `PrecompiledRuntime.Init` constructs the extension in the consumer's assembly and runs its real `InitStart`/`CompleteInit`, so a bodied, hook-overriding, `[Prop]`-declaring or `[BranchRole]` custom extension precompiles in a default build. Where a hook's typing is unresolvable the body is emitted type-agnostically over `PrecompiledLateAccessor`, never refused. A call the seam cannot serve costs **that call site** (`PrecompiledRuntime.SiteFallback`, `[PrecompileUnsupported]`/`HED7033`), not the template — reach for a `Refusal` only where the whole file must go. +- Extension instances are shared across concurrent renders: no mutable per-render state on them; per-render state lives in the `Scope` lineage. diff --git a/.claude/rules/coding-style.md b/.claude/rules/coding-style.md new file mode 100644 index 00000000..23354584 --- /dev/null +++ b/.claude/rules/coding-style.md @@ -0,0 +1,18 @@ +--- +paths: + - "**/*.cs" +--- + +# Coding style + +Authority order: (1) surrounding code in the file, (2) [coding-standards.md](../../docs/spec/common/coding-standards.md), (3) `.editorconfig` (editor guidance only, not a gate). + +- Block-scoped namespaces (`namespace X { … }`) — not file-scoped, even in new files. +- Allman braces predominantly — match the file. Braceless single-statement guards for early returns are idiomatic; multi-line/nested bodies always braced. +- `var` when the type is apparent; explicit types otherwise and for built-ins. +- Naming: `_camelCase` private instance fields; `PascalCase` private static readonly; `I`-prefixed interfaces; extension classes `Extension` with `[ExtensionName("name")]`. +- Existing quirks (space before parameter list, space after cast) are deliberate — do not "fix" them. +- Comments follow C1–C8: default to none; write one only when the code cannot carry the meaning; never cite specs, plans, findings, or reviews in code comments (C4). XML doc comments on public API; regression tests carry a doc comment explaining the pinned scenario. +- 4-space indent, UTF-8, final newline, ~120-column wrap. +- Never mass-reformat or run whole-file IDE cleanups; diffs contain only the lines the change needs. The established style is the maintainer's deliberate choice — consistency beats modernization. +- `src/Heddle.Language/generated/` is generated (ANTLR) — never hand-edited; grammar change = `.g4` edit → regen → commit both. diff --git a/.claude/rules/errors-diagnostics.md b/.claude/rules/errors-diagnostics.md new file mode 100644 index 00000000..7d1040c5 --- /dev/null +++ b/.claude/rules/errors-diagnostics.md @@ -0,0 +1,17 @@ +--- +paths: + - "src/Heddle/**/*.cs" + - "src/Heddle.Generator/**/*.cs" + - "src/Heddle.Language*/**/*.cs" +--- + +# Errors and diagnostics + +Details: [coding-standards.md § errors](../../docs/spec/common/coding-standards.md#error-handling-and-diagnostics), [cross-cutting-decisions.md D1 + registry](../../docs/spec/common/cross-cutting-decisions.md). + +- Compile-path problems are collected, not thrown: positioned `HeddleCompileError`/`HeddleCompileWarning` on the compile result, so template authors see all problems at once. The public API never surfaces raw exceptions for template mistakes. +- Host-programming errors throw at public API entry points (`ArgumentNullException` etc.). +- Every new diagnostic claims a stable `HED####` ID from the registry (feature-area blocks, D1) **in the same change**; IDs are never reused or renumbered. +- An ID whose condition becomes unreachable is **retired in place**, not deleted: the `HeddleDiagnosticIds` constant, the `HeddleDiagnosticCatalog` row, the registry row and a mention in the page the registry names as owner all stay, and the registry row says what stopped firing, why, and what replaced it (often nothing). `DiagnosticIdTests` gates all four; deleting any would free the number for a later, different fault. +- Messages name the construct, point at the remedy, and carry the template position. +- Security-sensitive failures never degrade to execution: a sandbox violation is a compile error, full stop. diff --git a/.claude/rules/performance.md b/.claude/rules/performance.md new file mode 100644 index 00000000..05c61f60 --- /dev/null +++ b/.claude/rules/performance.md @@ -0,0 +1,16 @@ +--- +paths: + - "src/Heddle/**/*.cs" + - "benchmarks/dotnet/**" +--- + +# Performance (render path is hot) + +Details: [coding-standards.md § performance](../../docs/spec/common/coding-standards.md#performance-rules-the-render-path-is-hot). + +- No new per-render allocations. `Scope` stays a `readonly struct` passed by `in`; optional per-render state is lazily created. +- Reflection at compile time only; render time executes pre-compiled delegates and direct calls. +- `[MethodImpl(AggressiveInlining)]` only on tiny, provably-hot transforms — with a benchmark justifying it. +- Perf claims are proven by BenchmarkDotNet (`benchmarks/dotnet`), never asserted. Hot-path changes run affected benchmarks before/after on the same machine: allocated bytes must not increase; mean must stay within reported error. Intentional trade-offs need maintainer ratification. +- Compile-time cost is "compile once, render many" — moderate compile-path allocation is fine, but startup/precompilation paths get measured too. +- No JIT-rescue assumptions for escaping allocations (D7). diff --git a/.claude/rules/spec-workflow.md b/.claude/rules/spec-workflow.md new file mode 100644 index 00000000..5070cf60 --- /dev/null +++ b/.claude/rules/spec-workflow.md @@ -0,0 +1,15 @@ +--- +paths: + - "docs/spec/**" +--- + +# Spec and decision workflow + +Details: [spec-conventions.md](../../docs/spec/common/spec-conventions.md), [cross-cutting-decisions.md](../../docs/spec/common/cross-cutting-decisions.md) (which also carries the condensed release and program records). + +- Specs live under `docs/spec/`, indexed from `docs/spec/README.md` (update the index in the same change); they are contributor material, never published (D9). +- Plan = what/why (ratified input); spec = exactly how. A finished spec has **no open questions** — every point is a closed decision with evidence, or a most-reversible default plus a named revisit trigger. +- Implementation follows the owning plan's declared item order (D5): assume 1..N−1 merged; never depend on later items. +- Changing an earlier recorded decision goes through the amendment mechanism (evidence → maintainer ratification → implemented by the amending effort); earlier spec text is never silently retrofitted. The accumulated E1–E28 ledger is closed — new amendments are recorded as dated notes in the owning spec (see cross-cutting-decisions.md § Cross-spec amendments ledger). +- Balanced-mode principle precedence on conflicts: correctness/back-compat → sandbox security → simplicity → measured hot-path performance → abstraction/extensibility. DRY consolidates knowledge (rule of three); YAGNI cuts presumptive features, never tests/benchmarks/docs. +- Writing style: sentence-case headings, en/em dashes, relative links only, cite `path` + member name over bare line numbers. diff --git a/.claude/rules/testing.md b/.claude/rules/testing.md new file mode 100644 index 00000000..cef4b25c --- /dev/null +++ b/.claude/rules/testing.md @@ -0,0 +1,22 @@ +--- +paths: + - "src/*Tests*/**" + - "src/TestCorpus/**" + - "samples/**" +--- + +# Testing + +Details: [testing-standards.md](../../docs/spec/common/testing-standards.md) — normative; this is the short form. + +- Loop: write the spec's tests failing first → implement to green → run the gate → fix forward. Goldens/baselines/spec tables change only with maintainer review, never to silence a red test. +- Gate (one combined run): `dotnet build -c Release` → `dotnet test --project src/Heddle.Tests/Heddle.Tests.csproj` (all TFMs, serially; both Debug and Release when `#if DEBUG` arms are touched) → no diff under `src/Heddle.Language/generated/` (unless the spec licenses a grammar change) → benchmarks when a hot path is touched → `npm run docs:build` when docs pages changed. +- xUnit v3 on MTP: `dotnet test` needs `--project`/`--solution` (directory form is rejected); filters are MTP syntax after `--` (`--filter-method` etc.); a filter matching nothing exits 8; CI legs run through `.github/scripts/dotnet-test-guarded.sh `, which passes `--fail-skips on`. +- **Run a suite once and keep the whole output.** These suites take minutes; re-running one to see a detail you piped away is the single most expensive habit available. Always `2>&1 | tee` (or redirect) the full run to a file, then read that file — grep it for failures, open the failing case, count tests, whatever is needed. Never pipe a run through `tail`/`grep` as the only sink, and never re-run a suite to answer a question the first run already contained. Redirect per suite so runs stay separable, and prefer one combined script that captures every suite in a single pass over four separate invocations. +- **No test-count floors.** `--minimum-expected-tests` was tried on nine CI legs and withdrawn: it is satisfied by editing a digit, it names nothing when it reddens, it drifted (one commit raised `dotnet.yml` and left `lsp.yml`, and that leg then tolerated a six-test regression for four commits), and it fails a leg for the wrong reason whenever a test is legitimately quarantined. What a suite CONTAINS is gated inside the suite: `src//test-classes.txt`, one line per fact-declaring class, set-equality asserted by that suite's `TestClassInventoryTests` — a red gate names the class. Deliberately the same shape as corpus membership below. +- Fixtures: `.heddle` + sibling golden under `src/Heddle.Tests/TestTemplate`; every new golden/fixture directory is LF-pinned in `.gitattributes` **in the same change**. +- Negative/security tests assert positioned `HED*` diagnostics (ID + position) and prove the construct never executes. +- Descriptive PascalCase sentence test names; assert with context (`Assert.True(result.Success, result.ToString())`); tests are exempt from DRY. +- Concurrency: any state shareable across renders ships a parallel-render isolation test. +- Precompiled tier: fallback to dynamic is byte-identical, so an unpinned test proves nothing about the tier it claims to test. End-to-end tests pin the tier (`PrecompiledMismatchPolicy.Strict` + fallback sentinel); expected fallbacks are declared only via `FallbackGuard.Expect` / `DifferentialHarness.ExpectDegrade`; quarantine guarded fixtures with an owning-item `Explicit = true` (reported *not run*, so it survives `--fail-skips`), never weaken them. +- Test-input single-sourcing: a template shape verified by more than one tier exists once, in the shared corpus, with declared (total) intent — duplicate copies drift silently and break the differential premise. Membership is gated by set equality — never a count or floor (a floor once hid 15 templates silently dropping out). diff --git a/.gitattributes b/.gitattributes index 0368cf01..6eb0d0a7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,15 +13,42 @@ # output — failing on Windows while Linux (LF everywhere) passes. Pin every such root to LF so the # byte comparison holds identically on both platforms regardless of the developer's autocrlf setting. # All files under these roots are text (verified: no binaries). New golden/fixture roots MUST be -# added here in the same change that introduces them — see docs/spec/common/testing-standards.md. +# added here in the same change that introduces them. +# +# eol=lf pins line endings and says nothing about byte-order marks; the two are independent, and a +# BOM drift can pass every eol=lf check there is. Templates carrying a deliberate UTF-8 BOM declare +# it in src/TestCorpus/CorpusIntent.cs, gated by CorpusIntentGateTests. samples/**/golden/** text eol=lf src/Heddle.Tests/TestTemplate/** text eol=lf +src/Heddle.Tests/TestOutput/** text eol=lf src/Heddle.Tests/Streaming/** text eol=lf src/Heddle.Generator.Tests/Snapshots/** text eol=lf src/Heddle.Generator.IntegrationTests/Fixtures/** text eol=lf src/Heddle.LanguageServices.Tests/Corpus/** text eol=lf src/Heddle.Demo.Wasm/contract-fixtures/** text eol=lf +# The per-suite test-class inventories are read line by line and compared as a set on both platforms. +# Reading normalises CRLF, but pinning them keeps the diff a reviewer sees identical everywhere. +src/*/test-classes.txt text eol=lf + +# Golden oracle corpus: the *.golden.html files intentionally end WITHOUT a trailing newline and must +# round-trip byte-exact on every platform, so they are pinned -text (no smudging at all) rather than +# eol=lf. The JSON sidecars are ordinary LF text. +benchmarks/dotnet/GoldenCorpus/*.golden.html -text +benchmarks/dotnet/GoldenCorpus/*.verify.json text eol=lf +benchmarks/dotnet/GoldenCorpus/manifest.json text eol=lf +# Exported model fixtures are hash-recorded in the manifest like the goldens; LF text. +benchmarks/dotnet/GoldenCorpus/fixtures/** text eol=lf + +# Rust benchmark harness: composed-page fragment data must round-trip byte-exact (-text); template +# files are ordinary LF text (the harness erases their line endings, but LF keeps diffs clean). +benchmarks/rust/templates/** text eol=lf + +# Python benchmark harness: template files are committed LF on every platform — Mako passes a literal +# \r\n in a template file through into rendered output, so LF-pinning keeps checked-in bytes equal to +# authored bytes. +benchmarks/python/templates/** text eol=lf + # Custom for Visual Studio *.cs diff=csharp *.sln merge=union diff --git a/.github/scripts/dotnet-test-guarded.sh b/.github/scripts/dotnet-test-guarded.sh new file mode 100755 index 00000000..f6b367fc --- /dev/null +++ b/.github/scripts/dotnet-test-guarded.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Runs one test project under Microsoft.Testing.Platform, with the two guards that are worth having. +# +# Usage: dotnet-test-guarded.sh [extra dotnet test args...] +# +# `--fail-skips on` turns a skipped test into a failed one. A skip is a test that stopped testing, and +# CI is the wrong place to find out quietly; the repository's protocol for a known-failing test is +# `[Fact(Explicit = true)]`, which is reported as NOT RUN rather than skipped and so survives this. +# +# Exit 8 -- a filter matched nothing, or discovery failed -- stays called out by name, because a stale +# filter that runs nothing used to pass. It is the platform's own signal, not a number anyone maintains. +# +# What this script no longer does is carry a per-suite `--minimum-expected-tests` floor. Nine of them +# were maintained by hand across two workflows and they failed at their own job: one commit added six +# tests, raised the floor in one workflow and left the other, and that leg then tolerated a six-test +# regression in silence for four commits. A floor is satisfied by editing a digit, it names nothing +# when it reddens, and it fails a leg for the wrong reason whenever a test is legitimately quarantined. +# Suite membership is gated instead by the checked-in test-class inventories (src//test-classes.txt, +# asserted by set equality inside each suite), which name the class that appeared or vanished. + +set -uo pipefail + +if [ "$#" -lt 1 ]; then + echo "usage: $0 [extra args...]" >&2 + exit 64 +fi + +project=$1 +shift 1 + +dotnet test --project "$project" "$@" -- --fail-skips on +status=$? + +if [ "$status" -eq 8 ]; then + echo "::error::Zero tests ran in ${project} -- a filter matched nothing, or discovery failed." +fi + +exit "$status" diff --git a/.github/workflows/dco.yml b/.github/workflows/dco.yml index 37b4df24..6f7b3b12 100644 --- a/.github/workflows/dco.yml +++ b/.github/workflows/dco.yml @@ -1,16 +1,20 @@ -# Verifies that every commit in a pull request carries a matching -# "Signed-off-by" trailer (Developer Certificate of Origin). This produces a -# required status check ("DCO / dco") that branch protection can enforce. +# Verifies that every commit in a pull request carries a matching "Signed-off-by" +# trailer (Developer Certificate of Origin). # -# Alternative: install the DCO GitHub App (https://github.com/apps/dco) which -# provides the same check with zero maintenance. If you do, you can delete this -# workflow and require the app's "DCO" check instead. +# Two roles: +# - a required status check ("DCO / dco") that branch protection enforces on PRs +# - via workflow_call, the gate the PR-sourced deploy jobs depend on, so a beta package +# never ships from unsigned commits +# +# Releases from main are deliberately NOT gated: they are the maintainer's own, and a tag +# push carries no pull request to check. name: DCO on: pull_request: branches: [ "main" ] + workflow_call: permissions: contents: read diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index b60e5055..03a1f564 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -18,6 +18,12 @@ on: permissions: contents: read +# The build matrix includes windows-latest, where the default shell is pwsh. The test steps +# below are bash, and a bash-only line there fails the step rather than running the tests. +defaults: + run: + shell: bash + jobs: build: strategy: @@ -30,33 +36,58 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v6 with: - dotnet-version: | - 6.0.x - 8.0.x + dotnet-version: 8.0.x global-json-file: global.json - name: Restore dependencies run: dotnet restore - name: Build run: dotnet build --no-restore -c Release - - name: Test - run: dotnet test -c Debug --no-restore + # Every leg goes through the same wrapper, which turns a skipped test into a failed one and calls + # out the platform's zero-tests-discovered exit. Each project is named explicitly: `dotnet test` + # under Microsoft.Testing.Platform takes --project or --solution, and a whole-solution run would + # report one aggregate result rather than one per suite, which is what makes a single suite going + # quiet visible. What each suite CONTAINS is gated inside the suite, by its checked-in + # src//test-classes.txt inventory; no test count is maintained here. + - name: Test engine suite (Debug) + run: .github/scripts/dotnet-test-guarded.sh src/Heddle.Tests/Heddle.Tests.csproj -c Debug --no-restore + - name: Test generator suite (Debug) + run: .github/scripts/dotnet-test-guarded.sh src/Heddle.Generator.Tests/Heddle.Generator.Tests.csproj -c Debug --no-restore + - name: Test generator integration suite (Debug) + run: .github/scripts/dotnet-test-guarded.sh src/Heddle.Generator.IntegrationTests/Heddle.Generator.IntegrationTests.csproj -c Debug --no-restore + - name: Test language services suite (Debug) + run: .github/scripts/dotnet-test-guarded.sh src/Heddle.LanguageServices.Tests/Heddle.LanguageServices.Tests.csproj -c Debug --no-restore + - name: Test tool suite (Debug) + run: .github/scripts/dotnet-test-guarded.sh src/Heddle.Tool.Tests/Heddle.Tool.Tests.csproj -c Debug --no-restore + # The generator suites had no Release leg, and the engine's `#if DEBUG` arms are reachable from them: + # a Release-only failure in the integration suite survived because every run above it was Debug. + # Reuses the Release build already produced by the Build step, the same way the LSP workflow does. + - name: Test generator suite (Release) + run: .github/scripts/dotnet-test-guarded.sh src/Heddle.Generator.Tests/Heddle.Generator.Tests.csproj -c Release --no-build + - name: Test generator integration suite (Release) + run: .github/scripts/dotnet-test-guarded.sh src/Heddle.Generator.IntegrationTests/Heddle.Generator.IntegrationTests.csproj -c Release --no-build + + # Every commit in a contributed pull request must carry its Signed-off-by before anything + # built from it is published. Releases from main are not gated — they are the maintainer's + # own, and a tag push carries no pull request to check. + dco: + if: ${{ github.event_name == 'pull_request' }} + uses: ./.github/workflows/dco.yml + permissions: + contents: read # Internal (non-fork) pull requests publish a beta prerelease to nuget.org. - prerelease: + # Packing is separated from pushing: this job produces the packages and holds no + # publishing credentials, so a build failure cannot happen mid-publish. + prerelease-pack: needs: build if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }} runs-on: ubuntu-latest - permissions: - contents: read - id-token: write # OIDC token for nuget.org Trusted Publishing steps: - uses: actions/checkout@v7 - name: Setup .NET uses: actions/setup-dotnet@v6 with: - dotnet-version: | - 6.0.x - 8.0.x + dotnet-version: 8.0.x global-json-file: global.json - name: Restore dependencies run: dotnet restore @@ -64,8 +95,32 @@ jobs: # .NET tools (PackAsTool + multiple RuntimeIdentifiers), so `dotnet pack` must publish each RID. # A RID-less `dotnet build` never produces those per-RID outputs, so `--no-build` fails with # MSB3030 (missing per-RID assemblies) / NETSDK1085. Let pack build+publish, like the release job. + # The suffix carries NO leading dash: since Q8.11 the version is one in Directory.Build.props and + # the SDK joins prefix and suffix with a single '-', so "-beta.N" would compose 2.1.0--beta.N. It was harmless only + # while every project spelled `2.0.0$(VersionSuffix)` by hand. Pinned by VersionConsistencyTests. - name: Pack beta packages - run: dotnet pack -c Release -o ${{ runner.temp }}/pkg --version-suffix "-beta.${{ github.run_number }}" + run: dotnet pack -c Release -o ${{ runner.temp }}/pkg --version-suffix "beta.${{ github.run_number }}" + - uses: actions/upload-artifact@v7 + with: + name: nupkg-beta + path: ${{ runner.temp }}/pkg/*.nupkg + if-no-files-found: error + + prerelease-publish: + needs: [ prerelease-pack, dco ] + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # OIDC token for nuget.org Trusted Publishing + steps: + - name: Setup .NET + uses: actions/setup-dotnet@v6 + with: + dotnet-version: 8.0.x + - uses: actions/download-artifact@v7 + with: + name: nupkg-beta + path: ${{ runner.temp }}/pkg - name: NuGet login (OIDC -> short-lived API key) uses: NuGet/login@v1 id: nuget-login @@ -76,21 +131,18 @@ jobs: # Production release: triggered by pushing a `vX.Y.Z` tag. Publishes that exact version # (becomes "latest" on nuget.org automatically) and creates a GitHub Release. - release: + release-pack: needs: build if: ${{ startsWith(github.ref, 'refs/tags/v') }} runs-on: ubuntu-latest - permissions: - contents: write # create the GitHub Release - id-token: write # OIDC token for nuget.org Trusted Publishing + outputs: + version: ${{ steps.ver.outputs.version }} steps: - uses: actions/checkout@v7 - name: Setup .NET uses: actions/setup-dotnet@v6 with: - dotnet-version: | - 6.0.x - 8.0.x + dotnet-version: 8.0.x global-json-file: global.json - name: Resolve version from tag id: ver @@ -99,6 +151,27 @@ jobs: run: dotnet restore - name: Pack release packages run: dotnet pack -c Release -p:Version=${{ steps.ver.outputs.version }} -o ${{ runner.temp }}/pkg + - uses: actions/upload-artifact@v7 + with: + name: nupkg-release + path: ${{ runner.temp }}/pkg/*.nupkg + if-no-files-found: error + + release-publish: + needs: release-pack + runs-on: ubuntu-latest + permissions: + contents: write # create the GitHub Release + id-token: write # OIDC token for nuget.org Trusted Publishing + steps: + - name: Setup .NET + uses: actions/setup-dotnet@v6 + with: + dotnet-version: 8.0.x + - uses: actions/download-artifact@v7 + with: + name: nupkg-release + path: ${{ runner.temp }}/pkg - name: NuGet login (OIDC -> short-lived API key) uses: NuGet/login@v1 id: nuget-login diff --git a/.github/workflows/lsp.yml b/.github/workflows/lsp.yml index bdd28ea6..d3d3cdb2 100644 --- a/.github/workflows/lsp.yml +++ b/.github/workflows/lsp.yml @@ -12,6 +12,11 @@ on: permissions: contents: read +# The test job runs on windows-latest, where the default shell is pwsh; the steps below are bash. +defaults: + run: + shell: bash + jobs: test: runs-on: windows-latest @@ -19,19 +24,19 @@ jobs: - uses: actions/checkout@v7 - uses: actions/setup-dotnet@v6 with: - # The multi-targeted test suite runs net6.0/net8.0/net10.0/net48; the runner image - # no longer ships the EOL .NET 6 (and may drop 8) runtime, so install them explicitly - # alongside the global.json SDK — otherwise the net6.0 test host aborts (NETCore.App 6 missing). - dotnet-version: | - 6.0.x - 8.0.x + # The multi-targeted test suite runs net8.0/net10.0/net48; the runner image may drop the + # .NET 8 runtime, so install it explicitly alongside the global.json SDK — otherwise the + # net8.0 test host aborts (NETCore.App 8 missing). + dotnet-version: 8.0.x global-json-file: global.json - name: Build (Release) run: dotnet build -c Release Heddle.sln + # Same wrapper the dotnet workflow uses; these two legs once had no guard at all. + # This runner is Windows, so Heddle.Tests also builds its net48 leg and runs every TFM. - name: Test engine suite - run: dotnet test src/Heddle.Tests/Heddle.Tests.csproj -c Release --no-build + run: .github/scripts/dotnet-test-guarded.sh src/Heddle.Tests/Heddle.Tests.csproj -c Release --no-build - name: Test language services - run: dotnet test src/Heddle.LanguageServices.Tests/Heddle.LanguageServices.Tests.csproj -c Release --no-build + run: .github/scripts/dotnet-test-guarded.sh src/Heddle.LanguageServices.Tests/Heddle.LanguageServices.Tests.csproj -c Release --no-build - uses: actions/setup-node@v7 with: node-version: 24 @@ -56,7 +61,7 @@ jobs: - name: Smoke — install and run --version run: | set -euo pipefail - dotnet tool install --global Heddle.LanguageServer --add-source ./nupkg --version 2.0.0 || true + dotnet tool install --global Heddle.LanguageServer --add-source ./nupkg --version 2.1.0 || true export PATH="$PATH:$HOME/.dotnet/tools" heddle-lsp --version - uses: actions/upload-artifact@v7 diff --git a/.github/workflows/npm.yml b/.github/workflows/npm.yml index b0b0b917..eaf7e619 100644 --- a/.github/workflows/npm.yml +++ b/.github/workflows/npm.yml @@ -6,6 +6,9 @@ # # Production is TAG-DRIVEN; merging to main does not publish. Fork PRs are skipped # (OIDC tokens aren't issued for forks). +# +# Building is a separate job from publishing: the build holds no publishing credentials, and +# each publish starts from an artifact that is already known to have built cleanly. name: Heddle Ace (npm) @@ -19,41 +22,85 @@ permissions: contents: read jobs: - publish: + # Every commit in a contributed pull request must carry its Signed-off-by before a package + # built from it is staged. Tag releases are not gated — see dco.yml. + dco: + if: ${{ github.event_name == 'pull_request' }} + uses: ./.github/workflows/dco.yml + permissions: + contents: read + + build: # Run for tag pushes and same-repo PRs; skip (not fail) for fork PRs. if: ${{ startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }} runs-on: ubuntu-latest - permissions: - contents: read - id-token: write # OIDC token for npm Trusted Publishing steps: - uses: actions/checkout@v7 - name: Setup Node uses: actions/setup-node@v7 with: node-version: 24 - registry-url: https://registry.npmjs.org - scope: '@multiarc' - # Note: we deliberately do NOT upgrade npm here. The node-bundled npm ships its - # dependencies (including `sigstore`, used by the provenance path) intact; a global - # `npm install -g npm@latest` self-upgrade prunes those bundled deps and breaks - # provenance publishing with "Cannot find module 'sigstore'". - name: Build custom Ace bundle working-directory: src/Heddle.Language run: bash build_ace.sh - name: Stage package manifest with built bundle working-directory: src/Heddle.Language run: cp package.json ace_build/ace/build/package.json - - name: Stage pre-release package (PR) - if: ${{ github.event_name == 'pull_request' }} - working-directory: src/Heddle.Language/ace_build/ace/build + - uses: actions/upload-artifact@v7 + with: + name: ace-bundle + path: src/Heddle.Language/ace_build/ace/build + if-no-files-found: error + + stage-prerelease: + needs: [ build, dco ] + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # OIDC token for npm Trusted Publishing + steps: + # Note: we deliberately do NOT upgrade npm here. The node-bundled npm ships its + # dependencies (including `sigstore`, used by the provenance path) intact; a global + # `npm install -g npm@latest` self-upgrade prunes those bundled deps and breaks + # provenance publishing with "Cannot find module 'sigstore'". + - name: Setup Node + uses: actions/setup-node@v7 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + scope: '@multiarc' + - uses: actions/download-artifact@v7 + with: + name: ace-bundle + path: ace-bundle + - name: Stage pre-release package + working-directory: ace-bundle run: | BASE_VERSION="$(node -p "require('./package.json').version")" npm version --no-git-tag-version "${BASE_VERSION}-beta.${{ github.run_number }}" npm stage publish --tag beta - - name: Publish release package (tag) - if: ${{ startsWith(github.ref, 'refs/tags/v') }} - working-directory: src/Heddle.Language/ace_build/ace/build + + publish-release: + needs: build + if: ${{ startsWith(github.ref, 'refs/tags/v') }} + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # OIDC token for npm Trusted Publishing + steps: + - name: Setup Node + uses: actions/setup-node@v7 + with: + node-version: 24 + registry-url: https://registry.npmjs.org + scope: '@multiarc' + - uses: actions/download-artifact@v7 + with: + name: ace-bundle + path: ace-bundle + - name: Publish release package + working-directory: ace-bundle run: | npm version --no-git-tag-version --allow-same-version "${GITHUB_REF_NAME#v}" npm publish diff --git a/.gitignore b/.gitignore index 34604d4e..9df633bc 100644 --- a/.gitignore +++ b/.gitignore @@ -108,7 +108,6 @@ project.lock.json /packages /.idea/.idea.Templating /src/Heddle.Language/js/ace/build -/src/Heddle.Performance/BenchmarkDotNet.Artifacts /src/Heddle.Language/ace_build /build @@ -130,9 +129,9 @@ project.lock.json /editors/vscode/server # Ace editor bundle staged into the site by the docs workflow (generated) /docs/public/ace/ -# Phase 9 demo WASM bundle staged into the site by the docs workflow (generated, never committed) +# Demo WASM bundle staged into the site by the docs workflow (generated, never committed) /docs/public/demo/ -# Phase 9 sample gallery capture outputs (written by `dotnet run -- --capture out`; goldens are committed) +# Sample gallery capture outputs (written by `dotnet run -- --capture out`; goldens are committed) samples/**/out/ /.idea /src/Heddle.Language/gen @@ -140,9 +139,34 @@ samples/**/out/ # Verify.SourceGenerators snapshot working files *.received.* -# Phase 9 generator EmitCompilerGeneratedFiles output (build artifact) +# Generator EmitCompilerGeneratedFiles output (build artifact) samples/**/generated/ # Playwright demo smoke artifacts docs/test-results/ docs/playwright-report/ /docs/logs + +# Python benchmark harness: venv and raw measurement outputs are never committed; published copies go +# to docs/benchmarks// +benchmarks/python/.venv/ +benchmarks/python/results/ +__pycache__/ +# Go harness in-place outputs (benchmarks/go/run-benchmarks.{sh,ps1} write here before the +# master runner's copy-results step lifts them into the run directory) +benchmarks/go/results/ +# Master-runner outputs (benchmarks/run-all.ps1, benchmarks/run-all.sh): per-run logs + copied artifacts +benchmarks/out/ +/benchmarks/go/bench.exe +# Prebuilt Go bench binary on Linux (benchmarks/go/run-benchmarks.sh) +/benchmarks/go/bench +# The Rust harness declares [[bin]] gate/summarize/alloc_report at src/bin/*.rs. The generic [Bb]in +# patterns near the top of this file would swallow those sources, so re-include them explicitly. +!benchmarks/rust/src/bin/ +!benchmarks/rust/src/bin/*.rs + +# Agent worktrees and local session state — but the path-scoped rules are shared and tracked +.claude/* +!.claude/rules/ + +# BenchmarkDotNet default output directory (generated; raw captures are kept locally, never committed) +BenchmarkDotNet.Artifacts/ diff --git a/CHANGELOG.md b/CHANGELOG.md index af8a8c48..7ad34c24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,220 @@ All notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.1.0] + +Additive at the language and rendering level — **no rendered byte changes on either tier** — with one +declared **binary** break in the precompiled-manifest contract, the removal of assembly auto-loading, +and three build-time behaviours that begin to occur because they were never wired. **2.1 is a ratified +breaking window**, scoped to binary changes and minor API changes or additions; the running window +record is in +[breaking-windows.md](docs/spec/common/breaking-windows.md#current-window--21-open-as-implemented-pending-release) +and the per-item judgements that predate the window's ratification remain in +[breaking-windows.md](docs/spec/common/breaking-windows.md#explicit-not-window-gated-rulings). + +### Changed (breaking) + +- **Precompiled assemblies built by a 2.0.x generator are no longer accepted.** + `PrecompiledSchema.MinSupportedSchemaVersion` rises `1` → `3`, and the manifest schema the generator + emits goes `2` → `3`. 2.0.0 shipped schema 2; this release moves the prop-layout fingerprint onto + `PrecompiledExtensionBinding` as an optional third constructor parameter, which **removes** the + two-argument `.ctor(string, string)` that every schema 1–2 manifest calls. Those manifests therefore + cannot run against the 2.1 engine at all, and a floor of `1` would *accept* them and then crash with + a `MissingMethodException` out of `PrecompiledTemplates.Register` at host startup. The gate rejects + them cleanly instead. + Schema 3 is a **single** increment carrying everything added since 2.0: the `PrecompiledRuntime.DynamicMember` + routing, the extension prop-layout fingerprint, the per-carrier `BindDefinition` overload, and the two + new per-template fields below. There is no schema 4 or 5 — intermediate numbers existed only inside + unreleased development and are not migration steps. + **What to do:** rebuild with the 2.1 `Heddle.Generator`. `Heddle.Generator` and `Heddle` are + version-locked — pair the matching versions. + **If you do not:** registration raises one `PrecompiledFallbackReason.SchemaVersionUnsupported` + callback (`HED7102`) per assembly and every template renders through the byte-identical dynamic + path; under `TemplateOptions.PrecompiledMismatchPolicy.Strict` it throws instead, which is that + option's purpose. No compatibility shim: restoring the two-argument constructor would keep the + unrunnable manifests accepted, which is the defect. + +- **`PrecompiledFallbackEvent.Key` is removed**, replaced by `TemplateKey` and `AssemblyName` with + exactly one populated. The single `Key` carried two different kinds of string — a template key for + the per-request reasons, an assembly name for the registration-time ones — with no discriminator, so + a host had to re-derive from `Reason` which of the two it held. Removal rather than narrowing is + deliberate: narrowing would leave a 2.0 host silently reading `null` off the channel whose entire + purpose is that failures are not silent, while removal is a compile error at the one line that has + to change. Events are constructed through `ForTemplate`/`ForAssembly`, which each refuse the other's + reasons, and the reason → carrier mapping is enforced by an exhaustive classifier that throws on an + unclassified reason — so a reason added later cannot be raised until it is mapped. + +- **The engine no longer loads or scans assemblies on its own.** It used to `Assembly.Load` the entry + assembly's entire transitive reference closure — plus every `DependencyContext` default assembly + name, loader failures swallowed — from a static constructor, and then scan all of it for + `[assembly: ExportExtensions]`. Because that scanned set decided extension **name ownership**, an + assembly you never chose to load could take a name, or collide with an unrelated claimant and throw + `TemplateOverrideException` out of a type initializer. + The set is now what your host has already loaded into the default load context, plus what you + register — including assemblies that load later, since the engine re-checks rather than snapshotting. + `[ExportExtensions]` is read **per assembly, at registration**. + **What to do:** call `HeddleTemplate.Register(assembly)` for your application assembly and for every + extension library you use. Registration is **not transitive** — an extension library you merely + reference is not discovered. `HeddleTemplate.Configure(assembly)` is the same call under its older + name and keeps working; its one-shot latch is gone, so a second call now takes effect instead of + being silently dropped. + **If you do not:** a template calling an unregistered extension reports `Cannot find extension + ` (`HED0002`); a precompiled one degrades per request with an `ExtensionBindingMismatch` + naming it. A template that names a model type by string in an assembly your host has never touched + no longer resolves either — register that assembly too. + The `Microsoft.Extensions.DependencyModel` package reference is **removed** along with the walk that + was its only consumer, so the engine's dependency surface shrinks by one. + +- **`` per-item metadata now takes effect.** `Key`, `Name` and `Precompile` were all + inert from a real project — the targets file overwrote each with the empty string while appearing to + map it — so only projects that never used them were unaffected. If you set `Key`, the template's + registration key **and its generated entry-class name** now follow it, so a call to the old + path-derived class name must be renamed. `Name` moves nothing (see *Added*). If you set + `Precompile="false"`, that file now really stops precompiling (it remains available to `@<<` imports) + and renders through the dynamic path. + +### Added + +- **The expression-tier parity program: the generator now emits what it used to degrade.** Five classes + of native-expression construct that previously fell back to the dynamic tier now precompile, each by + reproducing the engine's own semantics rather than trusting verbatim C# to agree with them: shifts, + ternaries and coalesces over mixed numeric kinds (the engine's promotion is spelled as explicit + casts); mixed-type equality and string concatenation (through `Heddle.Precompiled.RuntimeOperators` + adapters that replay the engine's own decision chain, so parity holds by construction); constant + subtrees the two tiers type or value differently (emitted as the engine's folded value with a typed + literal spelling); same-enum and reference operand shapes (the shared operator table now carries type + identity, not just a category); and the structural shapes — `::`-rooted paths, indexers, targeted + paths, collided extension names, and `params` exports. Rendered bytes are unchanged — the two tiers + are parity-checked — this only moves templates off the slower dynamic path. +- **`HED1018` — constant division by zero is a compile error, on both tiers.** `@(1/0)` used to compile + and throw `DivideByZeroException` at render; rendering it can only ever throw, so both the engine and + the generator now refuse it at compile time under one id. Scoped exactly where C# draws `CS0020`'s + lines: integral and `decimal` only, the divisor folded rather than spelled (`1/(1-1)` counts), + floating point stays legal (`@(1.0/0)` renders `∞`), and a runtime divisor that happens to be zero + still throws at render. +- **The engine's refusals fire at build: `HED1003`–`HED1011` forwarded as build errors.** Where the + generator can *prove* the engine would refuse a construct on every input — method-call syntax, + declared-`dynamic` roots, logical operators over non-`bool`, ununifiable ternary/coalesce arms, + undefined binary/unary operator pairings, a known indexer target with no matching indexer, a + non-`bool` condition — it raises the engine's own id with the engine's own sentence at build time + instead of degrading silently and letting the consumer's runtime say so. Where it cannot prove the + refusal it still degrades silently: never an error on a guess. +- **`ModelType` item metadata** types a template from the project file: + `` feeds the same + pipeline the in-file `@model` directive feeds (resolution, `@using` imports, the `HED7007`/`HED7023` + gating), so a template can be typed without a directive in its text. When both channels are present + they must agree: different resolved types are **`HED7032`**, a build error, because the runtime reads + only the directive and the build refuses to type the same template differently on the two tiers. +- **A zero-allocation clean-span path in `HtmlEncodedRenderer`.** The span path used to materialize + every write twice (span → string → encoded string) before the sink saw a byte; a span with nothing to + encode now writes straight through to a span-accepting sink with zero allocation, and a dirty span + pays only from the first character that needs encoding. Byte identity holds on both encoder paths; a + fortunes-style encoded loop drops 29 % of its per-render bytes. +- **`Name` item metadata** as an **additional** name for a template — not a rename: + `` leaves the key + `t/report.heddle` and the class `Heddle.Generated.T_Report` exactly as they were, and makes + `BuildReport` resolve **as well as** `t/report.heddle`. Nothing that resolved before stops + resolving. It pairs naturally with `Precompile="false"`: an import-only partial under a friendly name. + Because a name is not a registration key, it takes no part in the duplicate (`HED7002`) or + case-only-twin (`HED7003`) checks and does not suppress the out-of-root warning (`HED7018`) — the + path-derived key is still there and still unasked-for. Setting `Key` *and* `Name` is two names for one + template, not a conflict. A value the normalizer refuses, or a name another template already answers + to, is `HED7004` against the name; the key is unaffected. +- **The name works at run time too, not only for `@<<` imports.** The manifest row carries it + (`PrecompiledTemplateInfo.RegisteredName`) and `PrecompiledTemplates.TryGet`/`TryResolve` — and so every + resolver arm — find the same template by either spelling. Where a spelling names one template's key and + another's registered name, **the key wins**, whichever assembly registered first: a name is an addition + and never displaces a spelling that already resolved. Lookup is ordinal, as key lookup is. +- **`HED7028`** (warning): an `@<<` import names a template by its registration key while that template + also carries a `Name`. Both spellings resolve — this recommends the name-first spelling for a named + template. It cannot fire for a project that sets no `Name`. +- **`HED7104`** (`PrecompiledFallbackReason.RegisteredNameUnavailable`, via `OnFallback`): a registered + `Name` could not become a lookup spelling — either because another *registered* template already answers + to it, as its key or as its own name, or because the shared key rule refuses the spelling outright (a + `..` segment, a trailing separator, whitespace). Never a throw — the template stays reachable by its key, and only the + addition is lost. This collision is only detectable at registration, since the build tier cannot read a + referenced assembly's manifest rows; within one build the same fault is `HED7004`. +- **`HeddleTemplate.Register(Assembly)`** — the explicit registration seam described under *Changed*. + Idempotent per assembly and repeatable, so a host chooses its own order of precedence. Throws + `ArgumentNullException` on null and `TemplateOverrideException` when two unrelated types claim one + extension name — at the registering call, rather than out of a type initializer. +- **`PrecompiledTemplates.ValidateAll(TemplateOptions)`** and `PrecompiledValidationReport` — one + post-configuration pass that runs the gauntlet over every registered entry and collects **all** + failures, so a binding that drifted between build and deployment fails your startup once instead of + degrading on every request. `PassedForValidatedOptions` is the green property; the report names the + options shape it validated, because four of the gauntlet's inputs are per-request. +- **`PrecompiledTemplateInfo.LinePathForm`** records which form a template's generated `#line` file names + are in — `RootRelative`, `TemplatePath`, or `Unspecified` for a fallback-marker row that has no + generated source. Machine-readable, for stack-trace symbolizers and editor tooling. +- **`Precompile="false"` items are validated and advised.** An opted-out item's `Key`/`Name` now raise the + same `HED7004` faults an included item's would, instead of failing silently and surfacing as `HED7011` + at whichever file imported it; and its own imports can draw the `HED7028` advisory. It still contributes + no entry point and no manifest entry. Its *template* errors remain unreported — the file is excluded from + this build by request, and they surface through any precompiled template that imports it. + +### Fixed + +- **A model the template cannot accept is refused as a Heddle fault.** The top-level render now checks + the model against the compiled model type once per render, in every build configuration, and throws + `TemplateProcessingException` on a mismatch; the wrong-typed value used to reach the compiled + accessor's cast and escape as a raw `InvalidCastException`, which is not the shape any other render + fault has. A `null` model stays legal, the recursive path is untouched, and the precompiled adapter — + which has no compile-time model type to check against — skips the check as it always has. + `TemplateOptions.ValidateModelType` is left in place but no longer read; removing it would be a break. +- **The build tier no longer precompiles a body the engine refuses to render.** A body containing a + branch terminal with no opener (a bare `@else` continuation) precompiled while the engine rejects it — + the shared branch scan's error arm was never wired to the emitter. The emitter now declines the body + and the template falls back to the dynamic tier. +- **Lexer errors reach the compile error list.** A character the lexer could not tokenize went to + ANTLR's console listener — a template engine writing to its host's console — and skip-recovery then + compiled the template as if the character were never typed (`4 +` compiled as `4` with zero + diagnostics). It is now a positioned syntax error on the compile result. +- **`&`/`|`/`^` over a lifted same-enum pair no longer throws at render.** The engine computed the + result type from the left operand alone, so `Color & Color?` built a conversion that threw + `InvalidOperationException` the moment the nullable side was null; the result now lifts to the + nullable enum and the null propagates — exactly C#'s answer. +- **Three build-tier type-binding defects.** A type nested in a generic (`Outer.Inner`) degraded + because the generator compared per-type arity against a cumulative spelling; a dotted spelling + reachable through two `@using` imports was decided by declaration order on both tiers instead of + being ambiguous (now the engine's ambiguity error / the generator's `HED7023`, matching `CS0104`); + and an assembly-qualified model spelling stating a `Version` **ahead** of the referenced assembly + bound at build and threw at runtime — it now degrades, while exact and behind versions bind. +- **`#line` directives in generated code name the template file, not its registration key.** The two + were always equal for a path-derived key; an explicit `Key` made the difference observable and would + have pointed every mapped span at a path that does not exist. A template **outside** + `HeddleTemplateRoot` now gets its own (absolute) path rather than a bare filename the compiler cannot + open, and which form a template's `#line` names are in is recorded on its manifest row (see + `LinePathForm` under *Added*) rather than as a comment in the generated file, so tooling can act on it. +- **`heddle-lsp --version` and the LSP `initialize` response reported `1.0.0`** for the whole 2.0 line. + The value is now read off the assembly rather than hand-maintained. +- **`HED7004`'s message** names the offending metadata and the reason, covering an unusable or + already-taken `Name` as well as a malformed `Key`. + +### Build and packaging + +- **`Heddle.Generator` ships one build per Roslyn generation, with a .NET Framework leg.** The single + netstandard2.0 build against Microsoft.CodeAnalysis 4.4.0 matched no compiler the engine pins; the + package now carries three builds of the same sources (Roslyn 4.1.0 / 4.11.0 / 5.3.0, mirroring the + engine's per-TFM pins) under `analyzers/dotnet/roslyn{4.1,4.11,5.3}/cs`, so a versioning-aware host + selects the newest folder its compiler can bind and the `buildTransitive` targets trim older hosts to + the 4.1 floor — the only variant a VS 2022-era `msbuild.exe` can use. Standing the net48 test legs up + surfaced and fixed four generator defects a VS-hosted consumer could hit: `u8` literals emitted to + consumers parsing below C# 11, entry points that boxed `TypedReference` on net48 (whose mscorlib + predates `IsByRefLikeAttribute`), template keys derived through `Path.GetFileName` (which validates + characters on .NET Framework and silently dropped templates), and a reference closure read from + `TRUSTED_PLATFORM_ASSEMBLIES` where it does not exist. +- The dedicated `net6.0` target is retired: the libraries now target `netstandard2.0;net8.0;net10.0`. + A .NET 6 host still runs Heddle — it binds the `netstandard2.0` build, as .NET 7 always has — losing + only the modern-BCL extras that build carries anyway (`Range.FromSystemRange`, the span/UTF-8 + formatting fast paths). +- The release line is stated once, as `` in `Directory.Build.props`, replacing nine + per-project `` elements; a version-consistency test holds the statements that cannot live + there (the npm manifests, the VS Code extension's pinned tool version, the LSP workflow's + `--version`, the prose release-line sentences, the CHANGELOG section) in step with it. +- `Heddle.Demo.Models` and `Heddle.Demo.Wasm` are strong-named, so the build is `CS8002`-clean. The one + remaining unsigned reference is third-party (Scriban) and is suppressed at the reference rather than + by a blanket `NoWarn`. + ## [2.0.0] - 2026-07-19 The **2.0** release is a single breaking window: almost everything below is additive and the dynamic @@ -122,14 +336,21 @@ engine's rendered bytes are unchanged, except for the items under **Changed (bre ### Compatibility -- Precompiled projects must be rebuilt with the 2.0 `Heddle.Generator` when upgrading the engine; 1.x - manifests are rejected by the engine-version gate and fall back (or throw under +- Precompiled projects must be rebuilt with the matching `Heddle.Generator` when upgrading the engine: + a manifest outside the engine's schema window, or built by an incompatible generator version, is + rejected at registration and the assembly's templates fall back (or throw under `PrecompiledMismatchPolicy.Strict`). `Heddle.Generator` and `Heddle` are version-locked — pair the matching versions. + **Corrected 2026-07-26.** This entry originally said *"1.x manifests are rejected by the + engine-version gate"*. No 1.x manifest has ever existed: pre-compilation shipped **in 2.0.0**, so + there is nothing from 1.x for the gate to reject and it has never fired for one. The rebuild + requirement is real and stated above; the 1.x rejection path was not. + ## [1.0.0] Initial public release. +[2.1.0]: https://github.com/multiarc/Heddle/compare/v2.0.0...v2.1.0 [2.0.0]: https://github.com/multiarc/Heddle/compare/v1.0.1...v2.0.0 [1.0.0]: https://github.com/multiarc/Heddle/releases/tag/v1.0.0 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..6c77cbb3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,25 @@ +# Heddle + +.NET templating engine: runtime compiler + render engine (`src/Heddle`), ANTLR grammar + generated parser (`src/Heddle.Language`), build-time source generator (`src/Heddle.Generator`), LSP (`src/Heddle.LanguageServer`), CLI (`src/Heddle.Tool`). + +Normative sources (read before non-trivial work): [docs/spec/README.md](docs/spec/README.md) → `docs/spec/common/` (coding-standards, testing-standards, cross-cutting-decisions D1–D11 + diagnostic registry, breaking-windows, shared-source-architecture, review-protocol, findings-register, spec-conventions). Rules below are the operational summary; the specs win on conflict. + +## Commands + +- Build: `dotnet build -c Release` (whole solution, all TFMs) +- Test: `dotnet test --project src/Heddle.Tests/Heddle.Tests.csproj` (xUnit v3 on MTP: the directory form is rejected; filters are MTP syntax after `--`; all TFMs, zero failures, suites run serially). Five suites carry tests — `Heddle.Tests`, `Heddle.Generator.Tests`, `Heddle.Generator.IntegrationTests`, `Heddle.LanguageServices.Tests`, `Heddle.Tool.Tests` — and each gates its own membership from `src//test-classes.txt`; the gate runs all five. +- Benchmarks: BenchmarkDotNet in `benchmarks/dotnet` (not in the solution; gate first: `dotnet run -c Release --project benchmarks/dotnet -- gate`); cross-stack harness contract in `benchmarks/docs/` +- Docs site: `cd docs && npm run docs:build` +- Merge gate (one combined run): build → all five test suites → no diff in `src/Heddle.Language/generated/` → benchmarks if a hot path was touched → docs build if docs changed +- Grammar: edit `.g4` → `src/Heddle.Language/generate_cs.cmd` (ANTLR 4.13.1) → commit both. Never hand-edit `src/Heddle.Language/generated/`. + +## Hard rules + +- Libraries target `netstandard2.0;net8.0;net10.0` (tests add `net48` on Windows) — new engine code must work on `netstandard2.0`. C# 14 is fine on all TFMs; no `#if NET10_0_OR_GREATER` by default (D7). +- Template mistakes become collected, positioned `HED####` diagnostics — never thrown exceptions. Host-programming errors throw. Sandbox violations are compile errors, never execution. A `HED####` that stops firing is retired in place — constant, catalog row, registry row and published mention all stay — never deleted. +- The render path is hot: no new per-render allocations. Perf claims are proven by benchmarks, not asserted. +- Additive by default; breaking changes only inside a ratified breaking window (D2). +- Never mass-reformat, never `dotnet format`; match the file you are in; keep diffs minimal. +- Goldens, perf baselines, and spec tables never change to silence a red test — fix forward. + +Detailed rules live in `.claude/rules/` — auto-loaded, most path-scoped to the files they govern. Don't restate them here. diff --git a/Directory.Build.props b/Directory.Build.props index e904c818..b2976ea8 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,10 +2,17 @@ + + 2.1.0 Aliaksandr Kukrash Copyright 2026 Aliaksandr Kukrash @@ -21,9 +28,9 @@ a symbol package for the RID-specific-tool wrapper packages, which have no assembly, so NuGet fails with NU5017. Setting IncludeSymbols per-project lets the tools/generator opt out. --> snupkg - + false diff --git a/Heddle.sln b/Heddle.sln index d419109d..268d2e60 100644 --- a/Heddle.sln +++ b/Heddle.sln @@ -11,8 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Heddle", "src\Heddle\Heddle EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Heddle.Language", "src\Heddle.Language\Heddle.Language.csproj", "{CE96D768-CEF0-414C-8170-1834BC4DB44E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Heddle.Performance", "src\Heddle.Performance\Heddle.Performance.csproj", "{E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Heddle.Tests", "src\Heddle.Tests\Heddle.Tests.csproj", "{EDC55E94-74DF-43AC-A0F9-46B2AD5F0515}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Heddle.LanguageServices", "src\Heddle.LanguageServices\Heddle.LanguageServices.csproj", "{5A84CB76-2835-48BE-BA12-EC96FB483B06}" @@ -37,6 +35,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Heddle.Demo.Models", "src\H EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Heddle.Demo.Wasm", "src\Heddle.Demo.Wasm\Heddle.Demo.Wasm.csproj", "{81A72F09-FFB8-4967-AB08-141C56A72DE1}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generator Roslyn Variants", "Generator Roslyn Variants", "{FF8FF1A0-2F37-3C8A-D386-BFD4180F0F43}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Heddle.Generator.Roslyn411", "src\Heddle.Generator\Heddle.Generator.Roslyn411.csproj", "{33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Heddle.Generator.Roslyn530", "src\Heddle.Generator\Heddle.Generator.Roslyn530.csproj", "{9D06263E-69F7-46E3-B1A0-622BEA5A94B5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -71,18 +75,6 @@ Global {CE96D768-CEF0-414C-8170-1834BC4DB44E}.Release|x64.Build.0 = Release|Any CPU {CE96D768-CEF0-414C-8170-1834BC4DB44E}.Release|x86.ActiveCfg = Release|Any CPU {CE96D768-CEF0-414C-8170-1834BC4DB44E}.Release|x86.Build.0 = Release|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Debug|x64.ActiveCfg = Debug|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Debug|x64.Build.0 = Debug|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Debug|x86.ActiveCfg = Debug|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Debug|x86.Build.0 = Debug|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Release|Any CPU.Build.0 = Release|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Release|x64.ActiveCfg = Release|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Release|x64.Build.0 = Release|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Release|x86.ActiveCfg = Release|Any CPU - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8}.Release|x86.Build.0 = Release|Any CPU {EDC55E94-74DF-43AC-A0F9-46B2AD5F0515}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EDC55E94-74DF-43AC-A0F9-46B2AD5F0515}.Debug|Any CPU.Build.0 = Debug|Any CPU {EDC55E94-74DF-43AC-A0F9-46B2AD5F0515}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -227,6 +219,30 @@ Global {81A72F09-FFB8-4967-AB08-141C56A72DE1}.Release|x64.Build.0 = Release|Any CPU {81A72F09-FFB8-4967-AB08-141C56A72DE1}.Release|x86.ActiveCfg = Release|Any CPU {81A72F09-FFB8-4967-AB08-141C56A72DE1}.Release|x86.Build.0 = Release|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Debug|Any CPU.Build.0 = Debug|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Debug|x64.ActiveCfg = Debug|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Debug|x64.Build.0 = Debug|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Debug|x86.ActiveCfg = Debug|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Debug|x86.Build.0 = Debug|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Release|Any CPU.ActiveCfg = Release|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Release|Any CPU.Build.0 = Release|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Release|x64.ActiveCfg = Release|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Release|x64.Build.0 = Release|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Release|x86.ActiveCfg = Release|Any CPU + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08}.Release|x86.Build.0 = Release|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Debug|x64.ActiveCfg = Debug|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Debug|x64.Build.0 = Debug|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Debug|x86.Build.0 = Debug|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Release|Any CPU.Build.0 = Release|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Release|x64.ActiveCfg = Release|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Release|x64.Build.0 = Release|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Release|x86.ActiveCfg = Release|Any CPU + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -234,7 +250,6 @@ Global GlobalSection(NestedProjects) = preSolution {08216E41-F266-441F-ADB2-D8D7FB088B98} = {7A42C497-6F07-4B5E-9B4A-807D444A5277} {CE96D768-CEF0-414C-8170-1834BC4DB44E} = {7A42C497-6F07-4B5E-9B4A-807D444A5277} - {E7E2561E-7D5F-48A1-B5D0-DA4C95FDD7B8} = {7A42C497-6F07-4B5E-9B4A-807D444A5277} {EDC55E94-74DF-43AC-A0F9-46B2AD5F0515} = {7A42C497-6F07-4B5E-9B4A-807D444A5277} {5A84CB76-2835-48BE-BA12-EC96FB483B06} = {7A42C497-6F07-4B5E-9B4A-807D444A5277} {CE656057-EE58-4ED9-9533-C30B4422F364} = {7A42C497-6F07-4B5E-9B4A-807D444A5277} @@ -247,6 +262,9 @@ Global {D4D2E547-5D71-4C5A-93F8-F02262322B2C} = {7A42C497-6F07-4B5E-9B4A-807D444A5277} {3704A09C-3CF3-4CB8-BBA5-EDBC6554E13A} = {7A42C497-6F07-4B5E-9B4A-807D444A5277} {81A72F09-FFB8-4967-AB08-141C56A72DE1} = {7A42C497-6F07-4B5E-9B4A-807D444A5277} + {FF8FF1A0-2F37-3C8A-D386-BFD4180F0F43} = {7A42C497-6F07-4B5E-9B4A-807D444A5277} + {33D8C18A-AA25-40C5-8DAC-6BC0664EFF08} = {FF8FF1A0-2F37-3C8A-D386-BFD4180F0F43} + {9D06263E-69F7-46E3-B1A0-622BEA5A94B5} = {FF8FF1A0-2F37-3C8A-D386-BFD4180F0F43} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D41F54E0-CF7E-433A-9A70-F092AF0654FE} diff --git a/README.md b/README.md index ff00ef36..cf6a9dab 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,10 @@ people usually weigh it against. - **Compiled to an execution‑ready document.** A template becomes an in‑memory tree of extension calls wired to **compiled** accessors — member paths to expression‑tree delegates, embedded C# to Roslyn delegates — so nothing is reflected or re‑parsed per render. In the - benchmark run of 2026‑07‑11 it rendered [faster than Razor with fewer allocations](#performance) - (Razor's page is larger and not parity‑checked, so treat that pairing as indicative — the four - parity‑checked engines are the like‑for‑like comparison). + cross‑stack run of 2026‑07‑25 it rendered [1.37× faster than ASP.NET Core Razor with fewer + allocations](#performance) on **byte‑identical output** — Razor is held to the same parity gate as + the four Liquid/Handlebars twins as of that run, so this is a like‑for‑like comparison rather than + the indicative pairing earlier reports had to disclaim. **Best fit:** performance‑sensitive, first‑party .NET rendering by a team that values typed templates and component‑style composition. **Poor fit:** untrusted user‑supplied templates @@ -102,24 +103,28 @@ embedded C# to Roslyn delegates). Rendering walks that document, so it does not or pay per‑call activation, section, or dependency‑injection overhead at run time. The repository includes a [BenchmarkDotNet](https://benchmarkdotnet.org/) suite -([src/Heddle.Performance](src/Heddle.Performance)) that measures Heddle head‑to‑head against four +([benchmarks/dotnet](benchmarks/dotnet)) that measures Heddle head‑to‑head against four other .NET template engines — **Fluid**, **Scriban**, **DotLiquid**, and **Handlebars.Net** — plus ASP.NET Core **Razor**. Every one of the four Liquid/Handlebars twins is held to **byte‑identical output** with Heddle by a parity assertion that runs before any timing, so the render and compile numbers below compare identical work (see -[src/Heddle.Performance/Runners](src/Heddle.Performance/Runners/README.md)). Heddle is the ratio +[benchmarks/README.md](benchmarks/README.md)). Heddle is the ratio baseline (`[Benchmark(Baseline = true)]`, `[MemoryDiagnoser]` enabled). -**The measured workload.** The parity‑checked page is the static composition of -`home.heddle` + `layout.heddle`: the layout's reusable‑section defaults, ~a dozen -component/extension calls (`@assets_component`, `@head_scripts`, …), and a list loop over seven -area‑menu fragments (≈55.5 KB raw output). Because `home.heddle` extends the layout via -`@<<{{layout.heddle}}`, the current engine emits that **ordered fragment sequence** rather than the -full HTML page skeleton (the `@body()` slot resolves to its empty default); the four twins -reproduce exactly those bytes. This keeps the comparison honest — all five engines do the same -work — at the cost of not exercising the literal page chrome. The `RenderRazor` row below renders -the full `Views/home.cshtml` page (larger, different output) and is **not** under the parity -assertion, so treat it as indicative rather than apples‑to‑apples. +**The measured workload** *(as it stood for this 2026‑07‑11 run; the workload was redesigned +on 2026‑08‑08 — see the cross‑stack section below)*. The parity‑checked page was the static +composition of `home.heddle` + `layout.heddle`: the layout's reusable‑section defaults, ~a +dozen component/extension calls, and a list loop over seven area‑menu fragments (≈55.5 KB raw +output). Because `home.heddle` extended the layout via `@<<{{layout.heddle}}`, the engine +emitted that **ordered fragment sequence** rather than the full HTML page skeleton; the four +twins reproduced exactly those bytes. This kept the comparison honest — all five engines did +the same work — at the cost of not exercising the literal page chrome. *(That cost is gone in +the current suite: since the 2026‑08‑08 redesign, `composed-page` renders the **full HTML +page** — layout with a live body slot, section defaults, literal chrome, and a structured nav +through nested partials — in every engine.)* The `RenderRazor` row below rendered the full +`Views/home.cshtml` page (larger, different output) and was **not** under the parity +assertion, so treat it as indicative rather than apples‑to‑apples; the current suite's Razor +twin is a full parity twin. ### Results — 2026‑07‑11 (commit `8341bb67`) @@ -160,15 +165,15 @@ engines and allocates far more up front — a cost amortized across every subseq where it leads. Handlebars.Net compiles slower still (8.29 ms, 31.3× Heddle). Raw BenchmarkDotNet artifacts (md/csv/html) for this run are committed under -[docs/benchmarks/2026-07-11](docs/benchmarks/2026-07-11). Numbers are hardware‑ and date‑specific; +docs/benchmarks/2026-07-11. Numbers are hardware‑ and date‑specific; reproduce them yourself with: ``` -dotnet run -c Release --project src/Heddle.Performance +dotnet run -c Release --project benchmarks/dotnet -- bench-crossstack ``` **Workload breadth.** The composition page above is one of three published workloads. A -[trivial-substitution and a large-loop workload](docs/benchmarks/2026-07-18) bracket it — the +trivial-substitution and a large-loop workload bracket it — the former (scalar output, no composition) is the shape where Heddle's lead is workload-dependent rather than universal (in the 2026‑07‑18 run Heddle rendered it fastest but Handlebars.Net allocated less than half the memory), and the latter (one large iteration) is where the time race @@ -177,6 +182,110 @@ the same four engines. No universal-superiority claim follows. Numbers are hardw date-specific; reproduce with the command above filtered to `*SubstitutionRenderBenchmarks*` / `*LoopRenderBenchmarks*`. +### Cross-stack — 2026-08-08 + +The two runs above compare Heddle only against other .NET engines. The +cross-stack run widens that to **fifteen engines across six +ecosystems** — .NET, Rust, the JVM, JS/Node, Python and Go — over **eight workloads** in two +tracks, all on one machine in one session, every controlled cell held to byte-identical output +against a shared golden corpus. + +``` +Windows 11 (10.0.26200.8894/25H2) · AMD Ryzen 9 9950X, 16 physical / 32 logical cores +.NET 10.0.10 · rustc 1.97.1 · JDK 25.0.4 · node v24.19.0 · CPython 3.14.7 · go1.26.5 · templ v0.3.1020 +BenchmarkDotNet 0.15.8 · Criterion · JMH 1.37 · mitata 1.0.34 (38 passes per track) · pyperf 2.10.0 · benchstat +``` + +This run executed on the program's **Windows protocol machine** — the box its metrics protocol +pins for cross-compared runs — with **every toolchain on its pin, zero drift**, and it is +unreplicated: no cross-check on a second platform is currently published. Windows has no captured +tuned state (the posture is procedural: quiet machine, AC power, High Performance plan), so +absolute figures are not comparable with tuned boost-off runs on other platforms or clock states. +The report states the full caveat set. + +The eight workloads split into two sizing regimes, and the report leads with the realistic one. +The boundary is not editorial: the CLR allocates any object of **85,000 bytes or more on the Large +Object Heap**, and .NET strings are UTF-16, so a page crosses that line at 42,500 characters and +every render past it drives a full Gen2 collection. Five workloads sit below it; three sit above. + +#### Tier 1 — realistic sizing (338 B – 15.5 KB) + +**Heddle is the fastest of the six .NET engines on all five**, by 2.25×–3.64× (controlled track, +next-fastest .NET engine shown; lower is better): + +| Workload | Golden | Heddle | Next .NET engine | Margin | +| --- | ---: | ---: | --- | ---: | +| trivial-substitution | 338 B | 149 ns | Handlebars.Net 2.1.6 — 385.8 ns | **2.59×** | +| fortunes-encoded | 1,156 B | 739.1 ns | Handlebars.Net 2.1.6 — 1.66 μs | **2.25×** | +| fragment-heavy | 4,730 B | 3.081 μs | Fluid.Core 2.31.0 — 11.22 μs | **3.64×** | +| mixed-page | 9,712 B | 2.636 μs | Handlebars.Net 2.1.6 — 7.247 μs | **2.75×** | +| conditional-heavy | 15,549 B | 15.02 μs | Handlebars.Net 2.1.6 — 34.51 μs | **2.30×** | + +Cross-stack it is **top-4 on all five**, beaten only by Askama (Rust, compile-time), JTE (JVM, +compiled to Java source) and, on two of the five, eta (JS): + +| Workload | Golden | Heddle rank | Ahead of it | +| --- | ---: | ---: | --- | +| trivial-substitution | 338 B | **#3** of 16 | Askama, eta | +| fortunes-encoded | 1,156 B | **#2** of 16 | Askama | +| fragment-heavy | 4,730 B | **#3** of 16 | Askama, JTE | +| mixed-page | 9,712 B | **#2** of 16 | Askama | +| conditional-heavy | 15,549 B | **#4** of 16 | Askama, JTE, eta | + +It is ahead of Tera, templ, `text/template`, handlebars, Thymeleaf, Jinja2 and +Mako on every one of the five. **Askama is the only engine faster than Heddle on all eight +workloads** — a Rust compile-time engine making the same architectural bet, without a managed +runtime. + +#### Tier 2 — edge-case sizing (54 KB – 852 KB rendered), read with the caveats + +| Workload | Golden | Heddle | .NET field | Cross-stack rank | +| --- | ---: | ---: | --- | ---: | +| composed-page | 34,847 B | 34.07 μs | 1 of 6 — 1.77× over Fluid.Core | **#11** of 16 | +| large-loop | 192,780 B | 492.1 μs | 1 of 6 — 1.51× over Handlebars.Net | #6 of 16 | +| encoded-loop | 831,685 B | 1.766 ms | **2 of 6 — Handlebars.Net 1.72 ms** | #7 of 16 | + +**Heddle loses `encoded-loop`** — Handlebars.Net leads at 0.97×, and Razor sits at 1.00×, inside +overlapping dispersion. Handlebars.Net led this workload on the prior (since-removed) runs as +well, across two rebuilds of the .NET harness, so the ordering is a reproduced result rather than +noise. It is escaping throughput over an 852 KB output no page produces — a real signal about the +encoder's bulk path, not a page render. + +**`composed-page`'s #11 of 16 is not a statement about composition machinery.** That workload is +17 pre-existing string fragments concatenated — no loop body, no branch, no escaping — so every +compiled engine reduces it to about 17 `memcpy` calls, and the row measures memory bandwidth and +the allocator rather than template execution. The floor measurements behind that analysis (a +hand-written .NET `string.Concat` of the same fragments sits within ~2× of Heddle's figure) were +taken on an earlier run's box and are carried in the program's ledger as prior evidence; the +report quantifies the LOH cliff (throughput falls 4.5× across the threshold) and the +whitespace-normalization effect on the published `implied B/ns` column. + +**ASP.NET Core Razor is a full member of all eight workloads and both tracks**, under the same +parity gate as every other engine — the earlier single-workload Razor comparison is superseded. +Heddle leads it by 2.51×–37.07× at Tier 1 sizes and 1.90× on `composed-page`; on `encoded-loop` +Razor is marginally ahead (a 1.00× ratio in the tables, within overlapping dispersion). + +Read the cross-stack rows with their evidence class in mind: Rust, JVM and Go are compiled or +same-class **fair-fight** peers, while JS and Python are **reach/context** — they show where a +workload lands in those ecosystems, not a like-for-like engine contest. + +Every figure is materialised output. The JS leg ran **38 aggregated passes per render track**, +each a separate node process asserting a materialisation check before writing its artifact, so +the JS rows are real work rather than the V8 `ConsString` rope artifact earlier runs of this +suite reported. Its cross-process stability verdict is `verified-with-disclosure` on the +controlled track (one cell of sixteen at 5.11% cross-pass RSD; median 1.41%) and `verified` on +the idiomatic track. + +There is **no aggregate score, geomean or overall winner** in the full report, and none should be +inferred here. Numbers are hardware-, platform- and date-specific; reproduce them yourself with: + +```powershell +powershell -ExecutionPolicy Bypass -File benchmarks\run-all.ps1 +``` + +Full analysis, every workload and track, the per-ecosystem tables, allocation sidebars and the +complete caveat register: **[docs/benchmarks/2026-08-08](docs/benchmarks/2026-08-08/index.md)**. + ## Building ```bash diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md index 52bf9f1f..c761df60 100644 --- a/THIRD-PARTY-NOTICES.md +++ b/THIRD-PARTY-NOTICES.md @@ -66,7 +66,7 @@ artifact. | --- | --- | --- | | ANTLR 4 tool (`antlr-4.13.1-complete.jar`) | BSD-3-Clause | Grammar code generation | | Java / JDK | (vendor-dependent) | Running the ANTLR tool | -| xunit, xunit.runner.visualstudio | Apache-2.0 | Unit tests | +| xunit.v3 | Apache-2.0 | Unit tests | | Microsoft.NET.Test.Sdk, coverlet.collector | MIT | Test host / coverage | | BenchmarkDotNet | MIT | Performance benchmarks | | Microsoft.AspNetCore.Mvc.* (Razor) | MIT | Benchmark comparison baseline | diff --git a/benchmarks/ASSESSMENT-FINDINGS.md b/benchmarks/ASSESSMENT-FINDINGS.md new file mode 100644 index 00000000..52c54ae4 --- /dev/null +++ b/benchmarks/ASSESSMENT-FINDINGS.md @@ -0,0 +1,114 @@ +# Benchmark harness assessment — resolution status + +Assessment of the .NET benchmark leg (`benchmarks/dotnet`) and the Heddle sink render paths, +originally performed 2026-08-02 against `c74c3b37` ("New bench"). Re-assessed 2026-08-04 against +`5cd58406`. **All six findings are resolved**, verified by code review, a clean Release build +(0 warnings, 0 errors), and `selftest` (141/141 checks: sink materialisation, six-technique +differential, encoded security floor). Two trivial doc leftovers remain — listed at the end. + +**Discharged 2026-08-04:** `docs/benchmarks/` has been regenerated with the fixed harness. The +2026-08-02 tables — measured by the pre-flip anchor (utf8 checksum sink) — are replaced by the +full six-ecosystem run of 2026-08-03 (`docs/benchmarks/2026-08-03/`), measured on the Windows +protocol machine (newest commit at run start: `5cd58406`) and consolidated with `--check` green. + +--- + +## 1. Bench-path sinks computed checksums with heavy overhead — RESOLVED (`72bebc62`) + +Implemented as proposed, and further: + +- `Bench/BenchSinks.cs` (new): `BenchBufferWriter` (`Advance` moves an offset, nothing else — + the pooled-`PipeWriter` floor) and `BenchTextWriter` (bulk `CopyTo` in every overload, no + per-char virtual dispatch). Pre-sized in `[GlobalSetup]` past the high-water mark + (`oracle.Length * 4 + 4096` covers `Utf8ScopeRenderer`'s 3× worst-case span reservation), + reused via `Reset()` — the per-op 64 KB allocation and per-unit FNV are gone from every timed + region. +- `RenderToSink` was replaced by `RenderToBuffer` / `RenderToWriter` / `RenderToString` with + **caller-owned sinks and a hoisted model** — the old shape also called `ModelFor` inside every + timed iteration, an allocation the precompiled suite never paid; that asymmetry (which + compressed the runtime-vs-precompiled ratio toward 1.0) is fixed too. +- Benchmark bodies return the written count; the anti-elision proof moved to setup: + `CrossStackSuite.PrepareBenchSinks` / `TechniqueSetup.AssertSinks` render once through the + exact bench sinks and assert byte/char equality against the gated string render, per process, + untimed. The gate's `Checksum*` writers are untouched and still back `SelfTest` and the + MATERIALISATION-CHECK trailer. + +## 2. `"Heddle (utf8)"` name collision/mislabel — RESOLVED (`72bebc62`) + +`Name` is now `"Heddle"` (with a doc note recording the old defect); non-anchor cells are +labeled `"Heddle (utf8 sink)"` / `"Heddle (textwriter sink)"`, matching `consolidate.py`'s +display names — one vocabulary across gate output, bench IDs, and report. No two cells share a +name. + +## 3. Stale documentation contradicting the anchor flip — RESOLVED (`72bebc62`) + +- `HeddleEngine.cs` class header now states the string-sink anchor rationale ("materialise your + runtime's native string" invariant), records the earlier utf8-anchor reasoning as a corrected + mistake, and keeps the LOH observation as the reason the utf8 *technique row* is interesting + on composed-page — exactly the proposed shape. +- `Registry.cs` `Cell.InCrossStack` doc now describes the string-sink flag and the non-ranked + technique rows. +- The dangling `RenderHeddleSink` cref now points at `RenderHeddleUtf8Sink` / + `RenderHeddleTextWriterSink`. + +## 4. `HtmlEncodedRenderer` defeated the UTF-8 sink on encoded output — RESOLVED (`a773a509`) + +Stages 1 and 2 of the proposal implemented, invariant preserved (the proxy still never +implements `IUtf8ScopeRenderer`): + +- Clean-span pass-through: `FindFirstCharacterToEncode` (configured encoder) or a hand-written + scanner mirroring `WebUtility.HtmlEncode`'s exact trigger set (legacy path); spans with + nothing to encode forward directly to the inner span sink, zero allocation, and a clean + prefix is forwarded before the dirty tail. +- Chunked encode for dirty tails: `TextEncoder.Encode(span, stackalloc char[256], …)` loop with + a correct zero-progress fallback to the string path (oversized encoded scalar). +- Covered by a new 244-line `HtmlEncodedRendererSpanParityTests` suite plus the existing + encoded-workload byte gate and security floor. +- Stage 3 (`EncodeUtf8` straight-to-UTF-8) remains deliberately deferred pending profiling, as + proposed. + +## 5. Runtime backend re-transcoded static text every render — RESOLVED (`72bebc62`) + +`RuntimeDocument` now caches UTF-8 eagerly at document build: `DocumentStrategy._documentUtf8` +and `DataProcessor.PieceUtf8` (encoded once in the `NormalStrategy` constructor). Both `Render` +paths take the `WritePiece` shape — `IUtf8ScopeRenderer` gets `RenderUtf8(cachedBytes)`, all +other sinks get the chars — with the renderer type-tested once per document, not per piece. +Static pieces still reach the sink directly (never through the encode proxy), so the +never-bypass-encoding invariant is untouched. "Bytes prepared in final form" now holds on both +backends for static content; byte-identity proven by the technique differential (selftest) and +the strict `gate-precompiled` parity gate. + +## 6. Minor nits — RESOLVED (`72bebc62`) + +`ChecksumTextWriter.Encoding` returns `Encoding.Unicode` with a comment recording the +correction; the gate's double-render comment remains accurate under the new API. + +--- + +## Residual doc leftovers (trivial, no behavior impact) + +1. `Bench/TechniqueBenchmarks.cs` class header (~line 18) still says the cross-stack row "is + the runtime UTF-8 sink" — the ranked row is the runtime **string** sink. One-line fix. +2. `Engines/HeddleEngine.cs:167` — a comment in the gate's TextWriter case still references + `RenderToSink`, which no longer exists (now `RenderToBuffer`/`RenderToWriter`/ + `RenderToString`). + +## Verification performed (2026-08-04) + +- `dotnet build -c Release`: 0 warnings, 0 errors. +- `dotnet run -c Release -- selftest`: 141 passed, 0 failed — includes sink materialisation + (count + checksum vs string render, all eight workloads) and the six-technique differential + (runtime + precompiled × three sinks, byte-for-byte), which runtime-proves the `PieceUtf8` + cache and the `HtmlEncodedRenderer` chunked path. +- Grep confirms no non-comment references to the removed `RenderToSink` API remain. + +## Verified-sound (unchanged from the original assessment) + +- `Generate(model, IBufferWriter)` streams UTF-8 directly into caller-provided spans — + no full-output string, no intermediate `byte[]`, correct surrogate handling in the chunked + `Encoder.Convert` loop. +- The gate architecture: corpus byte gate + security floor, sink count/checksum + cross-assertions, six-technique differential, strict 3-sink runtime-vs-precompiled parity + gate — all in the process that times. +- The string anchor is like-for-like with all five .NET competitors, and `consolidate.py` + quarantines the technique rows from every ranking, margin, and summary. diff --git a/benchmarks/README.md b/benchmarks/README.md new file mode 100644 index 00000000..b5094437 --- /dev/null +++ b/benchmarks/README.md @@ -0,0 +1,323 @@ +# Cross-stack benchmarks — reproduce book + +One directory per ecosystem harness, plus two master runners (Windows and Linux) that run +every gate and every measurement with the parameters the phase specs make normative. + +The specs are the source of truth; nothing in this file overrides them: + +| Ecosystem | Harness | Normative spec | +|---|---|---| +| .NET (anchor) | `benchmarks/dotnet` (BenchmarkDotNet) | [metrics-protocol.md](docs/metrics-protocol.md) | +| Rust | `benchmarks/rust` (Criterion) | [rust-workload-ports.md](docs/rust-workload-ports.md) | +| JVM | `benchmarks/jvm` (JMH) | [jvm-harness-and-jmh.md](docs/jvm-harness-and-jmh.md) | +| JS | `benchmarks/js` (mitata) | [js-harness-and-run.md](docs/js-harness-and-run.md) | +| Python | `benchmarks/python` (pyperf) | [python-harness.md](docs/python-harness.md) | +| Go | `benchmarks/go` (testing + benchstat) | [go-harness-and-measurement.md](docs/go-harness-and-measurement.md) | +| Linux cross-check | `benchmarks/linux-crosscheck` | [linux-harness-settings-and-validation.md](docs/linux-harness-settings-and-validation.md), [linux-environment-and-toolchains.md](docs/linux-environment-and-toolchains.md) | + +## Prerequisites (toolchain pins) + +| Toolchain | Pin | Notes | +|---|---|---| +| .NET SDK | **TBD** — pinned to the SDK of the Windows protocol run, which is pending re-test. The published 2026-07-25 Linux run used SDK 10.0.110 / runtime .NET 10.0.10 | suites target `net10.0`, `-c Release` | +| Rust | rustc/cargo 1.97.1 | `rust-toolchain.toml` in `benchmarks/rust` | +| JDK | Temurin 25 | `pom.xml` pins `maven.compiler.release=25`; on a JDK < 25 the runner passes `-Dmaven.compiler.release=23` | +| Node.js | v24.x (major pin, amendment E18; was the exact v24.18.0) | `package.json` `engines: 24.x`; on a non-24 node the runner uses `npm ci --engine-strict=false` and records the delta | +| CPython | 3.14.x (minor pin, amendment E19; was the exact 3.14.6) | harness venv at `benchmarks/python/.venv`; pyperf 2.10.0 + psutil 7.2.2 from `requirements.txt` | +| Go | go1.26.x (1.26.5 asserted by `run-benchmarks.ps1`) | templ CLI v0.3.1020 via `go tool templ` | + +**Version deltas (SR-3 posture):** the Windows master runner *warns* on any delta from a pin +and continues; a *measurement* run on a delta'd toolchain must record the delta in the run +report's environment block (the Go harness is stricter: `run-benchmarks.ps1` hard-fails its +own version asserts). The Linux side records deltas in `version-deltas.md` +(`setup-toolchains.sh`). + +## The commands + +Run from the **repo root**: + +```powershell +# Windows — FULL measurement (protocol machine, quiet, AC power, elevated shell for pyperf): +powershell -ExecutionPolicy Bypass -File benchmarks\run-all.ps1 + +# Windows — SMOKE (short functional pass, ~10–20 min; results carry NO measurement validity): +powershell -ExecutionPolicy Bypass -File benchmarks\run-all.ps1 -Smoke +``` + +```bash +# Linux (bare metal) — FULL measurement, one command (tunes, measures, untunes). +# Needs the "Ubuntu — benchmark isolation" boot entry (see preconditions below): +./benchmarks/run-all.sh --tune + +# Linux (bare metal) — same, without that boot entry: performance governors + boost off +# are set here and restored on exit; the missing CPU isolation is a recorded delta: +./benchmarks/run-all.sh --tune-no-isolation + +# Linux (bare metal) — FULL measurement on an already-tuned machine: +./benchmarks/run-all.sh + +# Linux — SMOKE (short functional pass; no tuned state required, no measurement validity): +./benchmarks/run-all.sh --smoke +``` + +**Two Linux runners, different jobs.** `benchmarks/run-all.sh` is the twin of the Windows runner +(per-step logs, summary table, `--ecosystem` subsets, and `taskset` + `nice -n -20` standing in +for the Windows High priority classes). `benchmarks/linux-crosscheck/` is the Phase 8 cross-check +protocol — D2 no-priority posture, tuned-state pre-flight against a recorded session state, +`validate.py` part-2 tables. **Anything published as a Linux cross-check goes through +`linux-crosscheck/`**; see [its README](linux-crosscheck/README.md) for the full bare-metal order +of operations (install, GRUB isolation entry, environment capture): + +```bash +# Phase 8 cross-check, from benchmarks/linux-crosscheck/ — FULL measurement: +sudo ./tune.sh && ./run-all.sh; ./untune.sh + +# Phase 8 cross-check, Linux/WSL — functional pass (no tuned state required; bypass is recorded): +./run-all.sh --smoke --no-tune-check +``` + +### Windows runner options + +| Option | Effect | +|---|---| +| `-Smoke` | short functional flags everywhere (see table below) | +| `-Ecosystem dotnet,rust,jvm,js,python,go` | subset (any combination; program order is preserved) | +| `-OutDir ` | artifact/log destination (default `benchmarks\out\windows-run-`, git-ignored; the path must not contain spaces) | +| `-Budget short\|baseline` | measurement budget **per engine**: `short` ~10 min each (default), `baseline` ~30 min each. A leg's total is its engine count times that, so the .NET leg is about 3x the others. Named `-Budget` because `$PROFILE` is a PowerShell automatic variable | +| `-JsPasses ` | JS repeat passes per render track (default: the budget's — 18 short / 54 baseline; minimum 5, D13's verdict floor) | + +### Linux runner options + +| Option | Effect | +|---|---| +| `--smoke` | short functional flags everywhere (same shapes as `-Smoke`); also skips the bare-metal pre-flight, recorded in the log | +| `--ecosystem dotnet,rust,jvm,js,python,go` | subset (any combination; program order is preserved) | +| `--out-dir ` | artifact/log destination (default `benchmarks/out/linux-run-`, git-ignored) | +| `--budget short\|baseline` | measurement budget per engine, exactly as `-Budget` | +| `--js-passes ` | JS repeat passes per render track, exactly as `-JsPasses` | +| `--tune` | run the committed `linux-crosscheck/tune.sh` under `sudo` before the run and `untune.sh` from an `EXIT` trap afterwards (so an aborted run still restores the machine). Those two scripts are invoked unmodified. Requires the isolation boot entry — `tune.sh` refuses without it | +| `--tune-no-isolation` | tune what needs no reboot: `performance` governors, `cpufreq/boost=0`, `kernel.perf_event_max_sample_rate=1`. Every prior value is captured to `logs/tune-prior-state.txt` first and restored from an `EXIT` trap. The absent isolated SMT pair is recorded, the pre-flight accepts it, timed runs are not pinned, and pyperf falls back to `--affinity=4`. Mutually exclusive with `--tune` | +| `--no-tune-check` | record a bypass of the bare-metal pre-flight (and of the WSL refusal) and measure anyway — the numbers are not publishable | +| `--no-priority` | launch the JS and Go timed runs plain, matching the Phase 8 D2 posture | + +### Bare-metal preconditions (Linux, full measurement) + +Without `--smoke` the runner refuses to measure under WSL and pre-flights the machine state, +aborting with instructions unless all of the following hold: + +* the *Ubuntu — benchmark isolation* GRUB entry is booted, so `/sys/devices/system/cpu/isolated` + equals the SMT sibling pair of the isolation core (read from the topology, never assumed). + Instantiate it from [linux-crosscheck/grub-isolation.cfg.example](linux-crosscheck/grub-isolation.cfg.example) + — read the pair with `cat /sys/devices/system/cpu/cpu4/topology/thread_siblings_list`, put + `isolcpus= nohz_full= rcu_nocbs=` on a **dedicated** entry (never on + `GRUB_CMDLINE_LINUX_DEFAULT`), `sudo update-grub`, reboot into it. Without this entry + `--tune` refuses by design; use `--tune-no-isolation` to measure anyway with the delta recorded; +* every cpufreq policy reads `performance` and `/sys/devices/system/cpu/cpufreq/boost` reads `0` + — this is what `--tune` (i.e. `linux-crosscheck/tune.sh`) or `--tune-no-isolation` establishes; +* quiet machine: no other builds, watchers, indexing editors or browsers for the duration; +* root or passwordless `sudo`, so `nice -n -20` and pyperf's priority elevation actually apply + (missing privileges are recorded, not fatal — the run continues at default priority). + +## What a run does + +**Phase 1 — gates, all selected ecosystems, stop on first red** (same rule as +`linux-crosscheck/run-all.sh`: a red gate is triaged before anything later runs): + +1. .NET: `gate` (every registered cell), `selftest` (the gate's own checks, including the + six-technique differential), `verify-corpus` (corpus freshness + verifier calibration) +2. Rust: `cargo run --release --bin gate` +3. JVM: `mvnw -q clean verify` (gates wired into `verify`) +4. JS: `npm ci`, `npm run selftest`, `npm run gate` +5. Python: venv create/reuse + `pip install -r requirements.txt`, `python -m runner.selftest`, `python -m runner.gate_all` +6. Go: `go test ./suites` (TestMain gates before anything can time) + +**Phase 2 — measurement**, in the anchor-first program order dotnet → rust → jvm → js → +python → go. The runner prints the machine-state rules (protocol box, quiet machine, power/tuned +state) before this phase; failures here are recorded and the run continues, with a nonzero +overall exit at the end. + +| Ecosystem | Full mode (protocol shape) | Smoke mode | +|---|---|---| +| .NET | `bench-crossstack`, 8 suites, one `--filter **` run each, both fairness tracks, ShortRun + MemoryDiagnoser; then the `bench-techniques`, `bench-cold` and `bench-internal` sidebars | same, `--job Dry` | +| Rust | `cargo bench --bench controlled --bench idiomatic --bench cold -- --noplot`, then `alloc_report` (alloc-count feature), then `summarize` (non-fatal while the Phase 1 Heddle reference rows are pending) | `cargo bench … -- --test` | +| JVM | `java -jar target/benchmarks.jar -prof gc -rf json -rff ` — committed annotation regime (Fork 3, 1×2 s / 3×1 s), **~9 min**; `baseline` adds `-wi 2 -i 9` | `-f 1 -wi 1 -i 1 -w 1s -r 1s -foe true` | +| JS | `run.ps1` / `run.sh` per bench script (`--expose-gc --allow-natives-syntax`, priority posture per platform); the two render tracks run `-Repeat ` and are aggregated by `bench/aggregate.mjs`, which emits the D13 `STABILITY:` verdict every run | the three scripts once via the launcher | +| Python | five pyperf Runner scripts, `--affinity=<4 on Windows, isolated pair on Linux> -o /python/.json`, elevated shell / root (warned if not), then the separate `mem_tracemalloc.py` pass | pyperf `--debug-single-value`; memory `--reps 5` | +| Go | `run-benchmarks.ps1` / `run-benchmarks.sh` (version asserts, templ freshness, vet, gates, prebuild, timed runs `-test.count=20 -test.benchtime=1s`, benchstat) | `-Count 1 -BenchTime 100ms` / `--count 1 --benchtime 100ms` | + +### Measurement budget — `--budget short` (default) / `baseline` + +Each harness sets its own run lengths, so before +amendment E6 "one cell" cost wildly +different amounts of wall clock per ecosystem. These are **measured** figures from the +withdrawn 2026-07-22 Windows run's `summary.txt`, not estimates. That run's *render figures* are +invalid and its report has been removed pending a Windows re-test (**TBD**), but its per-step +wall-clock durations are simply how long each harness took, which is what this comparison needs: + +| Ecosystem | Cells | Was | s/cell | The problem | +|---|---:|---:|---:|---| +| JS | 32 | 31 s | **1.0** | 15–32× *below* every other leg | +| Rust | 33 | 8.3 min | 15 | in band | +| Python | 32 | 14.3 min | 17 | in band | +| Go | 32 | 13.8 min | 26 | in band | +| .NET | 41 | 21.5 min | 32 | in band | +| JVM | 32 | **4.47 h** | **503** | 16–34× above the band; **83% of the whole session** | + +Neither extreme was chosen — both are what the harness happened to default to. E6 replaced that +with one selectable budget; amendment E13 then changed +the unit it is measured in from **one ecosystem** to **one engine**: + +```bash +./benchmarks/run-all.sh # --budget short ~10 min per engine (default) +./benchmarks/run-all.sh --budget baseline # ~30 min per engine: ~3x the capture samples +``` +```powershell +.\benchmarks\run-all.ps1 -Budget baseline # same on Windows (-Budget, not -Profile: $PROFILE is reserved) +``` + +Every harness's **committed source/script default is the `short` shape**, so a bare invocation of +any single harness is already the budgeted regime; `baseline` layers CLI overrides on top. Nothing +changes about *what* is measured — only how many times. + +**The unit is one engine (E13, resized program-wide by E14).** An *engine* is **16 cells** — eight +workloads × two fairness tracks — and every engine in the program gets **~10 min at `short` and +~30 min at `baseline`**, whichever ecosystem it lives in. Five legs carry two engines each; .NET +carries **six** (Heddle, Fluid, Scriban, DotLiquid, Handlebars.Net, Razor), so its leg is about three +times the others *by construction*. Budgeting the leg instead would have given each .NET engine a +third of the sampling every other ecosystem's engines get, and the cross-engine comparison this +program exists to make would rest on its worst-sampled rows. + +| Ecosystem | Knob | `short` (committed default) | `baseline` override | short | baseline | +|---|---|---|---|---:|---:| +| .NET | BenchmarkDotNet job | ShortRun + **`LaunchCount 3`** | `--launchCount 10` | ~93 min† | ~284 min† | +| Rust | criterion | warm-up 5 s, measure 26 s, 100 samples | `--warm-up-time 10 --measurement-time 84` | ~20 min | ~60 min | +| JVM | JMH annotations | `@Fork(5)`, `@Warmup(1×2s)`, `@Measurement(5×1s)` | `-f 5 -wi 2 -i 17` | ~20 min | ~60 min | +| JS | aggregated passes | 38 passes per render track | 114 passes | ~20 min | ~61 min | +| Python | pyperf | render 20 processes × 6 values × 1 warmup; cold-compile `--processes 7` | `--values 20 --warmups 2`; cold-compile at default 20 | ~19 min | ~61 min | +| Go | `go test -count` | `28` | `--count 84` | ~19 min | ~58 min | + +**Every figure in that table is projected**, and deliberately so: they are the E6-measured durations +scaled by the knob change, not fresh measurements. Only the .NET per-cell cost was measured directly +for this resize (below). Replace the whole column with real durations after the first protocol run. + +Session totals at these settings: **~3.2 h short, ~9.7 h baseline** — against ~1 h and ~2.5 h when +the budget was per *ecosystem*, and 5.45 h before E6. That is the price of sampling seventeen +engines' worth of comparison rows equally instead of sampling six of them a third as well as the +rest. + +† **.NET, and why its figures are the shape they are.** The leg is **151 cells**: 96 cross-stack +(8 workloads × 6 engines × 2 tracks) plus the techniques, cold and internal sidebars. Only the 96 +cross-stack cells carry an engine's comparison rows, so those are what the per-engine budget sizes: +**~9.9 min short / ~30.1 min baseline** for each engine's 16 cells. + +.NET spends its budget on **launches**, and only on launches. Two reasons. The practical one: the leg +is overhead-bound (one process per benchmark case, plus JIT and `[MemoryDiagnoser]`), so wall clock +is very nearly linear in `LaunchCount`, which makes the knob predictable — measured here on one +12-cell suite, **139 s at 1 launch, 316 s at 2, 704 s at 5**, about 10.8 s per cell per additional +launch. Raising the iteration counts instead runs through BenchmarkDotNet's pilot stage and does +not: a trial at `--launchCount 4 --warmupCount 5 --iterationCount 8` overshot its projection by more +than 2× and was abandoned. + +The substantive reason: `LaunchCount 1` samples the **within-process term only** — one process, one +JIT, one heap layout — and never samples the cross-process term at all. E6 established that this is +the term worth paying for, keeping JMH's forks plural after measuring fork-to-fork RSD at 1.18% +median against a within-fork 0.18%, and re-spending the whole JS budget on independent processes for +exactly this reason. The .NET leg was the one that had never bought it. + +The default job lives in the harness's configuration rather than in a `[SimpleJob]` attribute, for +the same reason `--job Dry` now means what it says: an attribute job cannot be *replaced* from the +command line, only added to, so a smoke pass used to run the full measurement as well as the dry +one. + +`LaunchCount 3` puts an engine's 16 cells at ~9.9 min and `LaunchCount 10` at ~30.1 min. The leg +totals in the table are larger because they also carry the 55 Heddle-only sidebar cells, which ride +at the same job shape but belong to no engine's comparison share. + +**JS is a different mechanism, and deliberately so.** mitata exposes no per-cell time budget: +`B.run()` builds its own options object and `run()` forwards only `throw`, so the 642 ms +`min_cpu_time` is unreachable without forking the library. JS therefore spends its budget on +**independent processes** — `run.sh --repeat N`, then `bench/aggregate.mjs` publishes the median +of the per-pass `avg` with the cross-pass `min … max` as dispersion. That buys the +*cross-process* term a single-process harness never samples, which is the same thing JMH gets +from forks and pyperf from its 20 workers. It also makes the Phase 4 D13 stability verdict +automatic instead of opt-in: every run writes `stability-summary-.md` with a +`STABILITY:` line and exits non-zero on `failed`. Measured here: 18 passes of the controlled +track in 279 s → `STABILITY: verified`, cross-pass RSD median 1.81% / max 2.85%. The +withdrawn 2026-07-22 run shipped JS numbers with no verdict at all because the old opt-in switch was +simply never passed. + +**Priority posture (Linux twins).** Windows sets a High process priority class for the JS and Go +timed runs (`start /high`, `PriorityClass = High`); `run-all.sh`, `js/run.sh` and +`go/run-benchmarks.sh` approximate that with `taskset -c ` + `nice -n -20`. +The Phase 8 launchers under `linux-crosscheck/` deliberately do **not** (D2: the tune plus CPU +isolation *is* the isolation), so numbers from the twins are not drop-in comparable with the +published cross-check runs — record the delta in the run report's environment block, or pass +`--no-priority` to match D2. + +## Where artifacts land + +Everything from one Windows run lands under the run's `-OutDir` +(default `benchmarks\out\windows-run-`, git-ignored): + +``` +\ + logs\-.log every step's full output (also echoed live) + logs\preamble.log toolchain versions + pin-delta warnings + summary.txt the per-step exit-code table + dotnet\ copy of BenchmarkDotNet.Artifacts (results\*.md/csv/json + logs) + rust\criterion\ copy of target\criterion (estimates.json per benchmark) + jvm\jmh-result.json JMH JSON (written there directly via -rff) + js\ copy of benchmarks\js\artifacts (*.txt captures + *.json) + python\.json pyperf JSONs + memory.json (written there directly via -o) + go\ copy of benchmarks\go\results (bench + benchstat outputs) +``` + +A Linux run's outputs land under `--out-dir` in exactly the same shape +(default `benchmarks/out/linux-run-`, git-ignored), with `logs/tune.log` added +when `--tune` is used. The Phase 8 cross-check tooling writes elsewhere: +`benchmarks/linux-crosscheck/out/` (self-git-ignored). + +## Running one harness alone (manual per-ecosystem commands) + +All commands from the harness directory shown; gates first, always. Where the launcher differs +per platform, the Windows form is given first and the Linux twin second. + +| Ecosystem | Directory | Gate | Measurement | +|---|---|---|---| +| .NET | `benchmarks/dotnet` | `dotnet run -c Release -- gate`, then `… -- selftest`, then `… -- verify-corpus` | `dotnet run -c Release -- bench-crossstack --filter **` (8 suites), then `bench-techniques`, `bench-cold`, `bench-internal` (`export-corpus` rewrites the goldens — never run it casually) | +| Rust | `benchmarks/rust` | `cargo run --release --bin gate` | `cargo bench --bench controlled --bench idiomatic --bench cold -- --noplot`; `cargo run --release --features alloc-count --bin alloc_report`; `cargo run --release --bin summarize` | +| JVM | `benchmarks/jvm` | `.\mvnw.cmd -q clean verify` / `./mvnw -q clean verify` (add `-Dmaven.compiler.release=23` on a JDK < 25) | `java -jar target/benchmarks.jar -prof gc -rf json -rff jmh-result.json` | +| JS | `benchmarks/js` | `npm ci` + `npm run selftest` + `npm run gate` | `./run.ps1 bench/controlled.mjs` / `./run.sh bench/controlled.mjs` (also `idiomatic.mjs`, `cold-compile.mjs`); stability: `-Repeat 5` / `--repeat 5` | +| Python | `benchmarks/python` | `python -m runner.selftest` + `python -m runner.gate_all` (venv python: `.venv\Scripts\python.exe` / `.venv/bin/python`) | `python bench_.py --affinity=4 -o results/.json` (×5, elevated shell / root); `python mem_tracemalloc.py -o results/memory.json` | +| Go | `benchmarks/go` | `go test ./suites` | `./run-benchmarks.ps1` / `./run-benchmarks.sh` | + +## Publication + +Assembling a published report is **manual**, per +[metrics-protocol.md](docs/metrics-protocol.md): +copy the run's artifacts into `docs/benchmarks//` with the environment block, +the two-track tables, the allocation labels/caveats, and the honest-reporting rules — the +runners never write into `docs/`. The Linux cross-check report additionally goes through +`linux-crosscheck/validate.py` (part 2 tables/verdicts) and the WI8 assembly step described +in [linux-crosscheck/README.md](linux-crosscheck/README.md). + +**The tables themselves are generated, not transcribed.** Once the artifacts are in place, +`report/consolidate.py` reads every harness's native output — BenchmarkDotNet CSV, Criterion +`estimates.json`, JMH JSON, mitata JSON, pyperf JSON, benchstat text — and writes +`consolidated-tables.md` into the run directory: + +```bash +python benchmarks/report/consolidate.py docs/benchmarks/ +python benchmarks/report/consolidate.py --check docs/benchmarks/ +``` + +`--check` re-derives the tables and diffs them against the committed file, so a published +report stays byte-reproducible from its artifacts and a stale table is a failing command rather +than a silent error. The report's `index.md` is still hand-written — the narrative, the +environment block, the findings and the caveat register are judgement, not extraction — and it +links the generated tables rather than restating their numbers. Note this keeps the +runners-never-write-into-`docs/` invariant intact: `consolidate.py` is run by hand after a run, +never by `run-all.ps1`/`run-all.sh`. + +Worked example: docs/benchmarks/2026-07-25 is the first +six-ecosystem report published this way. diff --git a/benchmarks/bench-common.sh b/benchmarks/bench-common.sh new file mode 100644 index 00000000..8dabc072 --- /dev/null +++ b/benchmarks/bench-common.sh @@ -0,0 +1,264 @@ +#!/usr/bin/env bash +# bench-common.sh -- shared helpers for the Linux twins of the PowerShell runners +# (run-all.sh, go/run-benchmarks.sh, js/run.sh). +# +# Deliberately standalone: benchmarks/linux-crosscheck/common.sh implements the Phase 8 +# cross-check protocol (tuned-state pre-flight against a recorded session state, WSL +# functional posture, D2 no-priority rule) and is NOT sourced or modified from here. +# +# Sourced, not executed. + +# --- Layout ------------------------------------------------------------------------------ +BENCH_COMMON_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +BENCH_ROOT="$BENCH_COMMON_DIR" +BENCH_REPO_ROOT="$(cd -- "$BENCH_ROOT/.." >/dev/null 2>&1 && pwd)" + +# The physical core whose SMT sibling pair is the isolation target (Phase 8 D1.6 value). +BENCH_ISOLATION_CPU="${BENCH_ISOLATION_CPU:-4}" + +# Set to 1 to suppress the nice/taskset launch prefix everywhere (D2 posture). +BENCH_NO_PRIORITY="${BENCH_NO_PRIORITY:-0}" + +bench_note() { echo "== $*"; } +bench_warn() { echo "WARN: $*" >&2; } +bench_die() { echo "ERROR: $*" >&2; exit 1; } + +# --- WSL detection ----------------------------------------------------------------------- +# WSL2 kernels self-identify in /proc/version and /proc/sys/kernel/osrelease. +bench_is_wsl() { + grep -qiE 'microsoft|wsl' /proc/version 2>/dev/null || \ + grep -qiE 'microsoft|wsl' /proc/sys/kernel/osrelease 2>/dev/null +} + +# --- Topology ---------------------------------------------------------------------------- +# The SMT sibling pair is READ from the topology, never assumed. Fails (nonzero) when the +# topology file is absent -- which it is under WSL2. +bench_smt_pair() { + local f="/sys/devices/system/cpu/cpu${BENCH_ISOLATION_CPU}/topology/thread_siblings_list" + [ -r "$f" ] || return 1 + cat "$f" +} + +bench_isolated_set() { + cat /sys/devices/system/cpu/isolated 2>/dev/null || true +} + +# --- Tuned-state pre-flight --------------------------------------------------------------- +# Asserts the bare-metal measurement state: every cpufreq policy on 'performance', boost +# off, and the isolated set equal to the read SMT pair. Returns nonzero with remediation +# instructions instead of dying, so callers decide whether the failure is fatal. +# +# bench_tuned_preflight [allow_no_isolation] +# allow_no_isolation=1 -- a missing/empty isolated set is RECORDED instead of fatal +# (the --tune-no-isolation mode: tuned frequencies, no isolcpus boot entry). +bench_tuned_preflight() { + local allow_no_isolation="${1:-0}" + local ok=0 pair isolated govs boost + + if bench_is_wsl; then + echo "PRE-FLIGHT: WSL2 detected -- no cpufreq policies, no boost control, no isolcpus boot." >&2 + ok=1 + fi + + if ! pair="$(bench_smt_pair)"; then + echo "PRE-FLIGHT: cannot read cpu${BENCH_ISOLATION_CPU}'s thread_siblings_list (no per-CPU topology)." >&2 + [ "$allow_no_isolation" = "1" ] || ok=1 + pair="" + fi + + isolated="$(bench_isolated_set)" + if [ -z "$isolated" ]; then + if [ "$allow_no_isolation" = "1" ]; then + echo "RECORDED: /sys/devices/system/cpu/isolated is empty -- measuring WITHOUT CPU isolation." + echo "RECORDED: no isolcpus/nohz_full/rcu_nocbs boot entry, so the timed runs are not pinned" + echo "RECORDED: to an isolated SMT pair. This is a measurement-quality delta against the" + echo "RECORDED: published protocol and must be disclosed in the run report." + else + echo "PRE-FLIGHT: /sys/devices/system/cpu/isolated is empty -- the isolation GRUB entry is not booted." >&2 + ok=1 + fi + elif [ -n "$pair" ] && [ "$isolated" != "$pair" ]; then + echo "PRE-FLIGHT: isolated set '$isolated' does not equal the read sibling pair '$pair'." >&2 + ok=1 + fi + + govs="$(cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 2>/dev/null | sort -u || true)" + if [ "$govs" != "performance" ]; then + echo "PRE-FLIGHT: cpufreq governors read '${govs:-}', expected 'performance'." >&2 + ok=1 + fi + + boost="$(cat /sys/devices/system/cpu/cpufreq/boost 2>/dev/null || true)" + if [ "$boost" != "0" ]; then + echo "PRE-FLIGHT: cpufreq boost reads '${boost:-}', expected '0'." >&2 + ok=1 + fi + + if [ "$ok" -ne 0 ]; then + echo "PRE-FLIGHT: this machine is NOT in the bare-metal measurement state." >&2 + echo "PRE-FLIGHT: enter it with the committed Phase 8 tooling (unmodified):" >&2 + echo "PRE-FLIGHT: sudo $BENCH_ROOT/linux-crosscheck/tune.sh (or pass --tune to run-all.sh)" >&2 + echo "PRE-FLIGHT: boot the 'Ubuntu -- benchmark isolation' entry first" >&2 + echo "PRE-FLIGHT: (benchmarks/linux-crosscheck/grub-isolation.cfg.example)." >&2 + echo "PRE-FLIGHT: without that boot entry, --tune-no-isolation tunes frequencies only" >&2 + echo "PRE-FLIGHT: (recorded delta); --smoke skips this check; --no-tune-check records a bypass." >&2 + return 1 + fi + + bench_note "pre-flight OK: governors=performance, boost=0, isolated=${isolated:-}" + return 0 +} + +# --- Frequency tuning without the isolation boot entry -------------------------------------- +# Self-contained counterpart of linux-crosscheck/tune.sh for machines that are NOT booted +# into the isolcpus entry: it sets what can be set without a reboot (performance governors, +# boost off, perf sample rate) and nothing else. linux-crosscheck/ is not involved. +# +# Every prior value is captured first so bench_untune_no_isolation restores the machine +# exactly as found -- including on an aborted run (callers wire it to an EXIT trap). + +bench_sudo() { + if [ "$(id -u)" = "0" ]; then "$@"; else sudo "$@"; fi +} + +bench_write_sysfs() { # value path + printf '%s\n' "$1" | bench_sudo tee "$2" >/dev/null +} + +BENCH_BOOST_FILE="/sys/devices/system/cpu/cpufreq/boost" + +# bench_capture_prior_state +bench_capture_prior_state() { + local out="$1" f + : > "$out" + for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do + [ -r "$f" ] || continue + printf 'gov|%s|%s\n' "$f" "$(cat "$f")" >> "$out" + done + if [ -r "$BENCH_BOOST_FILE" ]; then + printf 'boost|%s|%s\n' "$BENCH_BOOST_FILE" "$(cat "$BENCH_BOOST_FILE")" >> "$out" + fi + if command -v sysctl >/dev/null 2>&1; then + printf 'sysctl|kernel.perf_event_max_sample_rate|%s\n' \ + "$(sysctl -n kernel.perf_event_max_sample_rate 2>/dev/null || echo '')" >> "$out" + fi +} + +# bench_tune_no_isolation +# Returns nonzero (after reporting) if a post-condition does not read back. +bench_tune_no_isolation() { + local prior="$1" f govs boost + + if bench_is_wsl; then + echo "ERROR: --tune-no-isolation is bare-metal only (WSL2 exposes no cpufreq policies)." >&2 + return 1 + fi + if [ "$(id -u)" != "0" ] && ! sudo -n true 2>/dev/null; then + echo "NOTE: --tune-no-isolation needs root; sudo will prompt." >&2 + fi + + bench_capture_prior_state "$prior" + bench_note "prior machine state captured -> $prior" + + local any=0 + for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do + [ -w "$f" ] || [ -r "$f" ] || continue + bench_write_sysfs performance "$f" || true + any=1 + done + [ "$any" = "1" ] || { echo "ERROR: no cpufreq scaling_governor files exposed -- nothing to tune." >&2; return 1; } + + if [ -e "$BENCH_BOOST_FILE" ]; then + bench_write_sysfs 0 "$BENCH_BOOST_FILE" || true + else + bench_note "RECORDED: no $BENCH_BOOST_FILE -- boost control absent on this kernel/platform" + fi + + if command -v sysctl >/dev/null 2>&1; then + bench_sudo sysctl -q -w kernel.perf_event_max_sample_rate=1 2>/dev/null || \ + bench_note "RECORDED: could not set kernel.perf_event_max_sample_rate=1" + fi + + # Post-conditions (the ones this mode claims; isolation is explicitly NOT claimed). + govs="$(cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 2>/dev/null | sort -u || true)" + if [ "$govs" != "performance" ]; then + echo "ERROR: governor post-condition failed: read '${govs:-}', expected 'performance'." >&2 + return 1 + fi + bench_note "post-condition OK (governor, all policies): performance" + if [ -e "$BENCH_BOOST_FILE" ]; then + boost="$(cat "$BENCH_BOOST_FILE")" + if [ "$boost" != "0" ]; then + echo "ERROR: boost post-condition failed: read '$boost', expected '0'." >&2 + return 1 + fi + bench_note "post-condition OK (boost): 0" + fi + bench_note "tuned WITHOUT CPU isolation (no isolcpus boot entry) -- recorded delta" + return 0 +} + +# bench_untune_no_isolation +bench_untune_no_isolation() { + local prior="$1" kind path value + if [ ! -f "$prior" ]; then + bench_warn "no prior-state file at $prior -- machine left tuned; restore manually" + return 1 + fi + while IFS='|' read -r kind path value; do + [ -n "${kind:-}" ] || continue + case "$kind" in + gov|boost) [ -n "$value" ] && bench_write_sysfs "$value" "$path" || true ;; + sysctl) [ -n "$value" ] && bench_sudo sysctl -q -w "$path=$value" 2>/dev/null || true ;; + esac + done < "$prior" + bench_note "machine state restored from $prior" + bench_note "governors now: $(cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 2>/dev/null | sort -u | tr '\n' ' ')" + [ -e "$BENCH_BOOST_FILE" ] && bench_note "boost now: $(cat "$BENCH_BOOST_FILE")" + return 0 +} + +# --- Launch priority (Windows-parity posture) --------------------------------------------- +# The Windows launchers set a High process priority class (js/run.ps1, go/run-benchmarks.ps1's +# `start /high`). The Linux twins approximate that with `nice -n -20` plus `taskset` onto the +# isolated SMT pair. +# +# NOTE: benchmarks/linux-crosscheck/run-{go,js}.sh deliberately do NOT do this (Phase 8 D2: +# the tune + isolation IS the isolation). Runs made with these twins therefore carry a +# posture delta that must be recorded in the run report's environment block. +# +# Populates the global array BENCH_PRIORITY_PREFIX (possibly empty) and the string +# BENCH_PRIORITY_RECORDED. Never fails: when part of the prefix cannot be applied it records +# the fact so it lands in the launcher log, and continues with what it can apply. +BENCH_PRIORITY_PREFIX=() +BENCH_PRIORITY_RECORDED="" + +bench_priority_argv() { + local pair + BENCH_PRIORITY_PREFIX=() + BENCH_PRIORITY_RECORDED="" + + if [ "$BENCH_NO_PRIORITY" = "1" ]; then + BENCH_PRIORITY_RECORDED="RECORDED: --no-priority -- plain launch (Phase 8 D2 posture)" + return 0 + fi + + if pair="$(bench_smt_pair)" && [ -n "$(bench_isolated_set)" ]; then + if command -v taskset >/dev/null 2>&1; then + BENCH_PRIORITY_PREFIX+=(taskset -c "$pair") + else + BENCH_PRIORITY_RECORDED="RECORDED: taskset not on PATH -- no CPU pinning applied" + fi + else + BENCH_PRIORITY_RECORDED="RECORDED: no isolated SMT pair -- no CPU pinning applied" + fi + + if [ "$(id -u)" = "0" ]; then + BENCH_PRIORITY_PREFIX+=(nice -n -20) + elif sudo -n true 2>/dev/null; then + BENCH_PRIORITY_PREFIX+=(sudo -n nice -n -20) + else + BENCH_PRIORITY_RECORDED="${BENCH_PRIORITY_RECORDED:+$BENCH_PRIORITY_RECORDED; }RECORDED: no root and no passwordless sudo -- 'nice -n -20' not applied, default priority used" + fi + return 0 +} diff --git a/benchmarks/docs/README.md b/benchmarks/docs/README.md new file mode 100644 index 00000000..3173b7c7 --- /dev/null +++ b/benchmarks/docs/README.md @@ -0,0 +1,27 @@ +# Benchmark contract documentation + +The operational contract the cross-stack benchmark harnesses implement. The program that +produced it is complete; its collapsed decision record lives in +[cross-cutting-decisions.md § Program record — cross-stack benchmarks](../../docs/spec/common/cross-cutting-decisions.md#program-record--cross-stack-benchmarks-closed). +The reproduce book is [benchmarks/README.md](../README.md). + +| Document | What it pins | +| --- | --- | +| [workloads.md](workloads.md) | The eight workloads: template shapes per engine, model data, expected output characteristics | +| [parity-contract-v2.md](parity-contract-v2.md) | The parity contract: normalization pipeline N1–N5 (+N3b), entity canonicalization, untrusted-data alphabet, controlled/idiomatic gates, exclusion policy | +| [golden-corpus.md](golden-corpus.md) | Golden oracle corpus: on-disk format, manifest, export tool, verifier definitions, regeneration policy | +| [metrics-protocol.md](metrics-protocol.md) | Statistic mapping, presentation rules, machine record, report format, honest-reporting rules | +| [report-assembly.md](report-assembly.md) | Consolidated-report assembly: verbatim-excerpt rule, permitted arithmetic, publication layout | +| [rust-workload-ports.md](rust-workload-ports.md) | Rust: Askama + Tera ports, the 32 normative cell texts, budget and measurement rules | +| [jvm-construct-mapping.md](jvm-construct-mapping.md) | JVM: JTE + Thymeleaf construct mapping | +| [jvm-harness-and-jmh.md](jvm-harness-and-jmh.md) | JVM: JMH harness settings and run procedure | +| [jvm-thymeleaf-feasibility.md](jvm-thymeleaf-feasibility.md) | JVM: Thymeleaf controlled-track feasibility probe and exclusion-evidence procedure | +| [js-harness-and-run.md](js-harness-and-run.md) | JS: mitata harness, materialisation checks, run procedure | +| [js-templates-and-models.md](js-templates-and-models.md) | JS: Handlebars + Eta templates and models | +| [python-harness.md](python-harness.md) | Python: pyperf harness, in-worker gate, tracemalloc memory pass | +| [python-templates.md](python-templates.md) | Python: Jinja2 + Mako templates | +| [go-port-mapping.md](go-port-mapping.md) | Go: html/template + templ port mapping | +| [go-harness-and-measurement.md](go-harness-and-measurement.md) | Go: testing/benchstat measurement, layout and toolchain rules | +| [go-templ-feasibility.md](go-templ-feasibility.md) | Go: templ feasibility spike | +| [linux-environment-and-toolchains.md](linux-environment-and-toolchains.md) | Linux cross-check: environment capture and toolchain install | +| [linux-harness-settings-and-validation.md](linux-harness-settings-and-validation.md) | Linux cross-check: harness settings, validation tool, material-divergence thresholds | diff --git a/benchmarks/docs/go-harness-and-measurement.md b/benchmarks/docs/go-harness-and-measurement.md new file mode 100644 index 00000000..6ef4991b --- /dev/null +++ b/benchmarks/docs/go-harness-and-measurement.md @@ -0,0 +1,259 @@ +# Go harness, gates, measurement settings, and report format + +> Operational documentation of the completed cross-stack benchmark program — the contract the harnesses implement. Collapsed decision record: [cross-cutting-decisions.md § Program record — cross-stack benchmarks](../../docs/spec/common/cross-cutting-decisions.md#program-record--cross-stack-benchmarks-closed). + +Harness documentation for the Go leg of the program (phase 6). It pins the Go module layout, the +gate implementations (controlled byte gate, idiomatic verifier, security floor), the +`testing.B` benchmark shape, the repeated-run and stability settings for the protocol machine, +and the phase's report format as an instantiation of the program's +[metrics & publication protocol](metrics-protocol.md). + +## Module layout + +``` +benchmarks/go/ ← D2: new top-level benchmarks// convention + go.mod / go.sum ← module heddle.dev/benchmarks/go (local-only, never published) + README.md ← how to run; S1 results block; regeneration commands + EXCLUSIONS.md ← created only on a confirmed non-whitespace exclusion (go-templ-feasibility.md) + internal/model/ ← pinned models (go-port-mapping.md), incl. composed.go fragments + internal/corpus/ ← corpus loader, N1–N5 pipeline, byte gate, verifier, alphabet assert + internal/stdlibtpl/controlled/ ← text/template + html/template controlled sources & renderers + internal/stdlibtpl/idiomatic/ ← stdlib idiomatic ports (same surface split) + internal/templeng/controlled/ ← controlled .templ + generated *_templ.go (committed) + internal/templeng/idiomatic/ ← idiomatic .templ + generated (committed) + internal/spike/ ← S1 probes + attempts/ (evidence, excluded from timing) + internal/qtpl/ ← created only if the quicktemplate stretch triggers (D10) + suites/ ← bench_test.go, gate_test.go, coldparse_test.go, TestMain + run-benchmarks.ps1 ← the reproduce-it-yourself entry point (below) +``` + +Corpus files are read at gate time from the repo-relative path +`../../benchmarks/dotnet/GoldenCorpus/` (resolved from the module root via +`runtime.Caller`-anchored path, so `go test` works from any working directory). The corpus does +not move (Phase 1's corpus decision, D6, names relocation only if a consumer *cannot* reach +it — a relative path within one repo can). + +### Layout and toolchain rules (D2/D3, condensed) + +The rules `benchmarks/go/.gitattributes` and the module layout cite, condensed from the +phase 6 decisions of record: + +- **D2 — repo layout.** All Go-side code is one repo-local Go module at `benchmarks/go/` + (`heddle.dev/benchmarks/go`, never published; all packages `internal/` except the `suites` + test package) — the program's `benchmarks//` convention. The golden corpus stays + at [`benchmarks/dotnet/GoldenCorpus/`](../dotnet/GoldenCorpus/README.md), consumed read-only + via the repo-relative path above. +- **D3 — toolchain and dependency pins.** `go.mod` pins `go 1.26` + `toolchain go1.26.5`; + `github.com/a-h/templ v0.3.1020` as a require (runtime package) **and** its CLI plus + benchstat as `tool` directives (`tool github.com/a-h/templ/cmd/templ`, + `tool golang.org/x/perf/cmd/benchstat` at + `golang.org/x/perf v0.0.0-20260709024250-82a0b07e230d`), so `go.sum` locks every byte and + `go tool templ` / `go tool benchstat` run the pinned versions with no global installs. + Generated `*_templ.go` files are committed; the runner script re-generates and asserts + `git diff --exit-code` so commits can never drift from the pinned generator. +- **Text/LF round-trip rule** (`benchmarks/go/.gitattributes`): `.templ` sources and the + generated `*_templ.go` are ordinary text under the repo's normal EOL handling. The former + `internal/model/data` `-text` byte-exact pin was removed when amendment E22 moved all literal + chrome into the template tier (the nav model now loads from the corpus fixture at runtime). + The corpus's own round-trip pins (`*.golden.html -text`; JSON sidecars and fixtures + `text eol=lf`) live in the repo root `.gitattributes` beside the corpus. + +## Normalization pipeline (Go implementation) + +`internal/corpus/normalize.go` implements the contract's closed list, nothing more: + +- **N1** — `utf8.Valid(bytes)` must hold (invalid UTF-8 = gate failure); a leading BOM is *not* + stripped (it flows into the comparison and fails it). +- **N2** — `strings.ReplaceAll(s, "\r\n", "\n")` then `strings.ReplaceAll(s, "\r", "\n")`. +- **N3** — collapse `>\s+<` to `><` with *whitespace* pinned to the contract's six-character set: + regex `>[\t\n\v\f\r ]+<` (RE2 `\s` is the ASCII subset `[\t\n\f\r ]`, which **omits VT (U+000B)** + that the contract's six-character set includes, so the explicit class is used, not `\s`), + replaced repeatedly until no match; a single `regexp.ReplaceAllString` pass suffices + for the same reason the contract records (`><` reintroduces no whitespace). +- **N3b** — remove every whitespace run anywhere (collapse to **nothing**, not to a space; the + contract's 2026-07-20 maintainer step): `regexp.MustCompile("[\t\n\v\f\r ]+").ReplaceAllString(s, "")`, + same six-character set. Applied at comparison to **both** the candidate's normalized output and + the loaded oracle, so the gate compares their non-whitespace bytes; any whitespace-only divergence + (run-length or presence/absence) passes. (N3b subsumes N3/N4 at comparison — they remain only to + produce the stored oracle's readable bytes.) +- **N4** — `strings.Trim(s, "\t\n\v\f\r ")` (the same six characters — not `strings.TrimSpace`, + which trims Unicode space and would exceed the closed definition). +- **N5** (encoded suite only) — the contract's five-character canonicalization table as a single + left-to-right scan without rescanning replacements: implemented as a hand-rolled scanner over + `&…;` candidates (match named spellings case-sensitively; numeric spellings per the contract's + leading-zero / case-insensitive-hex rules; map to `& < > " '`), not as + sequential `ReplaceAll` calls (which would rescan). Unit-tested against the contract's table + rows plus the no-rescan example (`&#39;` stays `&#39;`). + +## Controlled byte gate + +`internal/corpus/gate.go`: `AssertControlled(workloadID, suite, render func() string)` — +render, normalize (N1–N4, +N5 when `suite == "encoded"`), UTF-8 bytes, compare with the corpus +entry; on mismatch, fail with workload id, engine name, expected/actual byte lengths, first-diff +index, and a ±40-char / 120-char-window excerpt (the `ParityCheck.Describe` shape). The manifest +`hash` is also recomputed from the corpus file and checked, so a corrupted checkout is +distinguished from a divergent render. + +**Encoded security floor** (contract §controlled-track-gate 5): for encoded workloads the gate +additionally asserts, on the **un-normalized** candidate: zero occurrences of ``) + and byte-inspect what appears between fragments; record the exact output bytes. This is now an + **evidence-recording** probe, not a gate: whether templ emits a separator space or nothing, the + divergence is whitespace-only and passes via N3b (2026-07-20 ruling). It is retained so the + observed behavior is documented (and to confirm the divergence really is whitespace-only, not a + reordering or added non-whitespace byte). + +**Completion check:** `benchmarks/go/README.md` carries an "S1 results" section recording, per +probe, the command, the observed bytes (hex excerpt where relevant), and the verdict. + +### Expected outcome — pass (the analysis holds; this is the outcome that occurred) + +P1 byte-equal (with any whitespace-only difference reconciled by N3/N3b); P2 spellings all inside +N5; P3 style content whitespace-only-or-identical; P4 shows a whitespace-only boundary (space or +nothing) that N3b reconciles. **Path (taken):** the templ controlled ports were +authored for all eight workloads, `composed-page` first (it was the historically-flagged cell), +each gated before timing — the landed ports are byte-gate green at the pinned toolchain (F7). +No further feasibility checkpoints existed — S1 was the only one. + +### Contingency — a genuine non-whitespace divergence (did not fire; retained as the operative rule for re-runs) + +The exclusion path triggers **only** if a probe shows a divergence that is **not** whitespace-only +and that the pipeline cannot reconcile — for templ the sole such candidate is **P2 showing an +escaper spelling outside the N5 table** (a byte the untrusted-data alphabet did not already keep +out). A whitespace-only divergence never reaches this path (it passes via N3b, 2026-07-20 ruling). +A P1 non-whitespace failure additionally triggers a one-time re-check of the probe implementation +itself before any exclusion is recorded. If a genuine non-whitespace divergence is confirmed, the +contract's [exclusion policy](parity-contract-v2.md#exclusion-policy) +(Q1.2) is executed with this evidence-collection procedure, per affected workload: + +1. **Best-effort record.** Enumerate the authoring variants attempted (dense single-line, + adjacent-call, alternative element nesting — each with its `.templ` source committed under + `benchmarks/go/internal/spike/attempts/`), so "best-effort authoring" is demonstrable, not + asserted. +2. **Divergence record.** For the best variant: first-diff byte index, expected/actual lengths, + ±40-char excerpt of both sides (the `ParityCheck.Describe` shape), and the classification. The + classification must be `beyond whitespace` (non-whitespace) for this path to apply at all — a + whitespace-only divergence passes via N3b and never reaches here. Record the specific + non-whitespace bytes and the engine behavior responsible with its primary-source link (for the + only expected case, a P2 escaper spelling outside the N5 table). +3. **Evidence file.** Write `benchmarks/go/EXCLUSIONS.md` with one section per excluded cell + containing 1–2; the published report's controlled-track cell prints + `excluded — documented evidence` linking to it + (honest-reporting rule 6, [metrics-protocol.md](metrics-protocol.md#honest-reporting-rules)). +4. **Track consequences.** templ stays fully in the idiomatic track for the affected workloads + (idiomatic ports are unconditional scope); its controlled-track cells for unaffected + workloads still ship. No replacement engine enters without user sign-off (standing ruling). +5. **quicktemplate consequence.** Any templ controlled-track exclusion means templ is not + "fully green", so the quicktemplate conditional stretch (D10) is automatically not + triggered — no decision needed at that point; that consequence was decided in advance. +6. **Whitespace-only divergence never reaches this path (decision D13, CLOSED — option A).** + The former whitespace-only escalation is resolved: the 2026-07-20 maintainer ruling added the + uniform **N3b** whitespace-run collapse to contract v2, so **any** whitespace-only divergence + passes the controlled gate program-wide and is never a candidate for exclusion. If a probe's + divergence is classified whitespace-only in step 2, the cell **passes** — do not run the + exclusion procedure. This procedure applies only to a confirmed non-whitespace divergence. + +The expected outcome and the non-whitespace contingency were both fully specified in advance; +S1 confirmed and recorded evidence, it did not design. diff --git a/benchmarks/docs/golden-corpus.md b/benchmarks/docs/golden-corpus.md new file mode 100644 index 00000000..ea910efa --- /dev/null +++ b/benchmarks/docs/golden-corpus.md @@ -0,0 +1,268 @@ +# Golden oracle corpus — format, export, verification + +> Operational documentation of the completed cross-stack benchmark program — the contract the harnesses implement. Collapsed decision record: [cross-cutting-decisions.md § Program record — cross-stack benchmarks](../../docs/spec/common/cross-cutting-decisions.md#program-record--cross-stack-benchmarks-closed). + +Specifies +the on-disk corpus the phase 2–6 harnesses consume as their parity reference: location, +per-entry format and metadata, the export tool, the verification commands, and the +regeneration policy. The gate that consumes the corpus is defined in +[parity-contract-v2.md](parity-contract-v2.md); the workloads themselves in +[workloads.md](workloads.md). + +## Location and layout + +``` +benchmarks/dotnet/GoldenCorpus/ + README.md ← corpus contract summary + the composed-page fidelity note (verbatim) + manifest.json ← one entry per workload: length, hash, generating commit + composed-page.golden.html + trivial-substitution.golden.html + large-loop.golden.html + mixed-page.golden.html + conditional-heavy.golden.html + fragment-heavy.golden.html + fortunes-encoded.golden.html + encoded-loop.golden.html + composed-page.verify.json ← idiomatic-verifier definition (one per workload) + … (.verify.json for all eight) + fixtures/ + composed-page/ + nav.json ← structured nav model (amendment E20) — the single source the + non-.NET ports load; hash-recorded in the manifest +``` + +Rationale for the location: the corpus is produced by and re-verified against the code that +lives in `src/Heddle.Performance`, so it sits beside its generator; phases 2–6 read the files by +repo-relative path (`benchmarks/dotnet/GoldenCorpus/.golden.html`). No new top-level +repo directory is introduced (most reversible choice; the trigger to revisit is a phase 2–6 spec +demonstrating that its harness cannot conveniently reach into `src/` — then the corpus *moves* +in one ordinary versioned change, exactly as Q1.5 allows). + +## On-disk format + +Each `.golden.html` contains **the normalized oracle**: Heddle's rendered output for +the workload after the contract's **stored-form** normalization steps +(N1–N4 plus N5 for encoded entries — N5 is an identity transform on Heddle output, whose spellings +are already canonical), encoded as **UTF-8 without BOM, with no appended trailing newline** (N4's +trim means the content never ends in whitespace; the file's bytes are exactly the normalized +string's UTF-8 bytes). The stored form is **exactly v1's `TwinContent.Normalize` output** (N2/N3/N4; +the class itself was retired with the twin text fixtures under E22 — the pipeline lives in the +harness's `src/Gate/Normalize.cs`, unchanged) +plus N1's encoding rule and N5, so it is human-readable and byte-identical to the existing goldens. +N3b (the 2026-07-20 whitespace-run-collapse step) is **not** applied at export and is **not** baked +into the stored oracle — it is a comparison-time projection that removes every whitespace run from +**both** the loaded oracle and the candidate at gate time +([contract — N3b](parity-contract-v2.md#normalization-pipeline)). Storing the readable N1–N5 form +(not the whitespace-stripped projection) keeps the goldens diffable and their committed bytes +stable. + +Storing the normalized form (rather than raw render bytes) is deliberate: the gate everywhere is +`strip(normalize(candidate)) == strip(oracle)` (N3b applied symmetrically), so consumers apply the +N1–N5 pipeline **once, to their own output**, then remove whitespace from both their output and the +loaded oracle and compare — no consumer re-implements Heddle-side normalization. The raw render +remains reproducible at any time from the recorded generating commit. + +Git handling: a `.gitattributes` rule pins +`benchmarks/dotnet/GoldenCorpus/*.golden.html -text` (and `*.verify.json` / `manifest.json` +as `text eol=lf`), so no checkout smudging can +alter the golden bytes (per the +[testing-standards line-ending rule](../../docs/spec/common/testing-standards.md#fixtures-and-goldens); +`-text` rather than `eol=lf` because the goldens intentionally have no trailing newline and must +round-trip byte-exact). + +## Manifest + +`manifest.json` — UTF-8, LF, one object: + +```json +{ + "$schema": "manifest schema v1 (informal; fields below are normative)", + "generator": "Heddle.Performance export-corpus", + "entries": [ + { + "workload": "fortunes-encoded", + "suite": "encoded", + "file": "fortunes-encoded.golden.html", + "byteLength": 1234, + "hash": "sha256:9f2c…64-hex-lowercase…", + "generatingCommit": "0123456789abcdef0123456789abcdef01234567", + "generatedUtc": "2026-07-21T09:00:00Z" + } + ] +} +``` + +Field semantics (all required): + +| Field | Meaning | +|---|---| +| `workload` | The stable workload id ([workloads.md](workloads.md#the-set-at-a-glance)) | +| `suite` | `raw` or `encoded` — tells a consumer whether N5 applies to its own output | +| `file` | Corpus file name, relative to `GoldenCorpus/` | +| `byteLength` | Exact size in bytes of the corpus file | +| `hash` | `sha256:` + lowercase-hex SHA-256 of the corpus file bytes | +| `generatingCommit` | Full 40-hex SHA of the repo commit the export ran at (`git rev-parse HEAD`) | +| `generatedUtc` | Export timestamp, ISO-8601 UTC — informational only, never part of any gate | + +Entries are ordered by workload number (1–8). The manifest is regenerated whole on every export. + +> **Added (E20, 2026-08-08) — the `fixtures` section.** The manifest gains a second array, +> `fixtures`, recording every exported model fixture with the same fields as a golden entry +> (`workload`, `file` — relative to `GoldenCorpus/`, e.g. `fixtures/composed-page/nav.json` — +> `byteLength`, `hash`, `generatingCommit`, `generatedUtc`; no `suite`). Today it carries one +> entry: composed-page's structured navigation, serialized from `NavData` as UTF-8/LF, +> two-space-indented JSON with snake_case keys in declaration order (`menus` → `tabs` → +> `label`, `href`, `css`, `has_dropdown`, `dropdown_css`, `columns` → `sections` → `title`, +> `href`, `title_linked`, `links` → `label`, `href`; then `footer_columns`). Loaders that +> predate the section tolerate its presence (unknown-member-tolerant JSON parsing); the .NET +> loader models it explicitly and defaults it to empty for older manifests. + +## Export tool + +The export tool lives in `src/Heddle.Performance` (built net-new for the program; the +`Heddle.Tests` golden-file pattern was a precedent, not a shared mechanism). + +- **Entry point:** `dotnet run -c Release --project src/Heddle.Performance -f net10.0 -- export-corpus` + (a new verb in `Program.cs`, beside the existing `parity` verb). Optional flag `--allow-dirty`. +- **Implementation:** new `Runners/GoldenCorpus.cs` (internal static class) with a single + registry of the eight workloads: + `(string Id, string Suite, Func RenderHeddle)` — the render funcs reuse the existing + and new `*HeddleTest` runners. Export, per entry: render → normalize to the stored form + (`TwinContent.Normalize` = N2/N3/N4; encoded entries need no extra step, N5 is identity on Heddle + output) → UTF-8-encode (no BOM) → write `.golden.html` → compute SHA-256 → append manifest + entry. **N3b is deliberately not applied at export**: it is the gate's comparison-time whitespace + strip (applied to both sides at gate time), not a stored-form step, so the on-disk oracle stays + readable and byte-stable while the oracle and every candidate still pass through the identical + comparison ([contract — N3b](parity-contract-v2.md#normalization-pipeline)). Also writes every `.verify.json` from the check definitions in + `Runners/IdiomaticChecks.cs` (single source of truth in C#; the JSON is the exported, + cross-language-consumable form). +- **Added (E20):** the export additionally serializes the composed-page nav model to + `fixtures/composed-page/nav.json` and records it in the manifest's `fixtures` section (see + [Manifest](#manifest)); regeneration and review treat it exactly like a golden. +- **Commit stamping:** the tool runs `git rev-parse HEAD` and `git status --porcelain` + (`System.Diagnostics.Process`, working directory = repo root). A non-empty status output means + a dirty tree: the tool **refuses to export** and exits 1 with + `export-corpus: working tree is dirty; commit first or pass --allow-dirty.` With + `--allow-dirty` it exports and records `"+dirty"` as `generatingCommit` (useful mid-work, + never committed — a committed `+dirty` manifest fails review by inspection and `verify-corpus` + prints a warning line for it). +- **Determinism requirement:** exporting twice at the same commit produces byte-identical + corpus files and identical manifests except `generatedUtc` (plan success criterion + "regenerating any golden output at its recorded commit reproduces the committed bytes + exactly" — checkable because every model is a deterministic static construction, and the + render path has no time/random/locale dependence; all numeric formatting in models is + invariant-culture `int` formatting). + +## Verification + +`dotnet run -c Release --project src/Heddle.Performance -f net10.0 -- verify-corpus` — a second +new verb, exit 0 iff all checks pass: + +1. **Freshness** — for each of the eight entries: render Heddle live, normalize to the stored form + (N1–N5, `TwinContent.Normalize` + N5; N3b is not a stored-form step), UTF-8-encode, compare + byte-for-byte with the committed corpus file; also recompute SHA-256 and compare with + the manifest. Prints `[PASS]`/`[FAIL] …` lines in the `ParityCheck.Report` style + (first-diff index + excerpt on failure). **Added (E20):** the same discipline covers the + `fixtures` section — each fixture file is re-serialized live from its model source + (`nav.json` from `NavData`), compared byte-for-byte with the committed file, and its + hash/length re-checked against the manifest entry. +2. **Verifier calibration** — for each workload: run the idiomatic verifier + (`IdiomaticChecks`) against the corpus entry (must accept), then against its applicable + synthesized corruptions — two per raw workload, three per encoded workload — each of which + must be rejected with the correct failing check kind: + - *removed row* — delete the first occurrence of the workload's row-level marker segment + (per-workload substring pinned in `IdiomaticChecks`, e.g. the full first `…` of + `large-loop`). The two rowless raw anchors pin a whole segment instead: **composed-page** + deletes its `SectionSocial` marker fragment (trips the ordered-`markers` check for the + missing fragment) *(amended (E20): composed-page now deletes the SLIDER fragment the page + body splices at the layout's `@out()` slot — so an idiomatic implementation with an empty + body fails — and fragment-heavy deletes the full first `tile` section, computed from the + model)*; **trivial-substitution** deletes its `HB-2001` sku value (trips the + `values` check, `HB-2001` → 1 dropping to 0); + - *reordered section* — swap the first two ordered row/section segments. For the two rowless + raw anchors the pinned pair is: **composed-page** — swap the leading `SectionMeta` and + `SectionSocial` marker fragments *(amended (E20): swap the wholesale-only and retail-only + mega-menu anchors — `/product/coming-soon-paleo-pork` / `/products/paleo-friendly-pork`)*; + **trivial-substitution** — swap the `class="sku"` and + `class="rating"` marker segments. Either swap trips the markers-in-order check; + - *unescaped payload* (encoded workloads only) — replace the first `<script>alert(` + with ``, `` | — | +| trivial-substitution | `Heddle Handbook` → 1; `HB-2001` → 1; `A concise field guide to the engine.` → 1; `4.8` → 1 | `
`, `

`, `class="sku"`, `class="rating"`, `

` | — | +| large-loop | `row-00` → 1; `row-49994999` → 1; `row-` → 5000 | `row-0`, `row-2500`, `row-4999` | — | +| mixed-page | `Mercantile - Catalog` → 1; `Autumn hardware sale` → 1; `Product 01` → 1; `Product 36` → 1; `MX-1036` → 1; `
` → 36; `

On sale

` → 12; `Free shipping on orders over 60.` → 1 | ``, `
`, `class="hero"`, `class="grid"`, `
`, `` | — | +| conditional-heavy | `unit-000` → 1; `unit-199` → 1; `
  • ` → 200; `bronze` → 50; `platinum` → 50; `` → 100; `active` → 160 | `
      `, `unit-000`, `unit-100`, `unit-199`, `
    ` | — | +| fragment-heavy *(amended E20 — four dispatched kinds)* | `
    ` → 12; `
    ` → 12; `
    ` → 12; `
    ` → 12; `` → 12 and `

    ` → 12 (proof the card's nested badge/price partials ran); `item-00` → 1; `item-47` → 1 | `

    `, `item-00`, `item-24`, `item-47`, `
    ` | — | +| fortunes-encoded | each of the 12 escaped messages → 1 (escaped form of each pinned string; ten are identical to their raw form) **except** rows 3 and 11, whose text-context quote entities are weakened to quote-agnostic substrings (see the amendment below): row 3 → `A computer scientist is someone who fixes things that aren` → 1; row 11 → `<script>alert(` → 1 and `);</script>` → 1; `` → 12 (the header row uses `` and is not counted) | ``, ``, ``, `フレームワークのベンチマーク`, `
    idmessage
    ` | forbidden: `` | +| 12 | `フレームワークのベンチマーク` | + +Row 11 is **the XSS payload string** (identical to TechEmpower's) and row 12 **the Japanese +string** (identical to TechEmpower's). The em dashes in rows 4 and 8 are U+2014 — BMP, +≥ U+0100, inside the untrusted-data alphabet, and pass through every configured escaper +unescaped (spike B: `WebUtility.HtmlEncode` and every twin escape filter leave BMP ≥ U+0100 +alone). Apostrophes (rows 3) escape to the canonical `'` on every configured path. + +### Heddle template — `TestTemplates/fortunes-encoded.heddle` + +Compiled with `OutputProfile = OutputProfile.Html` (text-context substitutions run +`HtmlEncodedRenderer` → `WebUtility.HtmlEncode`): + +```heddle +Fortunes@list(Rows){{}}
    idmessage
    @(Id)@(Message)
    +``` + +(The skeleton mirrors TechEmpower's required Fortunes response markup.) + +### Twin templates + +| Engine | Row body | +|---|---| +| Fluid | `{{ r.id }}{{ r.message \| escape }}` | +| DotLiquid | `{{ r.id }}{{ r.message \| escape }}` | +| Scriban | `{{ r.id }}{{ r.message \| html.escape }}` | +| Handlebars | `{{id}}{{message}}` — double-mustache, under `FiveEntityTextEncoder` (phase 1 D3) | + +`id` is an int and never contains escapable characters; escaping it (Handlebars double-mustache +does) is a no-op, so the un-filtered `{{ r.id }}` on the other twins cannot diverge. + +### Expected output characteristics + +- Exactly one `` with a header row and 12 data rows in model order. +- The escaped XSS form appears exactly once: + `<script>alert("This should not be displayed in a browser alert box.");</script>`. +- The raw substring `
    holiday shipping
    \ No newline at end of file diff --git a/benchmarks/dotnet/GoldenCorpus/composed-page.verify.json b/benchmarks/dotnet/GoldenCorpus/composed-page.verify.json new file mode 100644 index 00000000..b6ea1462 --- /dev/null +++ b/benchmarks/dotnet/GoldenCorpus/composed-page.verify.json @@ -0,0 +1,28 @@ +{ + "workload": "composed-page", + "suite": "raw", + "values": [ + { "text": "Title", "count": 1 }, + { "text": "
  • ", "count": 36 }, + { "text": "Need Help?", "count": 1 }, + { "text": "
  • Privacy Policy
  • ", "count": 1 } + ], + "markers": [ + "", + "Title", + "xmas-shipping-alert-1.jpg", + "id=\"search-area-form\"", + "/content/wholesale-promotions", + "/content/request-catalog\">Catalog", + ">Shop All Products", + "/product/coming-soon-paleo-pork", + "/products/paleo-friendly-pork", + "homebtmbanners/gluten-hp.jpg", + "/Assets/images/seeourcatalog.jpg", + "", + "" + ], + "forbidden": [], + "required": [] +} diff --git a/benchmarks/dotnet/GoldenCorpus/conditional-heavy.golden.html b/benchmarks/dotnet/GoldenCorpus/conditional-heavy.golden.html new file mode 100644 index 00000000..484871d2 --- /dev/null +++ b/benchmarks/dotnet/GoldenCorpus/conditional-heavy.golden.html @@ -0,0 +1 @@ +
    • bronzeunit-000note 0
    • silverunit-001active
    • goldunit-002note 2active
    • platinumunit-003active
    • bronzeunit-004note 4active
    • silverunit-005
    • goldunit-006note 6active
    • platinumunit-007active
    • bronzeunit-008note 8active
    • silverunit-009active
    • goldunit-010note 10
    • platinumunit-011active
    • bronzeunit-012note 12active
    • silverunit-013active
    • goldunit-014note 14active
    • platinumunit-015
    • bronzeunit-016note 16active
    • silverunit-017active
    • goldunit-018note 18active
    • platinumunit-019active
    • bronzeunit-020note 20
    • silverunit-021active
    • goldunit-022note 22active
    • platinumunit-023active
    • bronzeunit-024note 24active
    • silverunit-025
    • goldunit-026note 26active
    • platinumunit-027active
    • bronzeunit-028note 28active
    • silverunit-029active
    • goldunit-030note 30
    • platinumunit-031active
    • bronzeunit-032note 32active
    • silverunit-033active
    • goldunit-034note 34active
    • platinumunit-035
    • bronzeunit-036note 36active
    • silverunit-037active
    • goldunit-038note 38active
    • platinumunit-039active
    • bronzeunit-040note 40
    • silverunit-041active
    • goldunit-042note 42active
    • platinumunit-043active
    • bronzeunit-044note 44active
    • silverunit-045
    • goldunit-046note 46active
    • platinumunit-047active
    • bronzeunit-048note 48active
    • silverunit-049active
    • goldunit-050note 50
    • platinumunit-051active
    • bronzeunit-052note 52active
    • silverunit-053active
    • goldunit-054note 54active
    • platinumunit-055
    • bronzeunit-056note 56active
    • silverunit-057active
    • goldunit-058note 58active
    • platinumunit-059active
    • bronzeunit-060note 60
    • silverunit-061active
    • goldunit-062note 62active
    • platinumunit-063active
    • bronzeunit-064note 64active
    • silverunit-065
    • goldunit-066note 66active
    • platinumunit-067active
    • bronzeunit-068note 68active
    • silverunit-069active
    • goldunit-070note 70
    • platinumunit-071active
    • bronzeunit-072note 72active
    • silverunit-073active
    • goldunit-074note 74active
    • platinumunit-075
    • bronzeunit-076note 76active
    • silverunit-077active
    • goldunit-078note 78active
    • platinumunit-079active
    • bronzeunit-080note 80
    • silverunit-081active
    • goldunit-082note 82active
    • platinumunit-083active
    • bronzeunit-084note 84active
    • silverunit-085
    • goldunit-086note 86active
    • platinumunit-087active
    • bronzeunit-088note 88active
    • silverunit-089active
    • goldunit-090note 90
    • platinumunit-091active
    • bronzeunit-092note 92active
    • silverunit-093active
    • goldunit-094note 94active
    • platinumunit-095
    • bronzeunit-096note 96active
    • silverunit-097active
    • goldunit-098note 98active
    • platinumunit-099active
    • bronzeunit-100note 100
    • silverunit-101active
    • goldunit-102note 102active
    • platinumunit-103active
    • bronzeunit-104note 104active
    • silverunit-105
    • goldunit-106note 106active
    • platinumunit-107active
    • bronzeunit-108note 108active
    • silverunit-109active
    • goldunit-110note 110
    • platinumunit-111active
    • bronzeunit-112note 112active
    • silverunit-113active
    • goldunit-114note 114active
    • platinumunit-115
    • bronzeunit-116note 116active
    • silverunit-117active
    • goldunit-118note 118active
    • platinumunit-119active
    • bronzeunit-120note 120
    • silverunit-121active
    • goldunit-122note 122active
    • platinumunit-123active
    • bronzeunit-124note 124active
    • silverunit-125
    • goldunit-126note 126active
    • platinumunit-127active
    • bronzeunit-128note 128active
    • silverunit-129active
    • goldunit-130note 130
    • platinumunit-131active
    • bronzeunit-132note 132active
    • silverunit-133active
    • goldunit-134note 134active
    • platinumunit-135
    • bronzeunit-136note 136active
    • silverunit-137active
    • goldunit-138note 138active
    • platinumunit-139active
    • bronzeunit-140note 140
    • silverunit-141active
    • goldunit-142note 142active
    • platinumunit-143active
    • bronzeunit-144note 144active
    • silverunit-145
    • goldunit-146note 146active
    • platinumunit-147active
    • bronzeunit-148note 148active
    • silverunit-149active
    • goldunit-150note 150
    • platinumunit-151active
    • bronzeunit-152note 152active
    • silverunit-153active
    • goldunit-154note 154active
    • platinumunit-155
    • bronzeunit-156note 156active
    • silverunit-157active
    • goldunit-158note 158active
    • platinumunit-159active
    • bronzeunit-160note 160
    • silverunit-161active
    • goldunit-162note 162active
    • platinumunit-163active
    • bronzeunit-164note 164active
    • silverunit-165
    • goldunit-166note 166active
    • platinumunit-167active
    • bronzeunit-168note 168active
    • silverunit-169active
    • goldunit-170note 170
    • platinumunit-171active
    • bronzeunit-172note 172active
    • silverunit-173active
    • goldunit-174note 174active
    • platinumunit-175
    • bronzeunit-176note 176active
    • silverunit-177active
    • goldunit-178note 178active
    • platinumunit-179active
    • bronzeunit-180note 180
    • silverunit-181active
    • goldunit-182note 182active
    • platinumunit-183active
    • bronzeunit-184note 184active
    • silverunit-185
    • goldunit-186note 186active
    • platinumunit-187active
    • bronzeunit-188note 188active
    • silverunit-189active
    • goldunit-190note 190
    • platinumunit-191active
    • bronzeunit-192note 192active
    • silverunit-193active
    • goldunit-194note 194active
    • platinumunit-195
    • bronzeunit-196note 196active
    • silverunit-197active
    • goldunit-198note 198active
    • platinumunit-199active
    \ No newline at end of file diff --git a/benchmarks/dotnet/GoldenCorpus/conditional-heavy.verify.json b/benchmarks/dotnet/GoldenCorpus/conditional-heavy.verify.json new file mode 100644 index 00000000..2d1c7d99 --- /dev/null +++ b/benchmarks/dotnet/GoldenCorpus/conditional-heavy.verify.json @@ -0,0 +1,22 @@ +{ + "workload": "conditional-heavy", + "suite": "raw", + "values": [ + { "text": "unit-000", "count": 1 }, + { "text": "unit-199", "count": 1 }, + { "text": "
  • ", "count": 200 }, + { "text": "bronze", "count": 50 }, + { "text": "platinum", "count": 50 }, + { "text": "", "count": 100 }, + { "text": "active", "count": 160 } + ], + "markers": [ + "
      ", + "unit-000", + "unit-100", + "unit-199", + "
    " + ], + "forbidden": [], + "required": [] +} diff --git a/benchmarks/dotnet/GoldenCorpus/encoded-loop.golden.html b/benchmarks/dotnet/GoldenCorpus/encoded-loop.golden.html new file mode 100644 index 00000000..e454920d --- /dev/null +++ b/benchmarks/dotnet/GoldenCorpus/encoded-loop.golden.html @@ -0,0 +1 @@ +
  • item <0> & "co"'q' & <angle> "d" こんにちは 0
    item <1> & "co"'q' & <angle> "d" こんにちは 1
    item <2> & "co"'q' & <angle> "d" こんにちは 2
    item <3> & "co"'q' & <angle> "d" こんにちは 3
    item <4> & "co"'q' & <angle> "d" こんにちは 4
    item <5> & "co"'q' & <angle> "d" こんにちは 5
    item <6> & "co"'q' & <angle> "d" こんにちは 6
    item <7> & "co"'q' & <angle> "d" こんにちは 7
    item <8> & "co"'q' & <angle> "d" こんにちは 8
    item <9> & "co"'q' & <angle> "d" こんにちは 9
    item <10> & "co"'q' & <angle> "d" こんにちは 10
    item <11> & "co"'q' & <angle> "d" こんにちは 11
    item <12> & "co"'q' & <angle> "d" こんにちは 12
    item <13> & "co"'q' & <angle> "d" こんにちは 13
    item <14> & "co"'q' & <angle> "d" こんにちは 14
    item <15> & "co"'q' & <angle> "d" こんにちは 15
    item <16> & "co"'q' & <angle> "d" こんにちは 16
    item <17> & "co"'q' & <angle> "d" こんにちは 17
    item <18> & "co"'q' & <angle> "d" こんにちは 18
    item <19> & "co"'q' & <angle> "d" こんにちは 19
    item <20> & "co"'q' & <angle> "d" こんにちは 20
    item <21> & "co"'q' & <angle> "d" こんにちは 21
    item <22> & "co"'q' & <angle> "d" こんにちは 22
    item <23> & "co"'q' & <angle> "d" こんにちは 23
    item <24> & "co"'q' & <angle> "d" こんにちは 24
    item <25> & "co"'q' & <angle> "d" こんにちは 25
    item <26> & "co"'q' & <angle> "d" こんにちは 26
    item <27> & "co"'q' & <angle> "d" こんにちは 27
    item <28> & "co"'q' & <angle> "d" こんにちは 28
    item <29> & "co"'q' & <angle> "d" こんにちは 29
    item <30> & "co"'q' & <angle> "d" こんにちは 30
    item <31> & "co"'q' & <angle> "d" こんにちは 31
    item <32> & "co"'q' & <angle> "d" こんにちは 32
    item <33> & "co"'q' & <angle> "d" こんにちは 33
    item <34> & "co"'q' & <angle> "d" こんにちは 34
    item <35> & "co"'q' & <angle> "d" こんにちは 35
    item <36> & "co"'q' & <angle> "d" こんにちは 36
    item <37> & "co"'q' & <angle> "d" こんにちは 37
    item <38> & "co"'q' & <angle> "d" こんにちは 38
    item <39> & "co"'q' & <angle> "d" こんにちは 39
    item <40> & "co"'q' & <angle> "d" こんにちは 40
    item <41> & "co"'q' & <angle> "d" こんにちは 41
    item <42> & "co"'q' & <angle> "d" こんにちは 42
    item <43> & "co"'q' & <angle> "d" こんにちは 43
    item <44> & "co"'q' & <angle> "d" こんにちは 44
    item <45> & "co"'q' & <angle> "d" こんにちは 45
    item <46> & "co"'q' & <angle> "d" こんにちは 46
    item <47> & "co"'q' & <angle> "d" こんにちは 47
    item <48> & "co"'q' & <angle> "d" こんにちは 48
    item <49> & "co"'q' & <angle> "d" こんにちは 49
    item <50> & "co"'q' & <angle> "d" こんにちは 50
    item <51> & "co"'q' & <angle> "d" こんにちは 51
    item <52> & "co"'q' & <angle> "d" こんにちは 52
    item <53> & "co"'q' & <angle> "d" こんにちは 53
    item <54> & "co"'q' & <angle> "d" こんにちは 54
    item <55> & "co"'q' & <angle> "d" こんにちは 55
    item <56> & "co"'q' & <angle> "d" こんにちは 56
    item <57> & "co"'q' & <angle> "d" こんにちは 57
    item <58> & "co"'q' & <angle> "d" こんにちは 58
    item <59> & "co"'q' & <angle> "d" こんにちは 59
    item <60> & "co"'q' & <angle> "d" こんにちは 60
    item <61> & "co"'q' & <angle> "d" こんにちは 61
    item <62> & "co"'q' & <angle> "d" こんにちは 62
    item <63> & "co"'q' & <angle> "d" こんにちは 63
    item <64> & "co"'q' & <angle> "d" こんにちは 64
    item <65> & "co"'q' & <angle> "d" こんにちは 65
    item <66> & "co"'q' & <angle> "d" こんにちは 66
    item <67> & "co"'q' & <angle> "d" こんにちは 67
    item <68> & "co"'q' & <angle> "d" こんにちは 68
    item <69> & "co"'q' & <angle> "d" こんにちは 69
    item <70> & "co"'q' & <angle> "d" こんにちは 70
    item <71> & "co"'q' & <angle> "d" こんにちは 71
    item <72> & "co"'q' & <angle> "d" こんにちは 72
    item <73> & "co"'q' & <angle> "d" こんにちは 73
    item <74> & "co"'q' & <angle> "d" こんにちは 74
    item <75> & "co"'q' & <angle> "d" こんにちは 75
    item <76> & "co"'q' & <angle> "d" こんにちは 76
    item <77> & "co"'q' & <angle> "d" こんにちは 77
    item <78> & "co"'q' & <angle> "d" こんにちは 78
    item <79> & "co"'q' & <angle> "d" こんにちは 79
    item <80> & "co"'q' & <angle> "d" こんにちは 80
    item <81> & "co"'q' & <angle> "d" こんにちは 81
    item <82> & "co"'q' & <angle> "d" こんにちは 82
    item <83> & "co"'q' & <angle> "d" こんにちは 83
    item <84> & "co"'q' & <angle> "d" こんにちは 84
    item <85> & "co"'q' & <angle> "d" こんにちは 85
    item <86> & "co"'q' & <angle> "d" こんにちは 86
    item <87> & "co"'q' & <angle> "d" こんにちは 87
    item <88> & "co"'q' & <angle> "d" こんにちは 88
    item <89> & "co"'q' & <angle> "d" こんにちは 89
    item <90> & "co"'q' & <angle> "d" こんにちは 90
    item <91> & "co"'q' & <angle> "d" こんにちは 91
    item <92> & "co"'q' & <angle> "d" こんにちは 92
    item <93> & "co"'q' & <angle> "d" こんにちは 93
    item <94> & "co"'q' & <angle> "d" こんにちは 94
    item <95> & "co"'q' & <angle> "d" こんにちは 95
    item <96> & "co"'q' & <angle> "d" こんにちは 96
    item <97> & "co"'q' & <angle> "d" こんにちは 97
    item <98> & "co"'q' & <angle> "d" こんにちは 98
    item <99> & "co"'q' & <angle> "d" こんにちは 99
    item <100> & "co"'q' & <angle> "d" こんにちは 100
    item <101> & "co"'q' & <angle> "d" こんにちは 101
    item <102> & "co"'q' & <angle> "d" こんにちは 102
    item <103> & "co"'q' & <angle> "d" こんにちは 103
    item <104> & "co"'q' & <angle> "d" こんにちは 104
    item <105> & "co"'q' & <angle> "d" こんにちは 105
    item <106> & "co"'q' & <angle> "d" こんにちは 106
    item <107> & "co"'q' & <angle> "d" こんにちは 107
    item <108> & "co"'q' & <angle> "d" こんにちは 108
    item <109> & "co"'q' & <angle> "d" こんにちは 109
    item <110> & "co"'q' & <angle> "d" こんにちは 110
    item <111> & "co"'q' & <angle> "d" こんにちは 111
    item <112> & "co"'q' & <angle> "d" こんにちは 112
    item <113> & "co"'q' & <angle> "d" こんにちは 113
    item <114> & "co"'q' & <angle> "d" こんにちは 114
    item <115> & "co"'q' & <angle> "d" こんにちは 115
    item <116> & "co"'q' & <angle> "d" こんにちは 116
    item <117> & "co"'q' & <angle> "d" こんにちは 117
    item <118> & "co"'q' & <angle> "d" こんにちは 118
    item <119> & "co"'q' & <angle> "d" こんにちは 119
    item <120> & "co"'q' & <angle> "d" こんにちは 120
    item <121> & "co"'q' & <angle> "d" こんにちは 121
    item <122> & "co"'q' & <angle> "d" こんにちは 122
    item <123> & "co"'q' & <angle> "d" こんにちは 123
    item <124> & "co"'q' & <angle> "d" こんにちは 124
    item <125> & "co"'q' & <angle> "d" こんにちは 125
    item <126> & "co"'q' & <angle> "d" こんにちは 126
    item <127> & "co"'q' & <angle> "d" こんにちは 127
    item <128> & "co"'q' & <angle> "d" こんにちは 128
    item <129> & "co"'q' & <angle> "d" こんにちは 129
    item <130> & "co"'q' & <angle> "d" こんにちは 130
    item <131> & "co"'q' & <angle> "d" こんにちは 131
    item <132> & "co"'q' & <angle> "d" こんにちは 132
    item <133> & "co"'q' & <angle> "d" こんにちは 133
    item <134> & "co"'q' & <angle> "d" こんにちは 134
    item <135> & "co"'q' & <angle> "d" こんにちは 135
    item <136> & "co"'q' & <angle> "d" こんにちは 136
    item <137> & "co"'q' & <angle> "d" こんにちは 137
    item <138> & "co"'q' & <angle> "d" こんにちは 138
    item <139> & "co"'q' & <angle> "d" こんにちは 139
    item <140> & "co"'q' & <angle> "d" こんにちは 140
    item <141> & "co"'q' & <angle> "d" こんにちは 141
    item <142> & "co"'q' & <angle> "d" こんにちは 142
    item <143> & "co"'q' & <angle> "d" こんにちは 143
    item <144> & "co"'q' & <angle> "d" こんにちは 144
    item <145> & "co"'q' & <angle> "d" こんにちは 145
    item <146> & "co"'q' & <angle> "d" こんにちは 146
    item <147> & "co"'q' & <angle> "d" こんにちは 147
    item <148> & "co"'q' & <angle> "d" こんにちは 148
    item <149> & "co"'q' & <angle> "d" こんにちは 149
    item <150> & "co"'q' & <angle> "d" こんにちは 150
    item <151> & "co"'q' & <angle> "d" こんにちは 151
    item <152> & "co"'q' & <angle> "d" こんにちは 152
    item <153> & "co"'q' & <angle> "d" こんにちは 153
    item <154> & "co"'q' & <angle> "d" こんにちは 154
    item <155> & "co"'q' & <angle> "d" こんにちは 155
    item <156> & "co"'q' & <angle> "d" こんにちは 156
    item <157> & "co"'q' & <angle> "d" こんにちは 157
    item <158> & "co"'q' & <angle> "d" こんにちは 158
    item <159> & "co"'q' & <angle> "d" こんにちは 159
    item <160> & "co"'q' & <angle> "d" こんにちは 160
    item <161> & "co"'q' & <angle> "d" こんにちは 161
    item <162> & "co"'q' & <angle> "d" こんにちは 162
    item <163> & "co"'q' & <angle> "d" こんにちは 163
    item <164> & "co"'q' & <angle> "d" こんにちは 164
    item <165> & "co"'q' & <angle> "d" こんにちは 165
    item <166> & "co"'q' & <angle> "d" こんにちは 166
    item <167> & "co"'q' & <angle> "d" こんにちは 167
    item <168> & "co"'q' & <angle> "d" こんにちは 168
    item <169> & "co"'q' & <angle> "d" こんにちは 169
    item <170> & "co"'q' & <angle> "d" こんにちは 170
    item <171> & "co"'q' & <angle> "d" こんにちは 171
    item <172> & "co"'q' & <angle> "d" こんにちは 172
    item <173> & "co"'q' & <angle> "d" こんにちは 173
    item <174> & "co"'q' & <angle> "d" こんにちは 174
    item <175> & "co"'q' & <angle> "d" こんにちは 175
    item <176> & "co"'q' & <angle> "d" こんにちは 176
    item <177> & "co"'q' & <angle> "d" こんにちは 177
    item <178> & "co"'q' & <angle> "d" こんにちは 178
    item <179> & "co"'q' & <angle> "d" こんにちは 179
    item <180> & "co"'q' & <angle> "d" こんにちは 180
    item <181> & "co"'q' & <angle> "d" こんにちは 181
    item <182> & "co"'q' & <angle> "d" こんにちは 182
    item <183> & "co"'q' & <angle> "d" こんにちは 183
    item <184> & "co"'q' & <angle> "d" こんにちは 184
    item <185> & "co"'q' & <angle> "d" こんにちは 185
    item <186> & "co"'q' & <angle> "d" こんにちは 186
    item <187> & "co"'q' & <angle> "d" こんにちは 187
    item <188> & "co"'q' & <angle> "d" こんにちは 188
    item <189> & "co"'q' & <angle> "d" こんにちは 189
    item <190> & "co"'q' & <angle> "d" こんにちは 190
    item <191> & "co"'q' & <angle> "d" こんにちは 191
    item <192> & "co"'q' & <angle> "d" こんにちは 192
    item <193> & "co"'q' & <angle> "d" こんにちは 193
    item <194> & "co"'q' & <angle> "d" こんにちは 194
    item <195> & "co"'q' & <angle> "d" こんにちは 195
    item <196> & "co"'q' & <angle> "d" こんにちは 196
    item <197> & "co"'q' & <angle> "d" こんにちは 197
    item <198> & "co"'q' & <angle> "d" こんにちは 198
    item <199> & "co"'q' & <angle> "d" こんにちは 199
    item <200> & "co"'q' & <angle> "d" こんにちは 200
    item <201> & "co"'q' & <angle> "d" こんにちは 201
    item <202> & "co"'q' & <angle> "d" こんにちは 202
    item <203> & "co"'q' & <angle> "d" こんにちは 203
    item <204> & "co"'q' & <angle> "d" こんにちは 204
    item <205> & "co"'q' & <angle> "d" こんにちは 205
    item <206> & "co"'q' & <angle> "d" こんにちは 206
    item <207> & "co"'q' & <angle> "d" こんにちは 207
    item <208> & "co"'q' & <angle> "d" こんにちは 208
    item <209> & "co"'q' & <angle> "d" こんにちは 209
    item <210> & "co"'q' & <angle> "d" こんにちは 210
    item <211> & "co"'q' & <angle> "d" こんにちは 211
    item <212> & "co"'q' & <angle> "d" こんにちは 212
    item <213> & "co"'q' & <angle> "d" こんにちは 213
    item <214> & "co"'q' & <angle> "d" こんにちは 214
    item <215> & "co"'q' & <angle> "d" こんにちは 215
    item <216> & "co"'q' & <angle> "d" こんにちは 216
    item <217> & "co"'q' & <angle> "d" こんにちは 217
    item <218> & "co"'q' & <angle> "d" こんにちは 218
    item <219> & "co"'q' & <angle> "d" こんにちは 219
    item <220> & "co"'q' & <angle> "d" こんにちは 220
    item <221> & "co"'q' & <angle> "d" こんにちは 221
    item <222> & "co"'q' & <angle> "d" こんにちは 222
    item <223> & "co"'q' & <angle> "d" こんにちは 223
    item <224> & "co"'q' & <angle> "d" こんにちは 224
    item <225> & "co"'q' & <angle> "d" こんにちは 225
    item <226> & "co"'q' & <angle> "d" こんにちは 226
    item <227> & "co"'q' & <angle> "d" こんにちは 227
    item <228> & "co"'q' & <angle> "d" こんにちは 228
    item <229> & "co"'q' & <angle> "d" こんにちは 229
    item <230> & "co"'q' & <angle> "d" こんにちは 230
    item <231> & "co"'q' & <angle> "d" こんにちは 231
    item <232> & "co"'q' & <angle> "d" こんにちは 232
    item <233> & "co"'q' & <angle> "d" こんにちは 233
    item <234> & "co"'q' & <angle> "d" こんにちは 234
    item <235> & "co"'q' & <angle> "d" こんにちは 235
    item <236> & "co"'q' & <angle> "d" こんにちは 236
    item <237> & "co"'q' & <angle> "d" こんにちは 237
    item <238> & "co"'q' & <angle> "d" こんにちは 238
    item <239> & "co"'q' & <angle> "d" こんにちは 239
    item <240> & "co"'q' & <angle> "d" こんにちは 240
    item <241> & "co"'q' & <angle> "d" こんにちは 241
    item <242> & "co"'q' & <angle> "d" こんにちは 242
    item <243> & "co"'q' & <angle> "d" こんにちは 243
    item <244> & "co"'q' & <angle> "d" こんにちは 244
    item <245> & "co"'q' & <angle> "d" こんにちは 245
    item <246> & "co"'q' & <angle> "d" こんにちは 246
    item <247> & "co"'q' & <angle> "d" こんにちは 247
    item <248> & "co"'q' & <angle> "d" こんにちは 248
    item <249> & "co"'q' & <angle> "d" こんにちは 249
    item <250> & "co"'q' & <angle> "d" こんにちは 250
    item <251> & "co"'q' & <angle> "d" こんにちは 251
    item <252> & "co"'q' & <angle> "d" こんにちは 252
    item <253> & "co"'q' & <angle> "d" こんにちは 253
    item <254> & "co"'q' & <angle> "d" こんにちは 254
    item <255> & "co"'q' & <angle> "d" こんにちは 255
    item <256> & "co"'q' & <angle> "d" こんにちは 256
    item <257> & "co"'q' & <angle> "d" こんにちは 257
    item <258> & "co"'q' & <angle> "d" こんにちは 258
    item <259> & "co"'q' & <angle> "d" こんにちは 259
    item <260> & "co"'q' & <angle> "d" こんにちは 260
    item <261> & "co"'q' & <angle> "d" こんにちは 261
    item <262> & "co"'q' & <angle> "d" こんにちは 262
    item <263> & "co"'q' & <angle> "d" こんにちは 263
    item <264> & "co"'q' & <angle> "d" こんにちは 264
    item <265> & "co"'q' & <angle> "d" こんにちは 265
    item <266> & "co"'q' & <angle> "d" こんにちは 266
    item <267> & "co"'q' & <angle> "d" こんにちは 267
    item <268> & "co"'q' & <angle> "d" こんにちは 268
    item <269> & "co"'q' & <angle> "d" こんにちは 269
    item <270> & "co"'q' & <angle> "d" こんにちは 270
    item <271> & "co"'q' & <angle> "d" こんにちは 271
    item <272> & "co"'q' & <angle> "d" こんにちは 272
    item <273> & "co"'q' & <angle> "d" こんにちは 273
    item <274> & "co"'q' & <angle> "d" こんにちは 274
    item <275> & "co"'q' & <angle> "d" こんにちは 275
    item <276> & "co"'q' & <angle> "d" こんにちは 276
    item <277> & "co"'q' & <angle> "d" こんにちは 277
    item <278> & "co"'q' & <angle> "d" こんにちは 278
    item <279> & "co"'q' & <angle> "d" こんにちは 279
    item <280> & "co"'q' & <angle> "d" こんにちは 280
    item <281> & "co"'q' & <angle> "d" こんにちは 281
    item <282> & "co"'q' & <angle> "d" こんにちは 282
    item <283> & "co"'q' & <angle> "d" こんにちは 283
    item <284> & "co"'q' & <angle> "d" こんにちは 284
    item <285> & "co"'q' & <angle> "d" こんにちは 285
    item <286> & "co"'q' & <angle> "d" こんにちは 286
    item <287> & "co"'q' & <angle> "d" こんにちは 287
    item <288> & "co"'q' & <angle> "d" こんにちは 288
    item <289> & "co"'q' & <angle> "d" こんにちは 289
    item <290> & "co"'q' & <angle> "d" こんにちは 290
    item <291> & "co"'q' & <angle> "d" こんにちは 291
    item <292> & "co"'q' & <angle> "d" こんにちは 292
    item <293> & "co"'q' & <angle> "d" こんにちは 293
    item <294> & "co"'q' & <angle> "d" こんにちは 294
    item <295> & "co"'q' & <angle> "d" こんにちは 295
    item <296> & "co"'q' & <angle> "d" こんにちは 296
    item <297> & "co"'q' & <angle> "d" こんにちは 297
    item <298> & "co"'q' & <angle> "d" こんにちは 298
    item <299> & "co"'q' & <angle> "d" こんにちは 299
    item <300> & "co"'q' & <angle> "d" こんにちは 300
    item <301> & "co"'q' & <angle> "d" こんにちは 301
    item <302> & "co"'q' & <angle> "d" こんにちは 302
    item <303> & "co"'q' & <angle> "d" こんにちは 303
    item <304> & "co"'q' & <angle> "d" こんにちは 304
    item <305> & "co"'q' & <angle> "d" こんにちは 305
    item <306> & "co"'q' & <angle> "d" こんにちは 306
    item <307> & "co"'q' & <angle> "d" こんにちは 307
    item <308> & "co"'q' & <angle> "d" こんにちは 308
    item <309> & "co"'q' & <angle> "d" こんにちは 309
    item <310> & "co"'q' & <angle> "d" こんにちは 310
    item <311> & "co"'q' & <angle> "d" こんにちは 311
    item <312> & "co"'q' & <angle> "d" こんにちは 312
    item <313> & "co"'q' & <angle> "d" こんにちは 313
    item <314> & "co"'q' & <angle> "d" こんにちは 314
    item <315> & "co"'q' & <angle> "d" こんにちは 315
    item <316> & "co"'q' & <angle> "d" こんにちは 316
    item <317> & "co"'q' & <angle> "d" こんにちは 317
    item <318> & "co"'q' & <angle> "d" こんにちは 318
    item <319> & "co"'q' & <angle> "d" こんにちは 319
    item <320> & "co"'q' & <angle> "d" こんにちは 320
    item <321> & "co"'q' & <angle> "d" こんにちは 321
    item <322> & "co"'q' & <angle> "d" こんにちは 322
    item <323> & "co"'q' & <angle> "d" こんにちは 323
    item <324> & "co"'q' & <angle> "d" こんにちは 324
    item <325> & "co"'q' & <angle> "d" こんにちは 325
    item <326> & "co"'q' & <angle> "d" こんにちは 326
    item <327> & "co"'q' & <angle> "d" こんにちは 327
    item <328> & "co"'q' & <angle> "d" こんにちは 328
    item <329> & "co"'q' & <angle> "d" こんにちは 329
    item <330> & "co"'q' & <angle> "d" こんにちは 330
    item <331> & "co"'q' & <angle> "d" こんにちは 331
    item <332> & "co"'q' & <angle> "d" こんにちは 332
    item <333> & "co"'q' & <angle> "d" こんにちは 333
    item <334> & "co"'q' & <angle> "d" こんにちは 334
    item <335> & "co"'q' & <angle> "d" こんにちは 335
    item <336> & "co"'q' & <angle> "d" こんにちは 336
    item <337> & "co"'q' & <angle> "d" こんにちは 337
    item <338> & "co"'q' & <angle> "d" こんにちは 338
    item <339> & "co"'q' & <angle> "d" こんにちは 339
    item <340> & "co"'q' & <angle> "d" こんにちは 340
    item <341> & "co"'q' & <angle> "d" こんにちは 341
    item <342> & "co"'q' & <angle> "d" こんにちは 342
    item <343> & "co"'q' & <angle> "d" こんにちは 343
    item <344> & "co"'q' & <angle> "d" こんにちは 344
    item <345> & "co"'q' & <angle> "d" こんにちは 345
    item <346> & "co"'q' & <angle> "d" こんにちは 346
    item <347> & "co"'q' & <angle> "d" こんにちは 347
    item <348> & "co"'q' & <angle> "d" こんにちは 348
    item <349> & "co"'q' & <angle> "d" こんにちは 349
    item <350> & "co"'q' & <angle> "d" こんにちは 350
    item <351> & "co"'q' & <angle> "d" こんにちは 351
    item <352> & "co"'q' & <angle> "d" こんにちは 352
    item <353> & "co"'q' & <angle> "d" こんにちは 353
    item <354> & "co"'q' & <angle> "d" こんにちは 354
    item <355> & "co"'q' & <angle> "d" こんにちは 355
    item <356> & "co"'q' & <angle> "d" こんにちは 356
    item <357> & "co"'q' & <angle> "d" こんにちは 357
    item <358> & "co"'q' & <angle> "d" こんにちは 358
    item <359> & "co"'q' & <angle> "d" こんにちは 359
    item <360> & "co"'q' & <angle> "d" こんにちは 360
    item <361> & "co"'q' & <angle> "d" こんにちは 361
    item <362> & "co"'q' & <angle> "d" こんにちは 362
    item <363> & "co"'q' & <angle> "d" こんにちは 363
    item <364> & "co"'q' & <angle> "d" こんにちは 364
    item <365> & "co"'q' & <angle> "d" こんにちは 365
    item <366> & "co"'q' & <angle> "d" こんにちは 366
    item <367> & "co"'q' & <angle> "d" こんにちは 367
    item <368> & "co"'q' & <angle> "d" こんにちは 368
    item <369> & "co"'q' & <angle> "d" こんにちは 369
    item <370> & "co"'q' & <angle> "d" こんにちは 370
    item <371> & "co"'q' & <angle> "d" こんにちは 371
    item <372> & "co"'q' & <angle> "d" こんにちは 372
    item <373> & "co"'q' & <angle> "d" こんにちは 373
    item <374> & "co"'q' & <angle> "d" こんにちは 374
    item <375> & "co"'q' & <angle> "d" こんにちは 375
    item <376> & "co"'q' & <angle> "d" こんにちは 376
    item <377> & "co"'q' & <angle> "d" こんにちは 377
    item <378> & "co"'q' & <angle> "d" こんにちは 378
    item <379> & "co"'q' & <angle> "d" こんにちは 379
    item <380> & "co"'q' & <angle> "d" こんにちは 380
    item <381> & "co"'q' & <angle> "d" こんにちは 381
    item <382> & "co"'q' & <angle> "d" こんにちは 382
    item <383> & "co"'q' & <angle> "d" こんにちは 383
    item <384> & "co"'q' & <angle> "d" こんにちは 384
    item <385> & "co"'q' & <angle> "d" こんにちは 385
    item <386> & "co"'q' & <angle> "d" こんにちは 386
    item <387> & "co"'q' & <angle> "d" こんにちは 387
    item <388> & "co"'q' & <angle> "d" こんにちは 388
    item <389> & "co"'q' & <angle> "d" こんにちは 389
    item <390> & "co"'q' & <angle> "d" こんにちは 390
    item <391> & "co"'q' & <angle> "d" こんにちは 391
    item <392> & "co"'q' & <angle> "d" こんにちは 392
    item <393> & "co"'q' & <angle> "d" こんにちは 393
    item <394> & "co"'q' & <angle> "d" こんにちは 394
    item <395> & "co"'q' & <angle> "d" こんにちは 395
    item <396> & "co"'q' & <angle> "d" こんにちは 396
    item <397> & "co"'q' & <angle> "d" こんにちは 397
    item <398> & "co"'q' & <angle> "d" こんにちは 398
    item <399> & "co"'q' & <angle> "d" こんにちは 399
    item <400> & "co"'q' & <angle> "d" こんにちは 400
    item <401> & "co"'q' & <angle> "d" こんにちは 401
    item <402> & "co"'q' & <angle> "d" こんにちは 402
    item <403> & "co"'q' & <angle> "d" こんにちは 403
    item <404> & "co"'q' & <angle> "d" こんにちは 404
    item <405> & "co"'q' & <angle> "d" こんにちは 405
    item <406> & "co"'q' & <angle> "d" こんにちは 406
    item <407> & "co"'q' & <angle> "d" こんにちは 407
    item <408> & "co"'q' & <angle> "d" こんにちは 408
    item <409> & "co"'q' & <angle> "d" こんにちは 409
    item <410> & "co"'q' & <angle> "d" こんにちは 410
    item <411> & "co"'q' & <angle> "d" こんにちは 411
    item <412> & "co"'q' & <angle> "d" こんにちは 412
    item <413> & "co"'q' & <angle> "d" こんにちは 413
    item <414> & "co"'q' & <angle> "d" こんにちは 414
    item <415> & "co"'q' & <angle> "d" こんにちは 415
    item <416> & "co"'q' & <angle> "d" こんにちは 416
    item <417> & "co"'q' & <angle> "d" こんにちは 417
    item <418> & "co"'q' & <angle> "d" こんにちは 418
    item <419> & "co"'q' & <angle> "d" こんにちは 419
    item <420> & "co"'q' & <angle> "d" こんにちは 420
    item <421> & "co"'q' & <angle> "d" こんにちは 421
    item <422> & "co"'q' & <angle> "d" こんにちは 422
    item <423> & "co"'q' & <angle> "d" こんにちは 423
    item <424> & "co"'q' & <angle> "d" こんにちは 424
    item <425> & "co"'q' & <angle> "d" こんにちは 425
    item <426> & "co"'q' & <angle> "d" こんにちは 426
    item <427> & "co"'q' & <angle> "d" こんにちは 427
    item <428> & "co"'q' & <angle> "d" こんにちは 428
    item <429> & "co"'q' & <angle> "d" こんにちは 429
    item <430> & "co"'q' & <angle> "d" こんにちは 430
    item <431> & "co"'q' & <angle> "d" こんにちは 431
    item <432> & "co"'q' & <angle> "d" こんにちは 432
    item <433> & "co"'q' & <angle> "d" こんにちは 433
    item <434> & "co"'q' & <angle> "d" こんにちは 434
    item <435> & "co"'q' & <angle> "d" こんにちは 435
    item <436> & "co"'q' & <angle> "d" こんにちは 436
    item <437> & "co"'q' & <angle> "d" こんにちは 437
    item <438> & "co"'q' & <angle> "d" こんにちは 438
    item <439> & "co"'q' & <angle> "d" こんにちは 439
    item <440> & "co"'q' & <angle> "d" こんにちは 440
    item <441> & "co"'q' & <angle> "d" こんにちは 441
    item <442> & "co"'q' & <angle> "d" こんにちは 442
    item <443> & "co"'q' & <angle> "d" こんにちは 443
    item <444> & "co"'q' & <angle> "d" こんにちは 444
    item <445> & "co"'q' & <angle> "d" こんにちは 445
    item <446> & "co"'q' & <angle> "d" こんにちは 446
    item <447> & "co"'q' & <angle> "d" こんにちは 447
    item <448> & "co"'q' & <angle> "d" こんにちは 448
    item <449> & "co"'q' & <angle> "d" こんにちは 449
    item <450> & "co"'q' & <angle> "d" こんにちは 450
    item <451> & "co"'q' & <angle> "d" こんにちは 451
    item <452> & "co"'q' & <angle> "d" こんにちは 452
    item <453> & "co"'q' & <angle> "d" こんにちは 453
    item <454> & "co"'q' & <angle> "d" こんにちは 454
    item <455> & "co"'q' & <angle> "d" こんにちは 455
    item <456> & "co"'q' & <angle> "d" こんにちは 456
    item <457> & "co"'q' & <angle> "d" こんにちは 457
    item <458> & "co"'q' & <angle> "d" こんにちは 458
    item <459> & "co"'q' & <angle> "d" こんにちは 459
    item <460> & "co"'q' & <angle> "d" こんにちは 460
    item <461> & "co"'q' & <angle> "d" こんにちは 461
    item <462> & "co"'q' & <angle> "d" こんにちは 462
    item <463> & "co"'q' & <angle> "d" こんにちは 463
    item <464> & "co"'q' & <angle> "d" こんにちは 464
    item <465> & "co"'q' & <angle> "d" こんにちは 465
    item <466> & "co"'q' & <angle> "d" こんにちは 466
    item <467> & "co"'q' & <angle> "d" こんにちは 467
    item <468> & "co"'q' & <angle> "d" こんにちは 468
    item <469> & "co"'q' & <angle> "d" こんにちは 469
    item <470> & "co"'q' & <angle> "d" こんにちは 470
    item <471> & "co"'q' & <angle> "d" こんにちは 471
    item <472> & "co"'q' & <angle> "d" こんにちは 472
    item <473> & "co"'q' & <angle> "d" こんにちは 473
    item <474> & "co"'q' & <angle> "d" こんにちは 474
    item <475> & "co"'q' & <angle> "d" こんにちは 475
    item <476> & "co"'q' & <angle> "d" こんにちは 476
    item <477> & "co"'q' & <angle> "d" こんにちは 477
    item <478> & "co"'q' & <angle> "d" こんにちは 478
    item <479> & "co"'q' & <angle> "d" こんにちは 479
    item <480> & "co"'q' & <angle> "d" こんにちは 480
    item <481> & "co"'q' & <angle> "d" こんにちは 481
    item <482> & "co"'q' & <angle> "d" こんにちは 482
    item <483> & "co"'q' & <angle> "d" こんにちは 483
    item <484> & "co"'q' & <angle> "d" こんにちは 484
    item <485> & "co"'q' & <angle> "d" こんにちは 485
    item <486> & "co"'q' & <angle> "d" こんにちは 486
    item <487> & "co"'q' & <angle> "d" こんにちは 487
    item <488> & "co"'q' & <angle> "d" こんにちは 488
    item <489> & "co"'q' & <angle> "d" こんにちは 489
    item <490> & "co"'q' & <angle> "d" こんにちは 490
    item <491> & "co"'q' & <angle> "d" こんにちは 491
    item <492> & "co"'q' & <angle> "d" こんにちは 492
    item <493> & "co"'q' & <angle> "d" こんにちは 493
    item <494> & "co"'q' & <angle> "d" こんにちは 494
    item <495> & "co"'q' & <angle> "d" こんにちは 495
    item <496> & "co"'q' & <angle> "d" こんにちは 496
    item <497> & "co"'q' & <angle> "d" こんにちは 497
    item <498> & "co"'q' & <angle> "d" こんにちは 498
    item <499> & "co"'q' & <angle> "d" こんにちは 499
    item <500> & "co"'q' & <angle> "d" こんにちは 500
    item <501> & "co"'q' & <angle> "d" こんにちは 501
    item <502> & "co"'q' & <angle> "d" こんにちは 502
    item <503> & "co"'q' & <angle> "d" こんにちは 503
    item <504> & "co"'q' & <angle> "d" こんにちは 504
    item <505> & "co"'q' & <angle> "d" こんにちは 505
    item <506> & "co"'q' & <angle> "d" こんにちは 506
    item <507> & "co"'q' & <angle> "d" こんにちは 507
    item <508> & "co"'q' & <angle> "d" こんにちは 508
    item <509> & "co"'q' & <angle> "d" こんにちは 509
    item <510> & "co"'q' & <angle> "d" こんにちは 510
    item <511> & "co"'q' & <angle> "d" こんにちは 511
    item <512> & "co"'q' & <angle> "d" こんにちは 512
    item <513> & "co"'q' & <angle> "d" こんにちは 513
    item <514> & "co"'q' & <angle> "d" こんにちは 514
    item <515> & "co"'q' & <angle> "d" こんにちは 515
    item <516> & "co"'q' & <angle> "d" こんにちは 516
    item <517> & "co"'q' & <angle> "d" こんにちは 517
    item <518> & "co"'q' & <angle> "d" こんにちは 518
    item <519> & "co"'q' & <angle> "d" こんにちは 519
    item <520> & "co"'q' & <angle> "d" こんにちは 520
    item <521> & "co"'q' & <angle> "d" こんにちは 521
    item <522> & "co"'q' & <angle> "d" こんにちは 522
    item <523> & "co"'q' & <angle> "d" こんにちは 523
    item <524> & "co"'q' & <angle> "d" こんにちは 524
    item <525> & "co"'q' & <angle> "d" こんにちは 525
    item <526> & "co"'q' & <angle> "d" こんにちは 526
    item <527> & "co"'q' & <angle> "d" こんにちは 527
    item <528> & "co"'q' & <angle> "d" こんにちは 528
    item <529> & "co"'q' & <angle> "d" こんにちは 529
    item <530> & "co"'q' & <angle> "d" こんにちは 530
    item <531> & "co"'q' & <angle> "d" こんにちは 531
    item <532> & "co"'q' & <angle> "d" こんにちは 532
    item <533> & "co"'q' & <angle> "d" こんにちは 533
    item <534> & "co"'q' & <angle> "d" こんにちは 534
    item <535> & "co"'q' & <angle> "d" こんにちは 535
    item <536> & "co"'q' & <angle> "d" こんにちは 536
    item <537> & "co"'q' & <angle> "d" こんにちは 537
    item <538> & "co"'q' & <angle> "d" こんにちは 538
    item <539> & "co"'q' & <angle> "d" こんにちは 539
    item <540> & "co"'q' & <angle> "d" こんにちは 540
    item <541> & "co"'q' & <angle> "d" こんにちは 541
    item <542> & "co"'q' & <angle> "d" こんにちは 542
    item <543> & "co"'q' & <angle> "d" こんにちは 543
    item <544> & "co"'q' & <angle> "d" こんにちは 544
    item <545> & "co"'q' & <angle> "d" こんにちは 545
    item <546> & "co"'q' & <angle> "d" こんにちは 546
    item <547> & "co"'q' & <angle> "d" こんにちは 547
    item <548> & "co"'q' & <angle> "d" こんにちは 548
    item <549> & "co"'q' & <angle> "d" こんにちは 549
    item <550> & "co"'q' & <angle> "d" こんにちは 550
    item <551> & "co"'q' & <angle> "d" こんにちは 551
    item <552> & "co"'q' & <angle> "d" こんにちは 552
    item <553> & "co"'q' & <angle> "d" こんにちは 553
    item <554> & "co"'q' & <angle> "d" こんにちは 554
    item <555> & "co"'q' & <angle> "d" こんにちは 555
    item <556> & "co"'q' & <angle> "d" こんにちは 556
    item <557> & "co"'q' & <angle> "d" こんにちは 557
    item <558> & "co"'q' & <angle> "d" こんにちは 558
    item <559> & "co"'q' & <angle> "d" こんにちは 559
    item <560> & "co"'q' & <angle> "d" こんにちは 560
    item <561> & "co"'q' & <angle> "d" こんにちは 561
    item <562> & "co"'q' & <angle> "d" こんにちは 562
    item <563> & "co"'q' & <angle> "d" こんにちは 563
    item <564> & "co"'q' & <angle> "d" こんにちは 564
    item <565> & "co"'q' & <angle> "d" こんにちは 565
    item <566> & "co"'q' & <angle> "d" こんにちは 566
    item <567> & "co"'q' & <angle> "d" こんにちは 567
    item <568> & "co"'q' & <angle> "d" こんにちは 568
    item <569> & "co"'q' & <angle> "d" こんにちは 569
    item <570> & "co"'q' & <angle> "d" こんにちは 570
    item <571> & "co"'q' & <angle> "d" こんにちは 571
    item <572> & "co"'q' & <angle> "d" こんにちは 572
    item <573> & "co"'q' & <angle> "d" こんにちは 573
    item <574> & "co"'q' & <angle> "d" こんにちは 574
    item <575> & "co"'q' & <angle> "d" こんにちは 575
    item <576> & "co"'q' & <angle> "d" こんにちは 576
    item <577> & "co"'q' & <angle> "d" こんにちは 577
    item <578> & "co"'q' & <angle> "d" こんにちは 578
    item <579> & "co"'q' & <angle> "d" こんにちは 579
    item <580> & "co"'q' & <angle> "d" こんにちは 580
    item <581> & "co"'q' & <angle> "d" こんにちは 581
    item <582> & "co"'q' & <angle> "d" こんにちは 582
    item <583> & "co"'q' & <angle> "d" こんにちは 583
    item <584> & "co"'q' & <angle> "d" こんにちは 584
    item <585> & "co"'q' & <angle> "d" こんにちは 585
    item <586> & "co"'q' & <angle> "d" こんにちは 586
    item <587> & "co"'q' & <angle> "d" こんにちは 587
    item <588> & "co"'q' & <angle> "d" こんにちは 588
    item <589> & "co"'q' & <angle> "d" こんにちは 589
    item <590> & "co"'q' & <angle> "d" こんにちは 590
    item <591> & "co"'q' & <angle> "d" こんにちは 591
    item <592> & "co"'q' & <angle> "d" こんにちは 592
    item <593> & "co"'q' & <angle> "d" こんにちは 593
    item <594> & "co"'q' & <angle> "d" こんにちは 594
    item <595> & "co"'q' & <angle> "d" こんにちは 595
    item <596> & "co"'q' & <angle> "d" こんにちは 596
    item <597> & "co"'q' & <angle> "d" こんにちは 597
    item <598> & "co"'q' & <angle> "d" こんにちは 598
    item <599> & "co"'q' & <angle> "d" こんにちは 599
    item <600> & "co"'q' & <angle> "d" こんにちは 600
    item <601> & "co"'q' & <angle> "d" こんにちは 601
    item <602> & "co"'q' & <angle> "d" こんにちは 602
    item <603> & "co"'q' & <angle> "d" こんにちは 603
    item <604> & "co"'q' & <angle> "d" こんにちは 604
    item <605> & "co"'q' & <angle> "d" こんにちは 605
    item <606> & "co"'q' & <angle> "d" こんにちは 606
    item <607> & "co"'q' & <angle> "d" こんにちは 607
    item <608> & "co"'q' & <angle> "d" こんにちは 608
    item <609> & "co"'q' & <angle> "d" こんにちは 609
    item <610> & "co"'q' & <angle> "d" こんにちは 610
    item <611> & "co"'q' & <angle> "d" こんにちは 611
    item <612> & "co"'q' & <angle> "d" こんにちは 612
    item <613> & "co"'q' & <angle> "d" こんにちは 613
    item <614> & "co"'q' & <angle> "d" こんにちは 614
    item <615> & "co"'q' & <angle> "d" こんにちは 615
    item <616> & "co"'q' & <angle> "d" こんにちは 616
    item <617> & "co"'q' & <angle> "d" こんにちは 617
    item <618> & "co"'q' & <angle> "d" こんにちは 618
    item <619> & "co"'q' & <angle> "d" こんにちは 619
    item <620> & "co"'q' & <angle> "d" こんにちは 620
    item <621> & "co"'q' & <angle> "d" こんにちは 621
    item <622> & "co"'q' & <angle> "d" こんにちは 622
    item <623> & "co"'q' & <angle> "d" こんにちは 623
    item <624> & "co"'q' & <angle> "d" こんにちは 624
    item <625> & "co"'q' & <angle> "d" こんにちは 625
    item <626> & "co"'q' & <angle> "d" こんにちは 626
    item <627> & "co"'q' & <angle> "d" こんにちは 627
    item <628> & "co"'q' & <angle> "d" こんにちは 628
    item <629> & "co"'q' & <angle> "d" こんにちは 629
    item <630> & "co"'q' & <angle> "d" こんにちは 630
    item <631> & "co"'q' & <angle> "d" こんにちは 631
    item <632> & "co"'q' & <angle> "d" こんにちは 632
    item <633> & "co"'q' & <angle> "d" こんにちは 633
    item <634> & "co"'q' & <angle> "d" こんにちは 634
    item <635> & "co"'q' & <angle> "d" こんにちは 635
    item <636> & "co"'q' & <angle> "d" こんにちは 636
    item <637> & "co"'q' & <angle> "d" こんにちは 637
    item <638> & "co"'q' & <angle> "d" こんにちは 638
    item <639> & "co"'q' & <angle> "d" こんにちは 639
    item <640> & "co"'q' & <angle> "d" こんにちは 640
    item <641> & "co"'q' & <angle> "d" こんにちは 641
    item <642> & "co"'q' & <angle> "d" こんにちは 642
    item <643> & "co"'q' & <angle> "d" こんにちは 643
    item <644> & "co"'q' & <angle> "d" こんにちは 644
    item <645> & "co"'q' & <angle> "d" こんにちは 645
    item <646> & "co"'q' & <angle> "d" こんにちは 646
    item <647> & "co"'q' & <angle> "d" こんにちは 647
    item <648> & "co"'q' & <angle> "d" こんにちは 648
    item <649> & "co"'q' & <angle> "d" こんにちは 649
    item <650> & "co"'q' & <angle> "d" こんにちは 650
    item <651> & "co"'q' & <angle> "d" こんにちは 651
    item <652> & "co"'q' & <angle> "d" こんにちは 652
    item <653> & "co"'q' & <angle> "d" こんにちは 653
    item <654> & "co"'q' & <angle> "d" こんにちは 654
    item <655> & "co"'q' & <angle> "d" こんにちは 655
    item <656> & "co"'q' & <angle> "d" こんにちは 656
    item <657> & "co"'q' & <angle> "d" こんにちは 657
    item <658> & "co"'q' & <angle> "d" こんにちは 658
    item <659> & "co"'q' & <angle> "d" こんにちは 659
    item <660> & "co"'q' & <angle> "d" こんにちは 660
    item <661> & "co"'q' & <angle> "d" こんにちは 661
    item <662> & "co"'q' & <angle> "d" こんにちは 662
    item <663> & "co"'q' & <angle> "d" こんにちは 663
    item <664> & "co"'q' & <angle> "d" こんにちは 664
    item <665> & "co"'q' & <angle> "d" こんにちは 665
    item <666> & "co"'q' & <angle> "d" こんにちは 666
    item <667> & "co"'q' & <angle> "d" こんにちは 667
    item <668> & "co"'q' & <angle> "d" こんにちは 668
    item <669> & "co"'q' & <angle> "d" こんにちは 669
    item <670> & "co"'q' & <angle> "d" こんにちは 670
    item <671> & "co"'q' & <angle> "d" こんにちは 671
    item <672> & "co"'q' & <angle> "d" こんにちは 672
    item <673> & "co"'q' & <angle> "d" こんにちは 673
    item <674> & "co"'q' & <angle> "d" こんにちは 674
    item <675> & "co"'q' & <angle> "d" こんにちは 675
    item <676> & "co"'q' & <angle> "d" こんにちは 676
    item <677> & "co"'q' & <angle> "d" こんにちは 677
    item <678> & "co"'q' & <angle> "d" こんにちは 678
    item <679> & "co"'q' & <angle> "d" こんにちは 679
    item <680> & "co"'q' & <angle> "d" こんにちは 680
    item <681> & "co"'q' & <angle> "d" こんにちは 681
    item <682> & "co"'q' & <angle> "d" こんにちは 682
    item <683> & "co"'q' & <angle> "d" こんにちは 683
    item <684> & "co"'q' & <angle> "d" こんにちは 684
    item <685> & "co"'q' & <angle> "d" こんにちは 685
    item <686> & "co"'q' & <angle> "d" こんにちは 686
    item <687> & "co"'q' & <angle> "d" こんにちは 687
    item <688> & "co"'q' & <angle> "d" こんにちは 688
    item <689> & "co"'q' & <angle> "d" こんにちは 689
    item <690> & "co"'q' & <angle> "d" こんにちは 690
    item <691> & "co"'q' & <angle> "d" こんにちは 691
    item <692> & "co"'q' & <angle> "d" こんにちは 692
    item <693> & "co"'q' & <angle> "d" こんにちは 693
    item <694> & "co"'q' & <angle> "d" こんにちは 694
    item <695> & "co"'q' & <angle> "d" こんにちは 695
    item <696> & "co"'q' & <angle> "d" こんにちは 696
    item <697> & "co"'q' & <angle> "d" こんにちは 697
    item <698> & "co"'q' & <angle> "d" こんにちは 698
    item <699> & "co"'q' & <angle> "d" こんにちは 699
    item <700> & "co"'q' & <angle> "d" こんにちは 700
    item <701> & "co"'q' & <angle> "d" こんにちは 701
    item <702> & "co"'q' & <angle> "d" こんにちは 702
    item <703> & "co"'q' & <angle> "d" こんにちは 703
    item <704> & "co"'q' & <angle> "d" こんにちは 704
    item <705> & "co"'q' & <angle> "d" こんにちは 705
    item <706> & "co"'q' & <angle> "d" こんにちは 706
    item <707> & "co"'q' & <angle> "d" こんにちは 707
    item <708> & "co"'q' & <angle> "d" こんにちは 708
    item <709> & "co"'q' & <angle> "d" こんにちは 709
    item <710> & "co"'q' & <angle> "d" こんにちは 710
    item <711> & "co"'q' & <angle> "d" こんにちは 711
    item <712> & "co"'q' & <angle> "d" こんにちは 712
    item <713> & "co"'q' & <angle> "d" こんにちは 713
    item <714> & "co"'q' & <angle> "d" こんにちは 714
    item <715> & "co"'q' & <angle> "d" こんにちは 715
    item <716> & "co"'q' & <angle> "d" こんにちは 716
    item <717> & "co"'q' & <angle> "d" こんにちは 717
    item <718> & "co"'q' & <angle> "d" こんにちは 718
    item <719> & "co"'q' & <angle> "d" こんにちは 719
    item <720> & "co"'q' & <angle> "d" こんにちは 720
    item <721> & "co"'q' & <angle> "d" こんにちは 721
    item <722> & "co"'q' & <angle> "d" こんにちは 722
    item <723> & "co"'q' & <angle> "d" こんにちは 723
    item <724> & "co"'q' & <angle> "d" こんにちは 724
    item <725> & "co"'q' & <angle> "d" こんにちは 725
    item <726> & "co"'q' & <angle> "d" こんにちは 726
    item <727> & "co"'q' & <angle> "d" こんにちは 727
    item <728> & "co"'q' & <angle> "d" こんにちは 728
    item <729> & "co"'q' & <angle> "d" こんにちは 729
    item <730> & "co"'q' & <angle> "d" こんにちは 730
    item <731> & "co"'q' & <angle> "d" こんにちは 731
    item <732> & "co"'q' & <angle> "d" こんにちは 732
    item <733> & "co"'q' & <angle> "d" こんにちは 733
    item <734> & "co"'q' & <angle> "d" こんにちは 734
    item <735> & "co"'q' & <angle> "d" こんにちは 735
    item <736> & "co"'q' & <angle> "d" こんにちは 736
    item <737> & "co"'q' & <angle> "d" こんにちは 737
    item <738> & "co"'q' & <angle> "d" こんにちは 738
    item <739> & "co"'q' & <angle> "d" こんにちは 739
    item <740> & "co"'q' & <angle> "d" こんにちは 740
    item <741> & "co"'q' & <angle> "d" こんにちは 741
    item <742> & "co"'q' & <angle> "d" こんにちは 742
    item <743> & "co"'q' & <angle> "d" こんにちは 743
    item <744> & "co"'q' & <angle> "d" こんにちは 744
    item <745> & "co"'q' & <angle> "d" こんにちは 745
    item <746> & "co"'q' & <angle> "d" こんにちは 746
    item <747> & "co"'q' & <angle> "d" こんにちは 747
    item <748> & "co"'q' & <angle> "d" こんにちは 748
    item <749> & "co"'q' & <angle> "d" こんにちは 749
    item <750> & "co"'q' & <angle> "d" こんにちは 750
    item <751> & "co"'q' & <angle> "d" こんにちは 751
    item <752> & "co"'q' & <angle> "d" こんにちは 752
    item <753> & "co"'q' & <angle> "d" こんにちは 753
    item <754> & "co"'q' & <angle> "d" こんにちは 754
    item <755> & "co"'q' & <angle> "d" こんにちは 755
    item <756> & "co"'q' & <angle> "d" こんにちは 756
    item <757> & "co"'q' & <angle> "d" こんにちは 757
    item <758> & "co"'q' & <angle> "d" こんにちは 758
    item <759> & "co"'q' & <angle> "d" こんにちは 759
    item <760> & "co"'q' & <angle> "d" こんにちは 760
    item <761> & "co"'q' & <angle> "d" こんにちは 761
    item <762> & "co"'q' & <angle> "d" こんにちは 762
    item <763> & "co"'q' & <angle> "d" こんにちは 763
    item <764> & "co"'q' & <angle> "d" こんにちは 764
    item <765> & "co"'q' & <angle> "d" こんにちは 765
    item <766> & "co"'q' & <angle> "d" こんにちは 766
    item <767> & "co"'q' & <angle> "d" こんにちは 767
    item <768> & "co"'q' & <angle> "d" こんにちは 768
    item <769> & "co"'q' & <angle> "d" こんにちは 769
    item <770> & "co"'q' & <angle> "d" こんにちは 770
    item <771> & "co"'q' & <angle> "d" こんにちは 771
    item <772> & "co"'q' & <angle> "d" こんにちは 772
    item <773> & "co"'q' & <angle> "d" こんにちは 773
    item <774> & "co"'q' & <angle> "d" こんにちは 774
    item <775> & "co"'q' & <angle> "d" こんにちは 775
    item <776> & "co"'q' & <angle> "d" こんにちは 776
    item <777> & "co"'q' & <angle> "d" こんにちは 777
    item <778> & "co"'q' & <angle> "d" こんにちは 778
    item <779> & "co"'q' & <angle> "d" こんにちは 779
    item <780> & "co"'q' & <angle> "d" こんにちは 780
    item <781> & "co"'q' & <angle> "d" こんにちは 781
    item <782> & "co"'q' & <angle> "d" こんにちは 782
    item <783> & "co"'q' & <angle> "d" こんにちは 783
    item <784> & "co"'q' & <angle> "d" こんにちは 784
    item <785> & "co"'q' & <angle> "d" こんにちは 785
    item <786> & "co"'q' & <angle> "d" こんにちは 786
    item <787> & "co"'q' & <angle> "d" こんにちは 787
    item <788> & "co"'q' & <angle> "d" こんにちは 788
    item <789> & "co"'q' & <angle> "d" こんにちは 789
    item <790> & "co"'q' & <angle> "d" こんにちは 790
    item <791> & "co"'q' & <angle> "d" こんにちは 791
    item <792> & "co"'q' & <angle> "d" こんにちは 792
    item <793> & "co"'q' & <angle> "d" こんにちは 793
    item <794> & "co"'q' & <angle> "d" こんにちは 794
    item <795> & "co"'q' & <angle> "d" こんにちは 795
    item <796> & "co"'q' & <angle> "d" こんにちは 796
    item <797> & "co"'q' & <angle> "d" こんにちは 797
    item <798> & "co"'q' & <angle> "d" こんにちは 798
    item <799> & "co"'q' & <angle> "d" こんにちは 799
    item <800> & "co"'q' & <angle> "d" こんにちは 800
    item <801> & "co"'q' & <angle> "d" こんにちは 801
    item <802> & "co"'q' & <angle> "d" こんにちは 802
    item <803> & "co"'q' & <angle> "d" こんにちは 803
    item <804> & "co"'q' & <angle> "d" こんにちは 804
    item <805> & "co"'q' & <angle> "d" こんにちは 805
    item <806> & "co"'q' & <angle> "d" こんにちは 806
    item <807> & "co"'q' & <angle> "d" こんにちは 807
    item <808> & "co"'q' & <angle> "d" こんにちは 808
    item <809> & "co"'q' & <angle> "d" こんにちは 809
    item <810> & "co"'q' & <angle> "d" こんにちは 810
    item <811> & "co"'q' & <angle> "d" こんにちは 811
    item <812> & "co"'q' & <angle> "d" こんにちは 812
    item <813> & "co"'q' & <angle> "d" こんにちは 813
    item <814> & "co"'q' & <angle> "d" こんにちは 814
    item <815> & "co"'q' & <angle> "d" こんにちは 815
    item <816> & "co"'q' & <angle> "d" こんにちは 816
    item <817> & "co"'q' & <angle> "d" こんにちは 817
    item <818> & "co"'q' & <angle> "d" こんにちは 818
    item <819> & "co"'q' & <angle> "d" こんにちは 819
    item <820> & "co"'q' & <angle> "d" こんにちは 820
    item <821> & "co"'q' & <angle> "d" こんにちは 821
    item <822> & "co"'q' & <angle> "d" こんにちは 822
    item <823> & "co"'q' & <angle> "d" こんにちは 823
    item <824> & "co"'q' & <angle> "d" こんにちは 824
    item <825> & "co"'q' & <angle> "d" こんにちは 825
    item <826> & "co"'q' & <angle> "d" こんにちは 826
    item <827> & "co"'q' & <angle> "d" こんにちは 827
    item <828> & "co"'q' & <angle> "d" こんにちは 828
    item <829> & "co"'q' & <angle> "d" こんにちは 829
    item <830> & "co"'q' & <angle> "d" こんにちは 830
    item <831> & "co"'q' & <angle> "d" こんにちは 831
    item <832> & "co"'q' & <angle> "d" こんにちは 832
    item <833> & "co"'q' & <angle> "d" こんにちは 833
    item <834> & "co"'q' & <angle> "d" こんにちは 834
    item <835> & "co"'q' & <angle> "d" こんにちは 835
    item <836> & "co"'q' & <angle> "d" こんにちは 836
    item <837> & "co"'q' & <angle> "d" こんにちは 837
    item <838> & "co"'q' & <angle> "d" こんにちは 838
    item <839> & "co"'q' & <angle> "d" こんにちは 839
    item <840> & "co"'q' & <angle> "d" こんにちは 840
    item <841> & "co"'q' & <angle> "d" こんにちは 841
    item <842> & "co"'q' & <angle> "d" こんにちは 842
    item <843> & "co"'q' & <angle> "d" こんにちは 843
    item <844> & "co"'q' & <angle> "d" こんにちは 844
    item <845> & "co"'q' & <angle> "d" こんにちは 845
    item <846> & "co"'q' & <angle> "d" こんにちは 846
    item <847> & "co"'q' & <angle> "d" こんにちは 847
    item <848> & "co"'q' & <angle> "d" こんにちは 848
    item <849> & "co"'q' & <angle> "d" こんにちは 849
    item <850> & "co"'q' & <angle> "d" こんにちは 850
    item <851> & "co"'q' & <angle> "d" こんにちは 851
    item <852> & "co"'q' & <angle> "d" こんにちは 852
    item <853> & "co"'q' & <angle> "d" こんにちは 853
    item <854> & "co"'q' & <angle> "d" こんにちは 854
    item <855> & "co"'q' & <angle> "d" こんにちは 855
    item <856> & "co"'q' & <angle> "d" こんにちは 856
    item <857> & "co"'q' & <angle> "d" こんにちは 857
    item <858> & "co"'q' & <angle> "d" こんにちは 858
    item <859> & "co"'q' & <angle> "d" こんにちは 859
    item <860> & "co"'q' & <angle> "d" こんにちは 860
    item <861> & "co"'q' & <angle> "d" こんにちは 861
    item <862> & "co"'q' & <angle> "d" こんにちは 862
    item <863> & "co"'q' & <angle> "d" こんにちは 863
    item <864> & "co"'q' & <angle> "d" こんにちは 864
    item <865> & "co"'q' & <angle> "d" こんにちは 865
    item <866> & "co"'q' & <angle> "d" こんにちは 866
    item <867> & "co"'q' & <angle> "d" こんにちは 867
    item <868> & "co"'q' & <angle> "d" こんにちは 868
    item <869> & "co"'q' & <angle> "d" こんにちは 869
    item <870> & "co"'q' & <angle> "d" こんにちは 870
    item <871> & "co"'q' & <angle> "d" こんにちは 871
    item <872> & "co"'q' & <angle> "d" こんにちは 872
    item <873> & "co"'q' & <angle> "d" こんにちは 873
    item <874> & "co"'q' & <angle> "d" こんにちは 874
    item <875> & "co"'q' & <angle> "d" こんにちは 875
    item <876> & "co"'q' & <angle> "d" こんにちは 876
    item <877> & "co"'q' & <angle> "d" こんにちは 877
    item <878> & "co"'q' & <angle> "d" こんにちは 878
    item <879> & "co"'q' & <angle> "d" こんにちは 879
    item <880> & "co"'q' & <angle> "d" こんにちは 880
    item <881> & "co"'q' & <angle> "d" こんにちは 881
    item <882> & "co"'q' & <angle> "d" こんにちは 882
    item <883> & "co"'q' & <angle> "d" こんにちは 883
    item <884> & "co"'q' & <angle> "d" こんにちは 884
    item <885> & "co"'q' & <angle> "d" こんにちは 885
    item <886> & "co"'q' & <angle> "d" こんにちは 886
    item <887> & "co"'q' & <angle> "d" こんにちは 887
    item <888> & "co"'q' & <angle> "d" こんにちは 888
    item <889> & "co"'q' & <angle> "d" こんにちは 889
    item <890> & "co"'q' & <angle> "d" こんにちは 890
    item <891> & "co"'q' & <angle> "d" こんにちは 891
    item <892> & "co"'q' & <angle> "d" こんにちは 892
    item <893> & "co"'q' & <angle> "d" こんにちは 893
    item <894> & "co"'q' & <angle> "d" こんにちは 894
    item <895> & "co"'q' & <angle> "d" こんにちは 895
    item <896> & "co"'q' & <angle> "d" こんにちは 896
    item <897> & "co"'q' & <angle> "d" こんにちは 897
    item <898> & "co"'q' & <angle> "d" こんにちは 898
    item <899> & "co"'q' & <angle> "d" こんにちは 899
    item <900> & "co"'q' & <angle> "d" こんにちは 900
    item <901> & "co"'q' & <angle> "d" こんにちは 901
    item <902> & "co"'q' & <angle> "d" こんにちは 902
    item <903> & "co"'q' & <angle> "d" こんにちは 903
    item <904> & "co"'q' & <angle> "d" こんにちは 904
    item <905> & "co"'q' & <angle> "d" こんにちは 905
    item <906> & "co"'q' & <angle> "d" こんにちは 906
    item <907> & "co"'q' & <angle> "d" こんにちは 907
    item <908> & "co"'q' & <angle> "d" こんにちは 908
    item <909> & "co"'q' & <angle> "d" こんにちは 909
    item <910> & "co"'q' & <angle> "d" こんにちは 910
    item <911> & "co"'q' & <angle> "d" こんにちは 911
    item <912> & "co"'q' & <angle> "d" こんにちは 912
    item <913> & "co"'q' & <angle> "d" こんにちは 913
    item <914> & "co"'q' & <angle> "d" こんにちは 914
    item <915> & "co"'q' & <angle> "d" こんにちは 915
    item <916> & "co"'q' & <angle> "d" こんにちは 916
    item <917> & "co"'q' & <angle> "d" こんにちは 917
    item <918> & "co"'q' & <angle> "d" こんにちは 918
    item <919> & "co"'q' & <angle> "d" こんにちは 919
    item <920> & "co"'q' & <angle> "d" こんにちは 920
    item <921> & "co"'q' & <angle> "d" こんにちは 921
    item <922> & "co"'q' & <angle> "d" こんにちは 922
    item <923> & "co"'q' & <angle> "d" こんにちは 923
    item <924> & "co"'q' & <angle> "d" こんにちは 924
    item <925> & "co"'q' & <angle> "d" こんにちは 925
    item <926> & "co"'q' & <angle> "d" こんにちは 926
    item <927> & "co"'q' & <angle> "d" こんにちは 927
    item <928> & "co"'q' & <angle> "d" こんにちは 928
    item <929> & "co"'q' & <angle> "d" こんにちは 929
    item <930> & "co"'q' & <angle> "d" こんにちは 930
    item <931> & "co"'q' & <angle> "d" こんにちは 931
    item <932> & "co"'q' & <angle> "d" こんにちは 932
    item <933> & "co"'q' & <angle> "d" こんにちは 933
    item <934> & "co"'q' & <angle> "d" こんにちは 934
    item <935> & "co"'q' & <angle> "d" こんにちは 935
    item <936> & "co"'q' & <angle> "d" こんにちは 936
    item <937> & "co"'q' & <angle> "d" こんにちは 937
    item <938> & "co"'q' & <angle> "d" こんにちは 938
    item <939> & "co"'q' & <angle> "d" こんにちは 939
    item <940> & "co"'q' & <angle> "d" こんにちは 940
    item <941> & "co"'q' & <angle> "d" こんにちは 941
    item <942> & "co"'q' & <angle> "d" こんにちは 942
    item <943> & "co"'q' & <angle> "d" こんにちは 943
    item <944> & "co"'q' & <angle> "d" こんにちは 944
    item <945> & "co"'q' & <angle> "d" こんにちは 945
    item <946> & "co"'q' & <angle> "d" こんにちは 946
    item <947> & "co"'q' & <angle> "d" こんにちは 947
    item <948> & "co"'q' & <angle> "d" こんにちは 948
    item <949> & "co"'q' & <angle> "d" こんにちは 949
    item <950> & "co"'q' & <angle> "d" こんにちは 950
    item <951> & "co"'q' & <angle> "d" こんにちは 951
    item <952> & "co"'q' & <angle> "d" こんにちは 952
    item <953> & "co"'q' & <angle> "d" こんにちは 953
    item <954> & "co"'q' & <angle> "d" こんにちは 954
    item <955> & "co"'q' & <angle> "d" こんにちは 955
    item <956> & "co"'q' & <angle> "d" こんにちは 956
    item <957> & "co"'q' & <angle> "d" こんにちは 957
    item <958> & "co"'q' & <angle> "d" こんにちは 958
    item <959> & "co"'q' & <angle> "d" こんにちは 959
    item <960> & "co"'q' & <angle> "d" こんにちは 960
    item <961> & "co"'q' & <angle> "d" こんにちは 961
    item <962> & "co"'q' & <angle> "d" こんにちは 962
    item <963> & "co"'q' & <angle> "d" こんにちは 963
    item <964> & "co"'q' & <angle> "d" こんにちは 964
    item <965> & "co"'q' & <angle> "d" こんにちは 965
    item <966> & "co"'q' & <angle> "d" こんにちは 966
    item <967> & "co"'q' & <angle> "d" こんにちは 967
    item <968> & "co"'q' & <angle> "d" こんにちは 968
    item <969> & "co"'q' & <angle> "d" こんにちは 969
    item <970> & "co"'q' & <angle> "d" こんにちは 970
    item <971> & "co"'q' & <angle> "d" こんにちは 971
    item <972> & "co"'q' & <angle> "d" こんにちは 972
    item <973> & "co"'q' & <angle> "d" こんにちは 973
    item <974> & "co"'q' & <angle> "d" こんにちは 974
    item <975> & "co"'q' & <angle> "d" こんにちは 975
    item <976> & "co"'q' & <angle> "d" こんにちは 976
    item <977> & "co"'q' & <angle> "d" こんにちは 977
    item <978> & "co"'q' & <angle> "d" こんにちは 978
    item <979> & "co"'q' & <angle> "d" こんにちは 979
    item <980> & "co"'q' & <angle> "d" こんにちは 980
    item <981> & "co"'q' & <angle> "d" こんにちは 981
    item <982> & "co"'q' & <angle> "d" こんにちは 982
    item <983> & "co"'q' & <angle> "d" こんにちは 983
    item <984> & "co"'q' & <angle> "d" こんにちは 984
    item <985> & "co"'q' & <angle> "d" こんにちは 985
    item <986> & "co"'q' & <angle> "d" こんにちは 986
    item <987> & "co"'q' & <angle> "d" こんにちは 987
    item <988> & "co"'q' & <angle> "d" こんにちは 988
    item <989> & "co"'q' & <angle> "d" こんにちは 989
    item <990> & "co"'q' & <angle> "d" こんにちは 990
    item <991> & "co"'q' & <angle> "d" こんにちは 991
    item <992> & "co"'q' & <angle> "d" こんにちは 992
    item <993> & "co"'q' & <angle> "d" こんにちは 993
    item <994> & "co"'q' & <angle> "d" こんにちは 994
    item <995> & "co"'q' & <angle> "d" こんにちは 995
    item <996> & "co"'q' & <angle> "d" こんにちは 996
    item <997> & "co"'q' & <angle> "d" こんにちは 997
    item <998> & "co"'q' & <angle> "d" こんにちは 998
    item <999> & "co"'q' & <angle> "d" こんにちは 999
    item <1000> & "co"'q' & <angle> "d" こんにちは 1000
    item <1001> & "co"'q' & <angle> "d" こんにちは 1001
    item <1002> & "co"'q' & <angle> "d" こんにちは 1002
    item <1003> & "co"'q' & <angle> "d" こんにちは 1003
    item <1004> & "co"'q' & <angle> "d" こんにちは 1004
    item <1005> & "co"'q' & <angle> "d" こんにちは 1005
    item <1006> & "co"'q' & <angle> "d" こんにちは 1006
    item <1007> & "co"'q' & <angle> "d" こんにちは 1007
    item <1008> & "co"'q' & <angle> "d" こんにちは 1008
    item <1009> & "co"'q' & <angle> "d" こんにちは 1009
    item <1010> & "co"'q' & <angle> "d" こんにちは 1010
    item <1011> & "co"'q' & <angle> "d" こんにちは 1011
    item <1012> & "co"'q' & <angle> "d" こんにちは 1012
    item <1013> & "co"'q' & <angle> "d" こんにちは 1013
    item <1014> & "co"'q' & <angle> "d" こんにちは 1014
    item <1015> & "co"'q' & <angle> "d" こんにちは 1015
    item <1016> & "co"'q' & <angle> "d" こんにちは 1016
    item <1017> & "co"'q' & <angle> "d" こんにちは 1017
    item <1018> & "co"'q' & <angle> "d" こんにちは 1018
    item <1019> & "co"'q' & <angle> "d" こんにちは 1019
    item <1020> & "co"'q' & <angle> "d" こんにちは 1020
    item <1021> & "co"'q' & <angle> "d" こんにちは 1021
    item <1022> & "co"'q' & <angle> "d" こんにちは 1022
    item <1023> & "co"'q' & <angle> "d" こんにちは 1023
    item <1024> & "co"'q' & <angle> "d" こんにちは 1024
    item <1025> & "co"'q' & <angle> "d" こんにちは 1025
    item <1026> & "co"'q' & <angle> "d" こんにちは 1026
    item <1027> & "co"'q' & <angle> "d" こんにちは 1027
    item <1028> & "co"'q' & <angle> "d" こんにちは 1028
    item <1029> & "co"'q' & <angle> "d" こんにちは 1029
    item <1030> & "co"'q' & <angle> "d" こんにちは 1030
    item <1031> & "co"'q' & <angle> "d" こんにちは 1031
    item <1032> & "co"'q' & <angle> "d" こんにちは 1032
    item <1033> & "co"'q' & <angle> "d" こんにちは 1033
    item <1034> & "co"'q' & <angle> "d" こんにちは 1034
    item <1035> & "co"'q' & <angle> "d" こんにちは 1035
    item <1036> & "co"'q' & <angle> "d" こんにちは 1036
    item <1037> & "co"'q' & <angle> "d" こんにちは 1037
    item <1038> & "co"'q' & <angle> "d" こんにちは 1038
    item <1039> & "co"'q' & <angle> "d" こんにちは 1039
    item <1040> & "co"'q' & <angle> "d" こんにちは 1040
    item <1041> & "co"'q' & <angle> "d" こんにちは 1041
    item <1042> & "co"'q' & <angle> "d" こんにちは 1042
    item <1043> & "co"'q' & <angle> "d" こんにちは 1043
    item <1044> & "co"'q' & <angle> "d" こんにちは 1044
    item <1045> & "co"'q' & <angle> "d" こんにちは 1045
    item <1046> & "co"'q' & <angle> "d" こんにちは 1046
    item <1047> & "co"'q' & <angle> "d" こんにちは 1047
    item <1048> & "co"'q' & <angle> "d" こんにちは 1048
    item <1049> & "co"'q' & <angle> "d" こんにちは 1049
    item <1050> & "co"'q' & <angle> "d" こんにちは 1050
    item <1051> & "co"'q' & <angle> "d" こんにちは 1051
    item <1052> & "co"'q' & <angle> "d" こんにちは 1052
    item <1053> & "co"'q' & <angle> "d" こんにちは 1053
    item <1054> & "co"'q' & <angle> "d" こんにちは 1054
    item <1055> & "co"'q' & <angle> "d" こんにちは 1055
    item <1056> & "co"'q' & <angle> "d" こんにちは 1056
    item <1057> & "co"'q' & <angle> "d" こんにちは 1057
    item <1058> & "co"'q' & <angle> "d" こんにちは 1058
    item <1059> & "co"'q' & <angle> "d" こんにちは 1059
    item <1060> & "co"'q' & <angle> "d" こんにちは 1060
    item <1061> & "co"'q' & <angle> "d" こんにちは 1061
    item <1062> & "co"'q' & <angle> "d" こんにちは 1062
    item <1063> & "co"'q' & <angle> "d" こんにちは 1063
    item <1064> & "co"'q' & <angle> "d" こんにちは 1064
    item <1065> & "co"'q' & <angle> "d" こんにちは 1065
    item <1066> & "co"'q' & <angle> "d" こんにちは 1066
    item <1067> & "co"'q' & <angle> "d" こんにちは 1067
    item <1068> & "co"'q' & <angle> "d" こんにちは 1068
    item <1069> & "co"'q' & <angle> "d" こんにちは 1069
    item <1070> & "co"'q' & <angle> "d" こんにちは 1070
    item <1071> & "co"'q' & <angle> "d" こんにちは 1071
    item <1072> & "co"'q' & <angle> "d" こんにちは 1072
    item <1073> & "co"'q' & <angle> "d" こんにちは 1073
    item <1074> & "co"'q' & <angle> "d" こんにちは 1074
    item <1075> & "co"'q' & <angle> "d" こんにちは 1075
    item <1076> & "co"'q' & <angle> "d" こんにちは 1076
    item <1077> & "co"'q' & <angle> "d" こんにちは 1077
    item <1078> & "co"'q' & <angle> "d" こんにちは 1078
    item <1079> & "co"'q' & <angle> "d" こんにちは 1079
    item <1080> & "co"'q' & <angle> "d" こんにちは 1080
    item <1081> & "co"'q' & <angle> "d" こんにちは 1081
    item <1082> & "co"'q' & <angle> "d" こんにちは 1082
    item <1083> & "co"'q' & <angle> "d" こんにちは 1083
    item <1084> & "co"'q' & <angle> "d" こんにちは 1084
    item <1085> & "co"'q' & <angle> "d" こんにちは 1085
    item <1086> & "co"'q' & <angle> "d" こんにちは 1086
    item <1087> & "co"'q' & <angle> "d" こんにちは 1087
    item <1088> & "co"'q' & <angle> "d" こんにちは 1088
    item <1089> & "co"'q' & <angle> "d" こんにちは 1089
    item <1090> & "co"'q' & <angle> "d" こんにちは 1090
    item <1091> & "co"'q' & <angle> "d" こんにちは 1091
    item <1092> & "co"'q' & <angle> "d" こんにちは 1092
    item <1093> & "co"'q' & <angle> "d" こんにちは 1093
    item <1094> & "co"'q' & <angle> "d" こんにちは 1094
    item <1095> & "co"'q' & <angle> "d" こんにちは 1095
    item <1096> & "co"'q' & <angle> "d" こんにちは 1096
    item <1097> & "co"'q' & <angle> "d" こんにちは 1097
    item <1098> & "co"'q' & <angle> "d" こんにちは 1098
    item <1099> & "co"'q' & <angle> "d" こんにちは 1099
    item <1100> & "co"'q' & <angle> "d" こんにちは 1100
    item <1101> & "co"'q' & <angle> "d" こんにちは 1101
    item <1102> & "co"'q' & <angle> "d" こんにちは 1102
    item <1103> & "co"'q' & <angle> "d" こんにちは 1103
    item <1104> & "co"'q' & <angle> "d" こんにちは 1104
    item <1105> & "co"'q' & <angle> "d" こんにちは 1105
    item <1106> & "co"'q' & <angle> "d" こんにちは 1106
    item <1107> & "co"'q' & <angle> "d" こんにちは 1107
    item <1108> & "co"'q' & <angle> "d" こんにちは 1108
    item <1109> & "co"'q' & <angle> "d" こんにちは 1109
    item <1110> & "co"'q' & <angle> "d" こんにちは 1110
    item <1111> & "co"'q' & <angle> "d" こんにちは 1111
    item <1112> & "co"'q' & <angle> "d" こんにちは 1112
    item <1113> & "co"'q' & <angle> "d" こんにちは 1113
    item <1114> & "co"'q' & <angle> "d" こんにちは 1114
    item <1115> & "co"'q' & <angle> "d" こんにちは 1115
    item <1116> & "co"'q' & <angle> "d" こんにちは 1116
    item <1117> & "co"'q' & <angle> "d" こんにちは 1117
    item <1118> & "co"'q' & <angle> "d" こんにちは 1118
    item <1119> & "co"'q' & <angle> "d" こんにちは 1119
    item <1120> & "co"'q' & <angle> "d" こんにちは 1120
    item <1121> & "co"'q' & <angle> "d" こんにちは 1121
    item <1122> & "co"'q' & <angle> "d" こんにちは 1122
    item <1123> & "co"'q' & <angle> "d" こんにちは 1123
    item <1124> & "co"'q' & <angle> "d" こんにちは 1124
    item <1125> & "co"'q' & <angle> "d" こんにちは 1125
    item <1126> & "co"'q' & <angle> "d" こんにちは 1126
    item <1127> & "co"'q' & <angle> "d" こんにちは 1127
    item <1128> & "co"'q' & <angle> "d" こんにちは 1128
    item <1129> & "co"'q' & <angle> "d" こんにちは 1129
    item <1130> & "co"'q' & <angle> "d" こんにちは 1130
    item <1131> & "co"'q' & <angle> "d" こんにちは 1131
    item <1132> & "co"'q' & <angle> "d" こんにちは 1132
    item <1133> & "co"'q' & <angle> "d" こんにちは 1133
    item <1134> & "co"'q' & <angle> "d" こんにちは 1134
    item <1135> & "co"'q' & <angle> "d" こんにちは 1135
    item <1136> & "co"'q' & <angle> "d" こんにちは 1136
    item <1137> & "co"'q' & <angle> "d" こんにちは 1137
    item <1138> & "co"'q' & <angle> "d" こんにちは 1138
    item <1139> & "co"'q' & <angle> "d" こんにちは 1139
    item <1140> & "co"'q' & <angle> "d" こんにちは 1140
    item <1141> & "co"'q' & <angle> "d" こんにちは 1141
    item <1142> & "co"'q' & <angle> "d" こんにちは 1142
    item <1143> & "co"'q' & <angle> "d" こんにちは 1143
    item <1144> & "co"'q' & <angle> "d" こんにちは 1144
    item <1145> & "co"'q' & <angle> "d" こんにちは 1145
    item <1146> & "co"'q' & <angle> "d" こんにちは 1146
    item <1147> & "co"'q' & <angle> "d" こんにちは 1147
    item <1148> & "co"'q' & <angle> "d" こんにちは 1148
    item <1149> & "co"'q' & <angle> "d" こんにちは 1149
    item <1150> & "co"'q' & <angle> "d" こんにちは 1150
    item <1151> & "co"'q' & <angle> "d" こんにちは 1151
    item <1152> & "co"'q' & <angle> "d" こんにちは 1152
    item <1153> & "co"'q' & <angle> "d" こんにちは 1153
    item <1154> & "co"'q' & <angle> "d" こんにちは 1154
    item <1155> & "co"'q' & <angle> "d" こんにちは 1155
    item <1156> & "co"'q' & <angle> "d" こんにちは 1156
    item <1157> & "co"'q' & <angle> "d" こんにちは 1157
    item <1158> & "co"'q' & <angle> "d" こんにちは 1158
    item <1159> & "co"'q' & <angle> "d" こんにちは 1159
    item <1160> & "co"'q' & <angle> "d" こんにちは 1160
    item <1161> & "co"'q' & <angle> "d" こんにちは 1161
    item <1162> & "co"'q' & <angle> "d" こんにちは 1162
    item <1163> & "co"'q' & <angle> "d" こんにちは 1163
    item <1164> & "co"'q' & <angle> "d" こんにちは 1164
    item <1165> & "co"'q' & <angle> "d" こんにちは 1165
    item <1166> & "co"'q' & <angle> "d" こんにちは 1166
    item <1167> & "co"'q' & <angle> "d" こんにちは 1167
    item <1168> & "co"'q' & <angle> "d" こんにちは 1168
    item <1169> & "co"'q' & <angle> "d" こんにちは 1169
    item <1170> & "co"'q' & <angle> "d" こんにちは 1170
    item <1171> & "co"'q' & <angle> "d" こんにちは 1171
    item <1172> & "co"'q' & <angle> "d" こんにちは 1172
    item <1173> & "co"'q' & <angle> "d" こんにちは 1173
    item <1174> & "co"'q' & <angle> "d" こんにちは 1174
    item <1175> & "co"'q' & <angle> "d" こんにちは 1175
    item <1176> & "co"'q' & <angle> "d" こんにちは 1176
    item <1177> & "co"'q' & <angle> "d" こんにちは 1177
    item <1178> & "co"'q' & <angle> "d" こんにちは 1178
    item <1179> & "co"'q' & <angle> "d" こんにちは 1179
    item <1180> & "co"'q' & <angle> "d" こんにちは 1180
    item <1181> & "co"'q' & <angle> "d" こんにちは 1181
    item <1182> & "co"'q' & <angle> "d" こんにちは 1182
    item <1183> & "co"'q' & <angle> "d" こんにちは 1183
    item <1184> & "co"'q' & <angle> "d" こんにちは 1184
    item <1185> & "co"'q' & <angle> "d" こんにちは 1185
    item <1186> & "co"'q' & <angle> "d" こんにちは 1186
    item <1187> & "co"'q' & <angle> "d" こんにちは 1187
    item <1188> & "co"'q' & <angle> "d" こんにちは 1188
    item <1189> & "co"'q' & <angle> "d" こんにちは 1189
    item <1190> & "co"'q' & <angle> "d" こんにちは 1190
    item <1191> & "co"'q' & <angle> "d" こんにちは 1191
    item <1192> & "co"'q' & <angle> "d" こんにちは 1192
    item <1193> & "co"'q' & <angle> "d" こんにちは 1193
    item <1194> & "co"'q' & <angle> "d" こんにちは 1194
    item <1195> & "co"'q' & <angle> "d" こんにちは 1195
    item <1196> & "co"'q' & <angle> "d" こんにちは 1196
    item <1197> & "co"'q' & <angle> "d" こんにちは 1197
    item <1198> & "co"'q' & <angle> "d" こんにちは 1198
    item <1199> & "co"'q' & <angle> "d" こんにちは 1199
    item <1200> & "co"'q' & <angle> "d" こんにちは 1200
    item <1201> & "co"'q' & <angle> "d" こんにちは 1201
    item <1202> & "co"'q' & <angle> "d" こんにちは 1202
    item <1203> & "co"'q' & <angle> "d" こんにちは 1203
    item <1204> & "co"'q' & <angle> "d" こんにちは 1204
    item <1205> & "co"'q' & <angle> "d" こんにちは 1205
    item <1206> & "co"'q' & <angle> "d" こんにちは 1206
    item <1207> & "co"'q' & <angle> "d" こんにちは 1207
    item <1208> & "co"'q' & <angle> "d" こんにちは 1208
    item <1209> & "co"'q' & <angle> "d" こんにちは 1209
    item <1210> & "co"'q' & <angle> "d" こんにちは 1210
    item <1211> & "co"'q' & <angle> "d" こんにちは 1211
    item <1212> & "co"'q' & <angle> "d" こんにちは 1212
    item <1213> & "co"'q' & <angle> "d" こんにちは 1213
    item <1214> & "co"'q' & <angle> "d" こんにちは 1214
    item <1215> & "co"'q' & <angle> "d" こんにちは 1215
    item <1216> & "co"'q' & <angle> "d" こんにちは 1216
    item <1217> & "co"'q' & <angle> "d" こんにちは 1217
    item <1218> & "co"'q' & <angle> "d" こんにちは 1218
    item <1219> & "co"'q' & <angle> "d" こんにちは 1219
    item <1220> & "co"'q' & <angle> "d" こんにちは 1220
    item <1221> & "co"'q' & <angle> "d" こんにちは 1221
    item <1222> & "co"'q' & <angle> "d" こんにちは 1222
    item <1223> & "co"'q' & <angle> "d" こんにちは 1223
    item <1224> & "co"'q' & <angle> "d" こんにちは 1224
    item <1225> & "co"'q' & <angle> "d" こんにちは 1225
    item <1226> & "co"'q' & <angle> "d" こんにちは 1226
    item <1227> & "co"'q' & <angle> "d" こんにちは 1227
    item <1228> & "co"'q' & <angle> "d" こんにちは 1228
    item <1229> & "co"'q' & <angle> "d" こんにちは 1229
    item <1230> & "co"'q' & <angle> "d" こんにちは 1230
    item <1231> & "co"'q' & <angle> "d" こんにちは 1231
    item <1232> & "co"'q' & <angle> "d" こんにちは 1232
    item <1233> & "co"'q' & <angle> "d" こんにちは 1233
    item <1234> & "co"'q' & <angle> "d" こんにちは 1234
    item <1235> & "co"'q' & <angle> "d" こんにちは 1235
    item <1236> & "co"'q' & <angle> "d" こんにちは 1236
    item <1237> & "co"'q' & <angle> "d" こんにちは 1237
    item <1238> & "co"'q' & <angle> "d" こんにちは 1238
    item <1239> & "co"'q' & <angle> "d" こんにちは 1239
    item <1240> & "co"'q' & <angle> "d" こんにちは 1240
    item <1241> & "co"'q' & <angle> "d" こんにちは 1241
    item <1242> & "co"'q' & <angle> "d" こんにちは 1242
    item <1243> & "co"'q' & <angle> "d" こんにちは 1243
    item <1244> & "co"'q' & <angle> "d" こんにちは 1244
    item <1245> & "co"'q' & <angle> "d" こんにちは 1245
    item <1246> & "co"'q' & <angle> "d" こんにちは 1246
    item <1247> & "co"'q' & <angle> "d" こんにちは 1247
    item <1248> & "co"'q' & <angle> "d" こんにちは 1248
    item <1249> & "co"'q' & <angle> "d" こんにちは 1249
    item <1250> & "co"'q' & <angle> "d" こんにちは 1250
    item <1251> & "co"'q' & <angle> "d" こんにちは 1251
    item <1252> & "co"'q' & <angle> "d" こんにちは 1252
    item <1253> & "co"'q' & <angle> "d" こんにちは 1253
    item <1254> & "co"'q' & <angle> "d" こんにちは 1254
    item <1255> & "co"'q' & <angle> "d" こんにちは 1255
    item <1256> & "co"'q' & <angle> "d" こんにちは 1256
    item <1257> & "co"'q' & <angle> "d" こんにちは 1257
    item <1258> & "co"'q' & <angle> "d" こんにちは 1258
    item <1259> & "co"'q' & <angle> "d" こんにちは 1259
    item <1260> & "co"'q' & <angle> "d" こんにちは 1260
    item <1261> & "co"'q' & <angle> "d" こんにちは 1261
    item <1262> & "co"'q' & <angle> "d" こんにちは 1262
    item <1263> & "co"'q' & <angle> "d" こんにちは 1263
    item <1264> & "co"'q' & <angle> "d" こんにちは 1264
    item <1265> & "co"'q' & <angle> "d" こんにちは 1265
    item <1266> & "co"'q' & <angle> "d" こんにちは 1266
    item <1267> & "co"'q' & <angle> "d" こんにちは 1267
    item <1268> & "co"'q' & <angle> "d" こんにちは 1268
    item <1269> & "co"'q' & <angle> "d" こんにちは 1269
    item <1270> & "co"'q' & <angle> "d" こんにちは 1270
    item <1271> & "co"'q' & <angle> "d" こんにちは 1271
    item <1272> & "co"'q' & <angle> "d" こんにちは 1272
    item <1273> & "co"'q' & <angle> "d" こんにちは 1273
    item <1274> & "co"'q' & <angle> "d" こんにちは 1274
    item <1275> & "co"'q' & <angle> "d" こんにちは 1275
    item <1276> & "co"'q' & <angle> "d" こんにちは 1276
    item <1277> & "co"'q' & <angle> "d" こんにちは 1277
    item <1278> & "co"'q' & <angle> "d" こんにちは 1278
    item <1279> & "co"'q' & <angle> "d" こんにちは 1279
    item <1280> & "co"'q' & <angle> "d" こんにちは 1280
    item <1281> & "co"'q' & <angle> "d" こんにちは 1281
    item <1282> & "co"'q' & <angle> "d" こんにちは 1282
    item <1283> & "co"'q' & <angle> "d" こんにちは 1283
    item <1284> & "co"'q' & <angle> "d" こんにちは 1284
    item <1285> & "co"'q' & <angle> "d" こんにちは 1285
    item <1286> & "co"'q' & <angle> "d" こんにちは 1286
    item <1287> & "co"'q' & <angle> "d" こんにちは 1287
    item <1288> & "co"'q' & <angle> "d" こんにちは 1288
    item <1289> & "co"'q' & <angle> "d" こんにちは 1289
    item <1290> & "co"'q' & <angle> "d" こんにちは 1290
    item <1291> & "co"'q' & <angle> "d" こんにちは 1291
    item <1292> & "co"'q' & <angle> "d" こんにちは 1292
    item <1293> & "co"'q' & <angle> "d" こんにちは 1293
    item <1294> & "co"'q' & <angle> "d" こんにちは 1294
    item <1295> & "co"'q' & <angle> "d" こんにちは 1295
    item <1296> & "co"'q' & <angle> "d" こんにちは 1296
    item <1297> & "co"'q' & <angle> "d" こんにちは 1297
    item <1298> & "co"'q' & <angle> "d" こんにちは 1298
    item <1299> & "co"'q' & <angle> "d" こんにちは 1299
    item <1300> & "co"'q' & <angle> "d" こんにちは 1300
    item <1301> & "co"'q' & <angle> "d" こんにちは 1301
    item <1302> & "co"'q' & <angle> "d" こんにちは 1302
    item <1303> & "co"'q' & <angle> "d" こんにちは 1303
    item <1304> & "co"'q' & <angle> "d" こんにちは 1304
    item <1305> & "co"'q' & <angle> "d" こんにちは 1305
    item <1306> & "co"'q' & <angle> "d" こんにちは 1306
    item <1307> & "co"'q' & <angle> "d" こんにちは 1307
    item <1308> & "co"'q' & <angle> "d" こんにちは 1308
    item <1309> & "co"'q' & <angle> "d" こんにちは 1309
    item <1310> & "co"'q' & <angle> "d" こんにちは 1310
    item <1311> & "co"'q' & <angle> "d" こんにちは 1311
    item <1312> & "co"'q' & <angle> "d" こんにちは 1312
    item <1313> & "co"'q' & <angle> "d" こんにちは 1313
    item <1314> & "co"'q' & <angle> "d" こんにちは 1314
    item <1315> & "co"'q' & <angle> "d" こんにちは 1315
    item <1316> & "co"'q' & <angle> "d" こんにちは 1316
    item <1317> & "co"'q' & <angle> "d" こんにちは 1317
    item <1318> & "co"'q' & <angle> "d" こんにちは 1318
    item <1319> & "co"'q' & <angle> "d" こんにちは 1319
    item <1320> & "co"'q' & <angle> "d" こんにちは 1320
    item <1321> & "co"'q' & <angle> "d" こんにちは 1321
    item <1322> & "co"'q' & <angle> "d" こんにちは 1322
    item <1323> & "co"'q' & <angle> "d" こんにちは 1323
    item <1324> & "co"'q' & <angle> "d" こんにちは 1324
    item <1325> & "co"'q' & <angle> "d" こんにちは 1325
    item <1326> & "co"'q' & <angle> "d" こんにちは 1326
    item <1327> & "co"'q' & <angle> "d" こんにちは 1327
    item <1328> & "co"'q' & <angle> "d" こんにちは 1328
    item <1329> & "co"'q' & <angle> "d" こんにちは 1329
    item <1330> & "co"'q' & <angle> "d" こんにちは 1330
    item <1331> & "co"'q' & <angle> "d" こんにちは 1331
    item <1332> & "co"'q' & <angle> "d" こんにちは 1332
    item <1333> & "co"'q' & <angle> "d" こんにちは 1333
    item <1334> & "co"'q' & <angle> "d" こんにちは 1334
    item <1335> & "co"'q' & <angle> "d" こんにちは 1335
    item <1336> & "co"'q' & <angle> "d" こんにちは 1336
    item <1337> & "co"'q' & <angle> "d" こんにちは 1337
    item <1338> & "co"'q' & <angle> "d" こんにちは 1338
    item <1339> & "co"'q' & <angle> "d" こんにちは 1339
    item <1340> & "co"'q' & <angle> "d" こんにちは 1340
    item <1341> & "co"'q' & <angle> "d" こんにちは 1341
    item <1342> & "co"'q' & <angle> "d" こんにちは 1342
    item <1343> & "co"'q' & <angle> "d" こんにちは 1343
    item <1344> & "co"'q' & <angle> "d" こんにちは 1344
    item <1345> & "co"'q' & <angle> "d" こんにちは 1345
    item <1346> & "co"'q' & <angle> "d" こんにちは 1346
    item <1347> & "co"'q' & <angle> "d" こんにちは 1347
    item <1348> & "co"'q' & <angle> "d" こんにちは 1348
    item <1349> & "co"'q' & <angle> "d" こんにちは 1349
    item <1350> & "co"'q' & <angle> "d" こんにちは 1350
    item <1351> & "co"'q' & <angle> "d" こんにちは 1351
    item <1352> & "co"'q' & <angle> "d" こんにちは 1352
    item <1353> & "co"'q' & <angle> "d" こんにちは 1353
    item <1354> & "co"'q' & <angle> "d" こんにちは 1354
    item <1355> & "co"'q' & <angle> "d" こんにちは 1355
    item <1356> & "co"'q' & <angle> "d" こんにちは 1356
    item <1357> & "co"'q' & <angle> "d" こんにちは 1357
    item <1358> & "co"'q' & <angle> "d" こんにちは 1358
    item <1359> & "co"'q' & <angle> "d" こんにちは 1359
    item <1360> & "co"'q' & <angle> "d" こんにちは 1360
    item <1361> & "co"'q' & <angle> "d" こんにちは 1361
    item <1362> & "co"'q' & <angle> "d" こんにちは 1362
    item <1363> & "co"'q' & <angle> "d" こんにちは 1363
    item <1364> & "co"'q' & <angle> "d" こんにちは 1364
    item <1365> & "co"'q' & <angle> "d" こんにちは 1365
    item <1366> & "co"'q' & <angle> "d" こんにちは 1366
    item <1367> & "co"'q' & <angle> "d" こんにちは 1367
    item <1368> & "co"'q' & <angle> "d" こんにちは 1368
    item <1369> & "co"'q' & <angle> "d" こんにちは 1369
    item <1370> & "co"'q' & <angle> "d" こんにちは 1370
    item <1371> & "co"'q' & <angle> "d" こんにちは 1371
    item <1372> & "co"'q' & <angle> "d" こんにちは 1372
    item <1373> & "co"'q' & <angle> "d" こんにちは 1373
    item <1374> & "co"'q' & <angle> "d" こんにちは 1374
    item <1375> & "co"'q' & <angle> "d" こんにちは 1375
    item <1376> & "co"'q' & <angle> "d" こんにちは 1376
    item <1377> & "co"'q' & <angle> "d" こんにちは 1377
    item <1378> & "co"'q' & <angle> "d" こんにちは 1378
    item <1379> & "co"'q' & <angle> "d" こんにちは 1379
    item <1380> & "co"'q' & <angle> "d" こんにちは 1380
    item <1381> & "co"'q' & <angle> "d" こんにちは 1381
    item <1382> & "co"'q' & <angle> "d" こんにちは 1382
    item <1383> & "co"'q' & <angle> "d" こんにちは 1383
    item <1384> & "co"'q' & <angle> "d" こんにちは 1384
    item <1385> & "co"'q' & <angle> "d" こんにちは 1385
    item <1386> & "co"'q' & <angle> "d" こんにちは 1386
    item <1387> & "co"'q' & <angle> "d" こんにちは 1387
    item <1388> & "co"'q' & <angle> "d" こんにちは 1388
    item <1389> & "co"'q' & <angle> "d" こんにちは 1389
    item <1390> & "co"'q' & <angle> "d" こんにちは 1390
    item <1391> & "co"'q' & <angle> "d" こんにちは 1391
    item <1392> & "co"'q' & <angle> "d" こんにちは 1392
    item <1393> & "co"'q' & <angle> "d" こんにちは 1393
    item <1394> & "co"'q' & <angle> "d" こんにちは 1394
    item <1395> & "co"'q' & <angle> "d" こんにちは 1395
    item <1396> & "co"'q' & <angle> "d" こんにちは 1396
    item <1397> & "co"'q' & <angle> "d" こんにちは 1397
    item <1398> & "co"'q' & <angle> "d" こんにちは 1398
    item <1399> & "co"'q' & <angle> "d" こんにちは 1399
    item <1400> & "co"'q' & <angle> "d" こんにちは 1400
    item <1401> & "co"'q' & <angle> "d" こんにちは 1401
    item <1402> & "co"'q' & <angle> "d" こんにちは 1402
    item <1403> & "co"'q' & <angle> "d" こんにちは 1403
    item <1404> & "co"'q' & <angle> "d" こんにちは 1404
    item <1405> & "co"'q' & <angle> "d" こんにちは 1405
    item <1406> & "co"'q' & <angle> "d" こんにちは 1406
    item <1407> & "co"'q' & <angle> "d" こんにちは 1407
    item <1408> & "co"'q' & <angle> "d" こんにちは 1408
    item <1409> & "co"'q' & <angle> "d" こんにちは 1409
    item <1410> & "co"'q' & <angle> "d" こんにちは 1410
    item <1411> & "co"'q' & <angle> "d" こんにちは 1411
    item <1412> & "co"'q' & <angle> "d" こんにちは 1412
    item <1413> & "co"'q' & <angle> "d" こんにちは 1413
    item <1414> & "co"'q' & <angle> "d" こんにちは 1414
    item <1415> & "co"'q' & <angle> "d" こんにちは 1415
    item <1416> & "co"'q' & <angle> "d" こんにちは 1416
    item <1417> & "co"'q' & <angle> "d" こんにちは 1417
    item <1418> & "co"'q' & <angle> "d" こんにちは 1418
    item <1419> & "co"'q' & <angle> "d" こんにちは 1419
    item <1420> & "co"'q' & <angle> "d" こんにちは 1420
    item <1421> & "co"'q' & <angle> "d" こんにちは 1421
    item <1422> & "co"'q' & <angle> "d" こんにちは 1422
    item <1423> & "co"'q' & <angle> "d" こんにちは 1423
    item <1424> & "co"'q' & <angle> "d" こんにちは 1424
    item <1425> & "co"'q' & <angle> "d" こんにちは 1425
    item <1426> & "co"'q' & <angle> "d" こんにちは 1426
    item <1427> & "co"'q' & <angle> "d" こんにちは 1427
    item <1428> & "co"'q' & <angle> "d" こんにちは 1428
    item <1429> & "co"'q' & <angle> "d" こんにちは 1429
    item <1430> & "co"'q' & <angle> "d" こんにちは 1430
    item <1431> & "co"'q' & <angle> "d" こんにちは 1431
    item <1432> & "co"'q' & <angle> "d" こんにちは 1432
    item <1433> & "co"'q' & <angle> "d" こんにちは 1433
    item <1434> & "co"'q' & <angle> "d" こんにちは 1434
    item <1435> & "co"'q' & <angle> "d" こんにちは 1435
    item <1436> & "co"'q' & <angle> "d" こんにちは 1436
    item <1437> & "co"'q' & <angle> "d" こんにちは 1437
    item <1438> & "co"'q' & <angle> "d" こんにちは 1438
    item <1439> & "co"'q' & <angle> "d" こんにちは 1439
    item <1440> & "co"'q' & <angle> "d" こんにちは 1440
    item <1441> & "co"'q' & <angle> "d" こんにちは 1441
    item <1442> & "co"'q' & <angle> "d" こんにちは 1442
    item <1443> & "co"'q' & <angle> "d" こんにちは 1443
    item <1444> & "co"'q' & <angle> "d" こんにちは 1444
    item <1445> & "co"'q' & <angle> "d" こんにちは 1445
    item <1446> & "co"'q' & <angle> "d" こんにちは 1446
    item <1447> & "co"'q' & <angle> "d" こんにちは 1447
    item <1448> & "co"'q' & <angle> "d" こんにちは 1448
    item <1449> & "co"'q' & <angle> "d" こんにちは 1449
    item <1450> & "co"'q' & <angle> "d" こんにちは 1450
    item <1451> & "co"'q' & <angle> "d" こんにちは 1451
    item <1452> & "co"'q' & <angle> "d" こんにちは 1452
    item <1453> & "co"'q' & <angle> "d" こんにちは 1453
    item <1454> & "co"'q' & <angle> "d" こんにちは 1454
    item <1455> & "co"'q' & <angle> "d" こんにちは 1455
    item <1456> & "co"'q' & <angle> "d" こんにちは 1456
    item <1457> & "co"'q' & <angle> "d" こんにちは 1457
    item <1458> & "co"'q' & <angle> "d" こんにちは 1458
    item <1459> & "co"'q' & <angle> "d" こんにちは 1459
    item <1460> & "co"'q' & <angle> "d" こんにちは 1460
    item <1461> & "co"'q' & <angle> "d" こんにちは 1461
    item <1462> & "co"'q' & <angle> "d" こんにちは 1462
    item <1463> & "co"'q' & <angle> "d" こんにちは 1463
    item <1464> & "co"'q' & <angle> "d" こんにちは 1464
    item <1465> & "co"'q' & <angle> "d" こんにちは 1465
    item <1466> & "co"'q' & <angle> "d" こんにちは 1466
    item <1467> & "co"'q' & <angle> "d" こんにちは 1467
    item <1468> & "co"'q' & <angle> "d" こんにちは 1468
    item <1469> & "co"'q' & <angle> "d" こんにちは 1469
    item <1470> & "co"'q' & <angle> "d" こんにちは 1470
    item <1471> & "co"'q' & <angle> "d" こんにちは 1471
    item <1472> & "co"'q' & <angle> "d" こんにちは 1472
    item <1473> & "co"'q' & <angle> "d" こんにちは 1473
    item <1474> & "co"'q' & <angle> "d" こんにちは 1474
    item <1475> & "co"'q' & <angle> "d" こんにちは 1475
    item <1476> & "co"'q' & <angle> "d" こんにちは 1476
    item <1477> & "co"'q' & <angle> "d" こんにちは 1477
    item <1478> & "co"'q' & <angle> "d" こんにちは 1478
    item <1479> & "co"'q' & <angle> "d" こんにちは 1479
    item <1480> & "co"'q' & <angle> "d" こんにちは 1480
    item <1481> & "co"'q' & <angle> "d" こんにちは 1481
    item <1482> & "co"'q' & <angle> "d" こんにちは 1482
    item <1483> & "co"'q' & <angle> "d" こんにちは 1483
    item <1484> & "co"'q' & <angle> "d" こんにちは 1484
    item <1485> & "co"'q' & <angle> "d" こんにちは 1485
    item <1486> & "co"'q' & <angle> "d" こんにちは 1486
    item <1487> & "co"'q' & <angle> "d" こんにちは 1487
    item <1488> & "co"'q' & <angle> "d" こんにちは 1488
    item <1489> & "co"'q' & <angle> "d" こんにちは 1489
    item <1490> & "co"'q' & <angle> "d" こんにちは 1490
    item <1491> & "co"'q' & <angle> "d" こんにちは 1491
    item <1492> & "co"'q' & <angle> "d" こんにちは 1492
    item <1493> & "co"'q' & <angle> "d" こんにちは 1493
    item <1494> & "co"'q' & <angle> "d" こんにちは 1494
    item <1495> & "co"'q' & <angle> "d" こんにちは 1495
    item <1496> & "co"'q' & <angle> "d" こんにちは 1496
    item <1497> & "co"'q' & <angle> "d" こんにちは 1497
    item <1498> & "co"'q' & <angle> "d" こんにちは 1498
    item <1499> & "co"'q' & <angle> "d" こんにちは 1499
    item <1500> & "co"'q' & <angle> "d" こんにちは 1500
    item <1501> & "co"'q' & <angle> "d" こんにちは 1501
    item <1502> & "co"'q' & <angle> "d" こんにちは 1502
    item <1503> & "co"'q' & <angle> "d" こんにちは 1503
    item <1504> & "co"'q' & <angle> "d" こんにちは 1504
    item <1505> & "co"'q' & <angle> "d" こんにちは 1505
    item <1506> & "co"'q' & <angle> "d" こんにちは 1506
    item <1507> & "co"'q' & <angle> "d" こんにちは 1507
    item <1508> & "co"'q' & <angle> "d" こんにちは 1508
    item <1509> & "co"'q' & <angle> "d" こんにちは 1509
    item <1510> & "co"'q' & <angle> "d" こんにちは 1510
    item <1511> & "co"'q' & <angle> "d" こんにちは 1511
    item <1512> & "co"'q' & <angle> "d" こんにちは 1512
    item <1513> & "co"'q' & <angle> "d" こんにちは 1513
    item <1514> & "co"'q' & <angle> "d" こんにちは 1514
    item <1515> & "co"'q' & <angle> "d" こんにちは 1515
    item <1516> & "co"'q' & <angle> "d" こんにちは 1516
    item <1517> & "co"'q' & <angle> "d" こんにちは 1517
    item <1518> & "co"'q' & <angle> "d" こんにちは 1518
    item <1519> & "co"'q' & <angle> "d" こんにちは 1519
    item <1520> & "co"'q' & <angle> "d" こんにちは 1520
    item <1521> & "co"'q' & <angle> "d" こんにちは 1521
    item <1522> & "co"'q' & <angle> "d" こんにちは 1522
    item <1523> & "co"'q' & <angle> "d" こんにちは 1523
    item <1524> & "co"'q' & <angle> "d" こんにちは 1524
    item <1525> & "co"'q' & <angle> "d" こんにちは 1525
    item <1526> & "co"'q' & <angle> "d" こんにちは 1526
    item <1527> & "co"'q' & <angle> "d" こんにちは 1527
    item <1528> & "co"'q' & <angle> "d" こんにちは 1528
    item <1529> & "co"'q' & <angle> "d" こんにちは 1529
    item <1530> & "co"'q' & <angle> "d" こんにちは 1530
    item <1531> & "co"'q' & <angle> "d" こんにちは 1531
    item <1532> & "co"'q' & <angle> "d" こんにちは 1532
    item <1533> & "co"'q' & <angle> "d" こんにちは 1533
    item <1534> & "co"'q' & <angle> "d" こんにちは 1534
    item <1535> & "co"'q' & <angle> "d" こんにちは 1535
    item <1536> & "co"'q' & <angle> "d" こんにちは 1536
    item <1537> & "co"'q' & <angle> "d" こんにちは 1537
    item <1538> & "co"'q' & <angle> "d" こんにちは 1538
    item <1539> & "co"'q' & <angle> "d" こんにちは 1539
    item <1540> & "co"'q' & <angle> "d" こんにちは 1540
    item <1541> & "co"'q' & <angle> "d" こんにちは 1541
    item <1542> & "co"'q' & <angle> "d" こんにちは 1542
    item <1543> & "co"'q' & <angle> "d" こんにちは 1543
    item <1544> & "co"'q' & <angle> "d" こんにちは 1544
    item <1545> & "co"'q' & <angle> "d" こんにちは 1545
    item <1546> & "co"'q' & <angle> "d" こんにちは 1546
    item <1547> & "co"'q' & <angle> "d" こんにちは 1547
    item <1548> & "co"'q' & <angle> "d" こんにちは 1548
    item <1549> & "co"'q' & <angle> "d" こんにちは 1549
    item <1550> & "co"'q' & <angle> "d" こんにちは 1550
    item <1551> & "co"'q' & <angle> "d" こんにちは 1551
    item <1552> & "co"'q' & <angle> "d" こんにちは 1552
    item <1553> & "co"'q' & <angle> "d" こんにちは 1553
    item <1554> & "co"'q' & <angle> "d" こんにちは 1554
    item <1555> & "co"'q' & <angle> "d" こんにちは 1555
    item <1556> & "co"'q' & <angle> "d" こんにちは 1556
    item <1557> & "co"'q' & <angle> "d" こんにちは 1557
    item <1558> & "co"'q' & <angle> "d" こんにちは 1558
    item <1559> & "co"'q' & <angle> "d" こんにちは 1559
    item <1560> & "co"'q' & <angle> "d" こんにちは 1560
    item <1561> & "co"'q' & <angle> "d" こんにちは 1561
    item <1562> & "co"'q' & <angle> "d" こんにちは 1562
    item <1563> & "co"'q' & <angle> "d" こんにちは 1563
    item <1564> & "co"'q' & <angle> "d" こんにちは 1564
    item <1565> & "co"'q' & <angle> "d" こんにちは 1565
    item <1566> & "co"'q' & <angle> "d" こんにちは 1566
    item <1567> & "co"'q' & <angle> "d" こんにちは 1567
    item <1568> & "co"'q' & <angle> "d" こんにちは 1568
    item <1569> & "co"'q' & <angle> "d" こんにちは 1569
    item <1570> & "co"'q' & <angle> "d" こんにちは 1570
    item <1571> & "co"'q' & <angle> "d" こんにちは 1571
    item <1572> & "co"'q' & <angle> "d" こんにちは 1572
    item <1573> & "co"'q' & <angle> "d" こんにちは 1573
    item <1574> & "co"'q' & <angle> "d" こんにちは 1574
    item <1575> & "co"'q' & <angle> "d" こんにちは 1575
    item <1576> & "co"'q' & <angle> "d" こんにちは 1576
    item <1577> & "co"'q' & <angle> "d" こんにちは 1577
    item <1578> & "co"'q' & <angle> "d" こんにちは 1578
    item <1579> & "co"'q' & <angle> "d" こんにちは 1579
    item <1580> & "co"'q' & <angle> "d" こんにちは 1580
    item <1581> & "co"'q' & <angle> "d" こんにちは 1581
    item <1582> & "co"'q' & <angle> "d" こんにちは 1582
    item <1583> & "co"'q' & <angle> "d" こんにちは 1583
    item <1584> & "co"'q' & <angle> "d" こんにちは 1584
    item <1585> & "co"'q' & <angle> "d" こんにちは 1585
    item <1586> & "co"'q' & <angle> "d" こんにちは 1586
    item <1587> & "co"'q' & <angle> "d" こんにちは 1587
    item <1588> & "co"'q' & <angle> "d" こんにちは 1588
    item <1589> & "co"'q' & <angle> "d" こんにちは 1589
    item <1590> & "co"'q' & <angle> "d" こんにちは 1590
    item <1591> & "co"'q' & <angle> "d" こんにちは 1591
    item <1592> & "co"'q' & <angle> "d" こんにちは 1592
    item <1593> & "co"'q' & <angle> "d" こんにちは 1593
    item <1594> & "co"'q' & <angle> "d" こんにちは 1594
    item <1595> & "co"'q' & <angle> "d" こんにちは 1595
    item <1596> & "co"'q' & <angle> "d" こんにちは 1596
    item <1597> & "co"'q' & <angle> "d" こんにちは 1597
    item <1598> & "co"'q' & <angle> "d" こんにちは 1598
    item <1599> & "co"'q' & <angle> "d" こんにちは 1599
    item <1600> & "co"'q' & <angle> "d" こんにちは 1600
    item <1601> & "co"'q' & <angle> "d" こんにちは 1601
    item <1602> & "co"'q' & <angle> "d" こんにちは 1602
    item <1603> & "co"'q' & <angle> "d" こんにちは 1603
    item <1604> & "co"'q' & <angle> "d" こんにちは 1604
    item <1605> & "co"'q' & <angle> "d" こんにちは 1605
    item <1606> & "co"'q' & <angle> "d" こんにちは 1606
    item <1607> & "co"'q' & <angle> "d" こんにちは 1607
    item <1608> & "co"'q' & <angle> "d" こんにちは 1608
    item <1609> & "co"'q' & <angle> "d" こんにちは 1609
    item <1610> & "co"'q' & <angle> "d" こんにちは 1610
    item <1611> & "co"'q' & <angle> "d" こんにちは 1611
    item <1612> & "co"'q' & <angle> "d" こんにちは 1612
    item <1613> & "co"'q' & <angle> "d" こんにちは 1613
    item <1614> & "co"'q' & <angle> "d" こんにちは 1614
    item <1615> & "co"'q' & <angle> "d" こんにちは 1615
    item <1616> & "co"'q' & <angle> "d" こんにちは 1616
    item <1617> & "co"'q' & <angle> "d" こんにちは 1617
    item <1618> & "co"'q' & <angle> "d" こんにちは 1618
    item <1619> & "co"'q' & <angle> "d" こんにちは 1619
    item <1620> & "co"'q' & <angle> "d" こんにちは 1620
    item <1621> & "co"'q' & <angle> "d" こんにちは 1621
    item <1622> & "co"'q' & <angle> "d" こんにちは 1622
    item <1623> & "co"'q' & <angle> "d" こんにちは 1623
    item <1624> & "co"'q' & <angle> "d" こんにちは 1624
    item <1625> & "co"'q' & <angle> "d" こんにちは 1625
    item <1626> & "co"'q' & <angle> "d" こんにちは 1626
    item <1627> & "co"'q' & <angle> "d" こんにちは 1627
    item <1628> & "co"'q' & <angle> "d" こんにちは 1628
    item <1629> & "co"'q' & <angle> "d" こんにちは 1629
    item <1630> & "co"'q' & <angle> "d" こんにちは 1630
    item <1631> & "co"'q' & <angle> "d" こんにちは 1631
    item <1632> & "co"'q' & <angle> "d" こんにちは 1632
    item <1633> & "co"'q' & <angle> "d" こんにちは 1633
    item <1634> & "co"'q' & <angle> "d" こんにちは 1634
    item <1635> & "co"'q' & <angle> "d" こんにちは 1635
    item <1636> & "co"'q' & <angle> "d" こんにちは 1636
    item <1637> & "co"'q' & <angle> "d" こんにちは 1637
    item <1638> & "co"'q' & <angle> "d" こんにちは 1638
    item <1639> & "co"'q' & <angle> "d" こんにちは 1639
    item <1640> & "co"'q' & <angle> "d" こんにちは 1640
    item <1641> & "co"'q' & <angle> "d" こんにちは 1641
    item <1642> & "co"'q' & <angle> "d" こんにちは 1642
    item <1643> & "co"'q' & <angle> "d" こんにちは 1643
    item <1644> & "co"'q' & <angle> "d" こんにちは 1644
    item <1645> & "co"'q' & <angle> "d" こんにちは 1645
    item <1646> & "co"'q' & <angle> "d" こんにちは 1646
    item <1647> & "co"'q' & <angle> "d" こんにちは 1647
    item <1648> & "co"'q' & <angle> "d" こんにちは 1648
    item <1649> & "co"'q' & <angle> "d" こんにちは 1649
    item <1650> & "co"'q' & <angle> "d" こんにちは 1650
    item <1651> & "co"'q' & <angle> "d" こんにちは 1651
    item <1652> & "co"'q' & <angle> "d" こんにちは 1652
    item <1653> & "co"'q' & <angle> "d" こんにちは 1653
    item <1654> & "co"'q' & <angle> "d" こんにちは 1654
    item <1655> & "co"'q' & <angle> "d" こんにちは 1655
    item <1656> & "co"'q' & <angle> "d" こんにちは 1656
    item <1657> & "co"'q' & <angle> "d" こんにちは 1657
    item <1658> & "co"'q' & <angle> "d" こんにちは 1658
    item <1659> & "co"'q' & <angle> "d" こんにちは 1659
    item <1660> & "co"'q' & <angle> "d" こんにちは 1660
    item <1661> & "co"'q' & <angle> "d" こんにちは 1661
    item <1662> & "co"'q' & <angle> "d" こんにちは 1662
    item <1663> & "co"'q' & <angle> "d" こんにちは 1663
    item <1664> & "co"'q' & <angle> "d" こんにちは 1664
    item <1665> & "co"'q' & <angle> "d" こんにちは 1665
    item <1666> & "co"'q' & <angle> "d" こんにちは 1666
    item <1667> & "co"'q' & <angle> "d" こんにちは 1667
    item <1668> & "co"'q' & <angle> "d" こんにちは 1668
    item <1669> & "co"'q' & <angle> "d" こんにちは 1669
    item <1670> & "co"'q' & <angle> "d" こんにちは 1670
    item <1671> & "co"'q' & <angle> "d" こんにちは 1671
    item <1672> & "co"'q' & <angle> "d" こんにちは 1672
    item <1673> & "co"'q' & <angle> "d" こんにちは 1673
    item <1674> & "co"'q' & <angle> "d" こんにちは 1674
    item <1675> & "co"'q' & <angle> "d" こんにちは 1675
    item <1676> & "co"'q' & <angle> "d" こんにちは 1676
    item <1677> & "co"'q' & <angle> "d" こんにちは 1677
    item <1678> & "co"'q' & <angle> "d" こんにちは 1678
    item <1679> & "co"'q' & <angle> "d" こんにちは 1679
    item <1680> & "co"'q' & <angle> "d" こんにちは 1680
    item <1681> & "co"'q' & <angle> "d" こんにちは 1681
    item <1682> & "co"'q' & <angle> "d" こんにちは 1682
    item <1683> & "co"'q' & <angle> "d" こんにちは 1683
    item <1684> & "co"'q' & <angle> "d" こんにちは 1684
    item <1685> & "co"'q' & <angle> "d" こんにちは 1685
    item <1686> & "co"'q' & <angle> "d" こんにちは 1686
    item <1687> & "co"'q' & <angle> "d" こんにちは 1687
    item <1688> & "co"'q' & <angle> "d" こんにちは 1688
    item <1689> & "co"'q' & <angle> "d" こんにちは 1689
    item <1690> & "co"'q' & <angle> "d" こんにちは 1690
    item <1691> & "co"'q' & <angle> "d" こんにちは 1691
    item <1692> & "co"'q' & <angle> "d" こんにちは 1692
    item <1693> & "co"'q' & <angle> "d" こんにちは 1693
    item <1694> & "co"'q' & <angle> "d" こんにちは 1694
    item <1695> & "co"'q' & <angle> "d" こんにちは 1695
    item <1696> & "co"'q' & <angle> "d" こんにちは 1696
    item <1697> & "co"'q' & <angle> "d" こんにちは 1697
    item <1698> & "co"'q' & <angle> "d" こんにちは 1698
    item <1699> & "co"'q' & <angle> "d" こんにちは 1699
    item <1700> & "co"'q' & <angle> "d" こんにちは 1700
    item <1701> & "co"'q' & <angle> "d" こんにちは 1701
    item <1702> & "co"'q' & <angle> "d" こんにちは 1702
    item <1703> & "co"'q' & <angle> "d" こんにちは 1703
    item <1704> & "co"'q' & <angle> "d" こんにちは 1704
    item <1705> & "co"'q' & <angle> "d" こんにちは 1705
    item <1706> & "co"'q' & <angle> "d" こんにちは 1706
    item <1707> & "co"'q' & <angle> "d" こんにちは 1707
    item <1708> & "co"'q' & <angle> "d" こんにちは 1708
    item <1709> & "co"'q' & <angle> "d" こんにちは 1709
    item <1710> & "co"'q' & <angle> "d" こんにちは 1710
    item <1711> & "co"'q' & <angle> "d" こんにちは 1711
    item <1712> & "co"'q' & <angle> "d" こんにちは 1712
    item <1713> & "co"'q' & <angle> "d" こんにちは 1713
    item <1714> & "co"'q' & <angle> "d" こんにちは 1714
    item <1715> & "co"'q' & <angle> "d" こんにちは 1715
    item <1716> & "co"'q' & <angle> "d" こんにちは 1716
    item <1717> & "co"'q' & <angle> "d" こんにちは 1717
    item <1718> & "co"'q' & <angle> "d" こんにちは 1718
    item <1719> & "co"'q' & <angle> "d" こんにちは 1719
    item <1720> & "co"'q' & <angle> "d" こんにちは 1720
    item <1721> & "co"'q' & <angle> "d" こんにちは 1721
    item <1722> & "co"'q' & <angle> "d" こんにちは 1722
    item <1723> & "co"'q' & <angle> "d" こんにちは 1723
    item <1724> & "co"'q' & <angle> "d" こんにちは 1724
    item <1725> & "co"'q' & <angle> "d" こんにちは 1725
    item <1726> & "co"'q' & <angle> "d" こんにちは 1726
    item <1727> & "co"'q' & <angle> "d" こんにちは 1727
    item <1728> & "co"'q' & <angle> "d" こんにちは 1728
    item <1729> & "co"'q' & <angle> "d" こんにちは 1729
    item <1730> & "co"'q' & <angle> "d" こんにちは 1730
    item <1731> & "co"'q' & <angle> "d" こんにちは 1731
    item <1732> & "co"'q' & <angle> "d" こんにちは 1732
    item <1733> & "co"'q' & <angle> "d" こんにちは 1733
    item <1734> & "co"'q' & <angle> "d" こんにちは 1734
    item <1735> & "co"'q' & <angle> "d" こんにちは 1735
    item <1736> & "co"'q' & <angle> "d" こんにちは 1736
    item <1737> & "co"'q' & <angle> "d" こんにちは 1737
    item <1738> & "co"'q' & <angle> "d" こんにちは 1738
    item <1739> & "co"'q' & <angle> "d" こんにちは 1739
    item <1740> & "co"'q' & <angle> "d" こんにちは 1740
    item <1741> & "co"'q' & <angle> "d" こんにちは 1741
    item <1742> & "co"'q' & <angle> "d" こんにちは 1742
    item <1743> & "co"'q' & <angle> "d" こんにちは 1743
    item <1744> & "co"'q' & <angle> "d" こんにちは 1744
    item <1745> & "co"'q' & <angle> "d" こんにちは 1745
    item <1746> & "co"'q' & <angle> "d" こんにちは 1746
    item <1747> & "co"'q' & <angle> "d" こんにちは 1747
    item <1748> & "co"'q' & <angle> "d" こんにちは 1748
    item <1749> & "co"'q' & <angle> "d" こんにちは 1749
    item <1750> & "co"'q' & <angle> "d" こんにちは 1750
    item <1751> & "co"'q' & <angle> "d" こんにちは 1751
    item <1752> & "co"'q' & <angle> "d" こんにちは 1752
    item <1753> & "co"'q' & <angle> "d" こんにちは 1753
    item <1754> & "co"'q' & <angle> "d" こんにちは 1754
    item <1755> & "co"'q' & <angle> "d" こんにちは 1755
    item <1756> & "co"'q' & <angle> "d" こんにちは 1756
    item <1757> & "co"'q' & <angle> "d" こんにちは 1757
    item <1758> & "co"'q' & <angle> "d" こんにちは 1758
    item <1759> & "co"'q' & <angle> "d" こんにちは 1759
    item <1760> & "co"'q' & <angle> "d" こんにちは 1760
    item <1761> & "co"'q' & <angle> "d" こんにちは 1761
    item <1762> & "co"'q' & <angle> "d" こんにちは 1762
    item <1763> & "co"'q' & <angle> "d" こんにちは 1763
    item <1764> & "co"'q' & <angle> "d" こんにちは 1764
    item <1765> & "co"'q' & <angle> "d" こんにちは 1765
    item <1766> & "co"'q' & <angle> "d" こんにちは 1766
    item <1767> & "co"'q' & <angle> "d" こんにちは 1767
    item <1768> & "co"'q' & <angle> "d" こんにちは 1768
    item <1769> & "co"'q' & <angle> "d" こんにちは 1769
    item <1770> & "co"'q' & <angle> "d" こんにちは 1770
    item <1771> & "co"'q' & <angle> "d" こんにちは 1771
    item <1772> & "co"'q' & <angle> "d" こんにちは 1772
    item <1773> & "co"'q' & <angle> "d" こんにちは 1773
    item <1774> & "co"'q' & <angle> "d" こんにちは 1774
    item <1775> & "co"'q' & <angle> "d" こんにちは 1775
    item <1776> & "co"'q' & <angle> "d" こんにちは 1776
    item <1777> & "co"'q' & <angle> "d" こんにちは 1777
    item <1778> & "co"'q' & <angle> "d" こんにちは 1778
    item <1779> & "co"'q' & <angle> "d" こんにちは 1779
    item <1780> & "co"'q' & <angle> "d" こんにちは 1780
    item <1781> & "co"'q' & <angle> "d" こんにちは 1781
    item <1782> & "co"'q' & <angle> "d" こんにちは 1782
    item <1783> & "co"'q' & <angle> "d" こんにちは 1783
    item <1784> & "co"'q' & <angle> "d" こんにちは 1784
    item <1785> & "co"'q' & <angle> "d" こんにちは 1785
    item <1786> & "co"'q' & <angle> "d" こんにちは 1786
    item <1787> & "co"'q' & <angle> "d" こんにちは 1787
    item <1788> & "co"'q' & <angle> "d" こんにちは 1788
    item <1789> & "co"'q' & <angle> "d" こんにちは 1789
    item <1790> & "co"'q' & <angle> "d" こんにちは 1790
    item <1791> & "co"'q' & <angle> "d" こんにちは 1791
    item <1792> & "co"'q' & <angle> "d" こんにちは 1792
    item <1793> & "co"'q' & <angle> "d" こんにちは 1793
    item <1794> & "co"'q' & <angle> "d" こんにちは 1794
    item <1795> & "co"'q' & <angle> "d" こんにちは 1795
    item <1796> & "co"'q' & <angle> "d" こんにちは 1796
    item <1797> & "co"'q' & <angle> "d" こんにちは 1797
    item <1798> & "co"'q' & <angle> "d" こんにちは 1798
    item <1799> & "co"'q' & <angle> "d" こんにちは 1799
    item <1800> & "co"'q' & <angle> "d" こんにちは 1800
    item <1801> & "co"'q' & <angle> "d" こんにちは 1801
    item <1802> & "co"'q' & <angle> "d" こんにちは 1802
    item <1803> & "co"'q' & <angle> "d" こんにちは 1803
    item <1804> & "co"'q' & <angle> "d" こんにちは 1804
    item <1805> & "co"'q' & <angle> "d" こんにちは 1805
    item <1806> & "co"'q' & <angle> "d" こんにちは 1806
    item <1807> & "co"'q' & <angle> "d" こんにちは 1807
    item <1808> & "co"'q' & <angle> "d" こんにちは 1808
    item <1809> & "co"'q' & <angle> "d" こんにちは 1809
    item <1810> & "co"'q' & <angle> "d" こんにちは 1810
    item <1811> & "co"'q' & <angle> "d" こんにちは 1811
    item <1812> & "co"'q' & <angle> "d" こんにちは 1812
    item <1813> & "co"'q' & <angle> "d" こんにちは 1813
    item <1814> & "co"'q' & <angle> "d" こんにちは 1814
    item <1815> & "co"'q' & <angle> "d" こんにちは 1815
    item <1816> & "co"'q' & <angle> "d" こんにちは 1816
    item <1817> & "co"'q' & <angle> "d" こんにちは 1817
    item <1818> & "co"'q' & <angle> "d" こんにちは 1818
    item <1819> & "co"'q' & <angle> "d" こんにちは 1819
    item <1820> & "co"'q' & <angle> "d" こんにちは 1820
    item <1821> & "co"'q' & <angle> "d" こんにちは 1821
    item <1822> & "co"'q' & <angle> "d" こんにちは 1822
    item <1823> & "co"'q' & <angle> "d" こんにちは 1823
    item <1824> & "co"'q' & <angle> "d" こんにちは 1824
    item <1825> & "co"'q' & <angle> "d" こんにちは 1825
    item <1826> & "co"'q' & <angle> "d" こんにちは 1826
    item <1827> & "co"'q' & <angle> "d" こんにちは 1827
    item <1828> & "co"'q' & <angle> "d" こんにちは 1828
    item <1829> & "co"'q' & <angle> "d" こんにちは 1829
    item <1830> & "co"'q' & <angle> "d" こんにちは 1830
    item <1831> & "co"'q' & <angle> "d" こんにちは 1831
    item <1832> & "co"'q' & <angle> "d" こんにちは 1832
    item <1833> & "co"'q' & <angle> "d" こんにちは 1833
    item <1834> & "co"'q' & <angle> "d" こんにちは 1834
    item <1835> & "co"'q' & <angle> "d" こんにちは 1835
    item <1836> & "co"'q' & <angle> "d" こんにちは 1836
    item <1837> & "co"'q' & <angle> "d" こんにちは 1837
    item <1838> & "co"'q' & <angle> "d" こんにちは 1838
    item <1839> & "co"'q' & <angle> "d" こんにちは 1839
    item <1840> & "co"'q' & <angle> "d" こんにちは 1840
    item <1841> & "co"'q' & <angle> "d" こんにちは 1841
    item <1842> & "co"'q' & <angle> "d" こんにちは 1842
    item <1843> & "co"'q' & <angle> "d" こんにちは 1843
    item <1844> & "co"'q' & <angle> "d" こんにちは 1844
    item <1845> & "co"'q' & <angle> "d" こんにちは 1845
    item <1846> & "co"'q' & <angle> "d" こんにちは 1846
    item <1847> & "co"'q' & <angle> "d" こんにちは 1847
    item <1848> & "co"'q' & <angle> "d" こんにちは 1848
    item <1849> & "co"'q' & <angle> "d" こんにちは 1849
    item <1850> & "co"'q' & <angle> "d" こんにちは 1850
    item <1851> & "co"'q' & <angle> "d" こんにちは 1851
    item <1852> & "co"'q' & <angle> "d" こんにちは 1852
    item <1853> & "co"'q' & <angle> "d" こんにちは 1853
    item <1854> & "co"'q' & <angle> "d" こんにちは 1854
    item <1855> & "co"'q' & <angle> "d" こんにちは 1855
    item <1856> & "co"'q' & <angle> "d" こんにちは 1856
    item <1857> & "co"'q' & <angle> "d" こんにちは 1857
    item <1858> & "co"'q' & <angle> "d" こんにちは 1858
    item <1859> & "co"'q' & <angle> "d" こんにちは 1859
    item <1860> & "co"'q' & <angle> "d" こんにちは 1860
    item <1861> & "co"'q' & <angle> "d" こんにちは 1861
    item <1862> & "co"'q' & <angle> "d" こんにちは 1862
    item <1863> & "co"'q' & <angle> "d" こんにちは 1863
    item <1864> & "co"'q' & <angle> "d" こんにちは 1864
    item <1865> & "co"'q' & <angle> "d" こんにちは 1865
    item <1866> & "co"'q' & <angle> "d" こんにちは 1866
    item <1867> & "co"'q' & <angle> "d" こんにちは 1867
    item <1868> & "co"'q' & <angle> "d" こんにちは 1868
    item <1869> & "co"'q' & <angle> "d" こんにちは 1869
    item <1870> & "co"'q' & <angle> "d" こんにちは 1870
    item <1871> & "co"'q' & <angle> "d" こんにちは 1871
    item <1872> & "co"'q' & <angle> "d" こんにちは 1872
    item <1873> & "co"'q' & <angle> "d" こんにちは 1873
    item <1874> & "co"'q' & <angle> "d" こんにちは 1874
    item <1875> & "co"'q' & <angle> "d" こんにちは 1875
    item <1876> & "co"'q' & <angle> "d" こんにちは 1876
    item <1877> & "co"'q' & <angle> "d" こんにちは 1877
    item <1878> & "co"'q' & <angle> "d" こんにちは 1878
    item <1879> & "co"'q' & <angle> "d" こんにちは 1879
    item <1880> & "co"'q' & <angle> "d" こんにちは 1880
    item <1881> & "co"'q' & <angle> "d" こんにちは 1881
    item <1882> & "co"'q' & <angle> "d" こんにちは 1882
    item <1883> & "co"'q' & <angle> "d" こんにちは 1883
    item <1884> & "co"'q' & <angle> "d" こんにちは 1884
    item <1885> & "co"'q' & <angle> "d" こんにちは 1885
    item <1886> & "co"'q' & <angle> "d" こんにちは 1886
    item <1887> & "co"'q' & <angle> "d" こんにちは 1887
    item <1888> & "co"'q' & <angle> "d" こんにちは 1888
    item <1889> & "co"'q' & <angle> "d" こんにちは 1889
    item <1890> & "co"'q' & <angle> "d" こんにちは 1890
    item <1891> & "co"'q' & <angle> "d" こんにちは 1891
    item <1892> & "co"'q' & <angle> "d" こんにちは 1892
    item <1893> & "co"'q' & <angle> "d" こんにちは 1893
    item <1894> & "co"'q' & <angle> "d" こんにちは 1894
    item <1895> & "co"'q' & <angle> "d" こんにちは 1895
    item <1896> & "co"'q' & <angle> "d" こんにちは 1896
    item <1897> & "co"'q' & <angle> "d" こんにちは 1897
    item <1898> & "co"'q' & <angle> "d" こんにちは 1898
    item <1899> & "co"'q' & <angle> "d" こんにちは 1899
    item <1900> & "co"'q' & <angle> "d" こんにちは 1900
    item <1901> & "co"'q' & <angle> "d" こんにちは 1901
    item <1902> & "co"'q' & <angle> "d" こんにちは 1902
    item <1903> & "co"'q' & <angle> "d" こんにちは 1903
    item <1904> & "co"'q' & <angle> "d" こんにちは 1904
    item <1905> & "co"'q' & <angle> "d" こんにちは 1905
    item <1906> & "co"'q' & <angle> "d" こんにちは 1906
    item <1907> & "co"'q' & <angle> "d" こんにちは 1907
    item <1908> & "co"'q' & <angle> "d" こんにちは 1908
    item <1909> & "co"'q' & <angle> "d" こんにちは 1909
    item <1910> & "co"'q' & <angle> "d" こんにちは 1910
    item <1911> & "co"'q' & <angle> "d" こんにちは 1911
    item <1912> & "co"'q' & <angle> "d" こんにちは 1912
    item <1913> & "co"'q' & <angle> "d" こんにちは 1913
    item <1914> & "co"'q' & <angle> "d" こんにちは 1914
    item <1915> & "co"'q' & <angle> "d" こんにちは 1915
    item <1916> & "co"'q' & <angle> "d" こんにちは 1916
    item <1917> & "co"'q' & <angle> "d" こんにちは 1917
    item <1918> & "co"'q' & <angle> "d" こんにちは 1918
    item <1919> & "co"'q' & <angle> "d" こんにちは 1919
    item <1920> & "co"'q' & <angle> "d" こんにちは 1920
    item <1921> & "co"'q' & <angle> "d" こんにちは 1921
    item <1922> & "co"'q' & <angle> "d" こんにちは 1922
    item <1923> & "co"'q' & <angle> "d" こんにちは 1923
    item <1924> & "co"'q' & <angle> "d" こんにちは 1924
    item <1925> & "co"'q' & <angle> "d" こんにちは 1925
    item <1926> & "co"'q' & <angle> "d" こんにちは 1926
    item <1927> & "co"'q' & <angle> "d" こんにちは 1927
    item <1928> & "co"'q' & <angle> "d" こんにちは 1928
    item <1929> & "co"'q' & <angle> "d" こんにちは 1929
    item <1930> & "co"'q' & <angle> "d" こんにちは 1930
    item <1931> & "co"'q' & <angle> "d" こんにちは 1931
    item <1932> & "co"'q' & <angle> "d" こんにちは 1932
    item <1933> & "co"'q' & <angle> "d" こんにちは 1933
    item <1934> & "co"'q' & <angle> "d" こんにちは 1934
    item <1935> & "co"'q' & <angle> "d" こんにちは 1935
    item <1936> & "co"'q' & <angle> "d" こんにちは 1936
    item <1937> & "co"'q' & <angle> "d" こんにちは 1937
    item <1938> & "co"'q' & <angle> "d" こんにちは 1938
    item <1939> & "co"'q' & <angle> "d" こんにちは 1939
    item <1940> & "co"'q' & <angle> "d" こんにちは 1940
    item <1941> & "co"'q' & <angle> "d" こんにちは 1941
    item <1942> & "co"'q' & <angle> "d" こんにちは 1942
    item <1943> & "co"'q' & <angle> "d" こんにちは 1943
    item <1944> & "co"'q' & <angle> "d" こんにちは 1944
    item <1945> & "co"'q' & <angle> "d" こんにちは 1945
    item <1946> & "co"'q' & <angle> "d" こんにちは 1946
    item <1947> & "co"'q' & <angle> "d" こんにちは 1947
    item <1948> & "co"'q' & <angle> "d" こんにちは 1948
    item <1949> & "co"'q' & <angle> "d" こんにちは 1949
    item <1950> & "co"'q' & <angle> "d" こんにちは 1950
    item <1951> & "co"'q' & <angle> "d" こんにちは 1951
    item <1952> & "co"'q' & <angle> "d" こんにちは 1952
    item <1953> & "co"'q' & <angle> "d" こんにちは 1953
    item <1954> & "co"'q' & <angle> "d" こんにちは 1954
    item <1955> & "co"'q' & <angle> "d" こんにちは 1955
    item <1956> & "co"'q' & <angle> "d" こんにちは 1956
    item <1957> & "co"'q' & <angle> "d" こんにちは 1957
    item <1958> & "co"'q' & <angle> "d" こんにちは 1958
    item <1959> & "co"'q' & <angle> "d" こんにちは 1959
    item <1960> & "co"'q' & <angle> "d" こんにちは 1960
    item <1961> & "co"'q' & <angle> "d" こんにちは 1961
    item <1962> & "co"'q' & <angle> "d" こんにちは 1962
    item <1963> & "co"'q' & <angle> "d" こんにちは 1963
    item <1964> & "co"'q' & <angle> "d" こんにちは 1964
    item <1965> & "co"'q' & <angle> "d" こんにちは 1965
    item <1966> & "co"'q' & <angle> "d" こんにちは 1966
    item <1967> & "co"'q' & <angle> "d" こんにちは 1967
    item <1968> & "co"'q' & <angle> "d" こんにちは 1968
    item <1969> & "co"'q' & <angle> "d" こんにちは 1969
    item <1970> & "co"'q' & <angle> "d" こんにちは 1970
    item <1971> & "co"'q' & <angle> "d" こんにちは 1971
    item <1972> & "co"'q' & <angle> "d" こんにちは 1972
    item <1973> & "co"'q' & <angle> "d" こんにちは 1973
    item <1974> & "co"'q' & <angle> "d" こんにちは 1974
    item <1975> & "co"'q' & <angle> "d" こんにちは 1975
    item <1976> & "co"'q' & <angle> "d" こんにちは 1976
    item <1977> & "co"'q' & <angle> "d" こんにちは 1977
    item <1978> & "co"'q' & <angle> "d" こんにちは 1978
    item <1979> & "co"'q' & <angle> "d" こんにちは 1979
    item <1980> & "co"'q' & <angle> "d" こんにちは 1980
    item <1981> & "co"'q' & <angle> "d" こんにちは 1981
    item <1982> & "co"'q' & <angle> "d" こんにちは 1982
    item <1983> & "co"'q' & <angle> "d" こんにちは 1983
    item <1984> & "co"'q' & <angle> "d" こんにちは 1984
    item <1985> & "co"'q' & <angle> "d" こんにちは 1985
    item <1986> & "co"'q' & <angle> "d" こんにちは 1986
    item <1987> & "co"'q' & <angle> "d" こんにちは 1987
    item <1988> & "co"'q' & <angle> "d" こんにちは 1988
    item <1989> & "co"'q' & <angle> "d" こんにちは 1989
    item <1990> & "co"'q' & <angle> "d" こんにちは 1990
    item <1991> & "co"'q' & <angle> "d" こんにちは 1991
    item <1992> & "co"'q' & <angle> "d" こんにちは 1992
    item <1993> & "co"'q' & <angle> "d" こんにちは 1993
    item <1994> & "co"'q' & <angle> "d" こんにちは 1994
    item <1995> & "co"'q' & <angle> "d" こんにちは 1995
    item <1996> & "co"'q' & <angle> "d" こんにちは 1996
    item <1997> & "co"'q' & <angle> "d" こんにちは 1997
    item <1998> & "co"'q' & <angle> "d" こんにちは 1998
    item <1999> & "co"'q' & <angle> "d" こんにちは 1999
    item <2000> & "co"'q' & <angle> "d" こんにちは 2000
    item <2001> & "co"'q' & <angle> "d" こんにちは 2001
    item <2002> & "co"'q' & <angle> "d" こんにちは 2002
    item <2003> & "co"'q' & <angle> "d" こんにちは 2003
    item <2004> & "co"'q' & <angle> "d" こんにちは 2004
    item <2005> & "co"'q' & <angle> "d" こんにちは 2005
    item <2006> & "co"'q' & <angle> "d" こんにちは 2006
    item <2007> & "co"'q' & <angle> "d" こんにちは 2007
    item <2008> & "co"'q' & <angle> "d" こんにちは 2008
    item <2009> & "co"'q' & <angle> "d" こんにちは 2009
    item <2010> & "co"'q' & <angle> "d" こんにちは 2010
    item <2011> & "co"'q' & <angle> "d" こんにちは 2011
    item <2012> & "co"'q' & <angle> "d" こんにちは 2012
    item <2013> & "co"'q' & <angle> "d" こんにちは 2013
    item <2014> & "co"'q' & <angle> "d" こんにちは 2014
    item <2015> & "co"'q' & <angle> "d" こんにちは 2015
    item <2016> & "co"'q' & <angle> "d" こんにちは 2016
    item <2017> & "co"'q' & <angle> "d" こんにちは 2017
    item <2018> & "co"'q' & <angle> "d" こんにちは 2018
    item <2019> & "co"'q' & <angle> "d" こんにちは 2019
    item <2020> & "co"'q' & <angle> "d" こんにちは 2020
    item <2021> & "co"'q' & <angle> "d" こんにちは 2021
    item <2022> & "co"'q' & <angle> "d" こんにちは 2022
    item <2023> & "co"'q' & <angle> "d" こんにちは 2023
    item <2024> & "co"'q' & <angle> "d" こんにちは 2024
    item <2025> & "co"'q' & <angle> "d" こんにちは 2025
    item <2026> & "co"'q' & <angle> "d" こんにちは 2026
    item <2027> & "co"'q' & <angle> "d" こんにちは 2027
    item <2028> & "co"'q' & <angle> "d" こんにちは 2028
    item <2029> & "co"'q' & <angle> "d" こんにちは 2029
    item <2030> & "co"'q' & <angle> "d" こんにちは 2030
    item <2031> & "co"'q' & <angle> "d" こんにちは 2031
    item <2032> & "co"'q' & <angle> "d" こんにちは 2032
    item <2033> & "co"'q' & <angle> "d" こんにちは 2033
    item <2034> & "co"'q' & <angle> "d" こんにちは 2034
    item <2035> & "co"'q' & <angle> "d" こんにちは 2035
    item <2036> & "co"'q' & <angle> "d" こんにちは 2036
    item <2037> & "co"'q' & <angle> "d" こんにちは 2037
    item <2038> & "co"'q' & <angle> "d" こんにちは 2038
    item <2039> & "co"'q' & <angle> "d" こんにちは 2039
    item <2040> & "co"'q' & <angle> "d" こんにちは 2040
    item <2041> & "co"'q' & <angle> "d" こんにちは 2041
    item <2042> & "co"'q' & <angle> "d" こんにちは 2042
    item <2043> & "co"'q' & <angle> "d" こんにちは 2043
    item <2044> & "co"'q' & <angle> "d" こんにちは 2044
    item <2045> & "co"'q' & <angle> "d" こんにちは 2045
    item <2046> & "co"'q' & <angle> "d" こんにちは 2046
    item <2047> & "co"'q' & <angle> "d" こんにちは 2047
    item <2048> & "co"'q' & <angle> "d" こんにちは 2048
    item <2049> & "co"'q' & <angle> "d" こんにちは 2049
    item <2050> & "co"'q' & <angle> "d" こんにちは 2050
    item <2051> & "co"'q' & <angle> "d" こんにちは 2051
    item <2052> & "co"'q' & <angle> "d" こんにちは 2052
    item <2053> & "co"'q' & <angle> "d" こんにちは 2053
    item <2054> & "co"'q' & <angle> "d" こんにちは 2054
    item <2055> & "co"'q' & <angle> "d" こんにちは 2055
    item <2056> & "co"'q' & <angle> "d" こんにちは 2056
    item <2057> & "co"'q' & <angle> "d" こんにちは 2057
    item <2058> & "co"'q' & <angle> "d" こんにちは 2058
    item <2059> & "co"'q' & <angle> "d" こんにちは 2059
    item <2060> & "co"'q' & <angle> "d" こんにちは 2060
    item <2061> & "co"'q' & <angle> "d" こんにちは 2061
    item <2062> & "co"'q' & <angle> "d" こんにちは 2062
    item <2063> & "co"'q' & <angle> "d" こんにちは 2063
    item <2064> & "co"'q' & <angle> "d" こんにちは 2064
    item <2065> & "co"'q' & <angle> "d" こんにちは 2065
    item <2066> & "co"'q' & <angle> "d" こんにちは 2066
    item <2067> & "co"'q' & <angle> "d" こんにちは 2067
    item <2068> & "co"'q' & <angle> "d" こんにちは 2068
    item <2069> & "co"'q' & <angle> "d" こんにちは 2069
    item <2070> & "co"'q' & <angle> "d" こんにちは 2070
    item <2071> & "co"'q' & <angle> "d" こんにちは 2071
    item <2072> & "co"'q' & <angle> "d" こんにちは 2072
    item <2073> & "co"'q' & <angle> "d" こんにちは 2073
    item <2074> & "co"'q' & <angle> "d" こんにちは 2074
    item <2075> & "co"'q' & <angle> "d" こんにちは 2075
    item <2076> & "co"'q' & <angle> "d" こんにちは 2076
    item <2077> & "co"'q' & <angle> "d" こんにちは 2077
    item <2078> & "co"'q' & <angle> "d" こんにちは 2078
    item <2079> & "co"'q' & <angle> "d" こんにちは 2079
    item <2080> & "co"'q' & <angle> "d" こんにちは 2080
    item <2081> & "co"'q' & <angle> "d" こんにちは 2081
    item <2082> & "co"'q' & <angle> "d" こんにちは 2082
    item <2083> & "co"'q' & <angle> "d" こんにちは 2083
    item <2084> & "co"'q' & <angle> "d" こんにちは 2084
    item <2085> & "co"'q' & <angle> "d" こんにちは 2085
    item <2086> & "co"'q' & <angle> "d" こんにちは 2086
    item <2087> & "co"'q' & <angle> "d" こんにちは 2087
    item <2088> & "co"'q' & <angle> "d" こんにちは 2088
    item <2089> & "co"'q' & <angle> "d" こんにちは 2089
    item <2090> & "co"'q' & <angle> "d" こんにちは 2090
    item <2091> & "co"'q' & <angle> "d" こんにちは 2091
    item <2092> & "co"'q' & <angle> "d" こんにちは 2092
    item <2093> & "co"'q' & <angle> "d" こんにちは 2093
    item <2094> & "co"'q' & <angle> "d" こんにちは 2094
    item <2095> & "co"'q' & <angle> "d" こんにちは 2095
    item <2096> & "co"'q' & <angle> "d" こんにちは 2096
    item <2097> & "co"'q' & <angle> "d" こんにちは 2097
    item <2098> & "co"'q' & <angle> "d" こんにちは 2098
    item <2099> & "co"'q' & <angle> "d" こんにちは 2099
    item <2100> & "co"'q' & <angle> "d" こんにちは 2100
    item <2101> & "co"'q' & <angle> "d" こんにちは 2101
    item <2102> & "co"'q' & <angle> "d" こんにちは 2102
    item <2103> & "co"'q' & <angle> "d" こんにちは 2103
    item <2104> & "co"'q' & <angle> "d" こんにちは 2104
    item <2105> & "co"'q' & <angle> "d" こんにちは 2105
    item <2106> & "co"'q' & <angle> "d" こんにちは 2106
    item <2107> & "co"'q' & <angle> "d" こんにちは 2107
    item <2108> & "co"'q' & <angle> "d" こんにちは 2108
    item <2109> & "co"'q' & <angle> "d" こんにちは 2109
    item <2110> & "co"'q' & <angle> "d" こんにちは 2110
    item <2111> & "co"'q' & <angle> "d" こんにちは 2111
    item <2112> & "co"'q' & <angle> "d" こんにちは 2112
    item <2113> & "co"'q' & <angle> "d" こんにちは 2113
    item <2114> & "co"'q' & <angle> "d" こんにちは 2114
    item <2115> & "co"'q' & <angle> "d" こんにちは 2115
    item <2116> & "co"'q' & <angle> "d" こんにちは 2116
    item <2117> & "co"'q' & <angle> "d" こんにちは 2117
    item <2118> & "co"'q' & <angle> "d" こんにちは 2118
    item <2119> & "co"'q' & <angle> "d" こんにちは 2119
    item <2120> & "co"'q' & <angle> "d" こんにちは 2120
    item <2121> & "co"'q' & <angle> "d" こんにちは 2121
    item <2122> & "co"'q' & <angle> "d" こんにちは 2122
    item <2123> & "co"'q' & <angle> "d" こんにちは 2123
    item <2124> & "co"'q' & <angle> "d" こんにちは 2124
    item <2125> & "co"'q' & <angle> "d" こんにちは 2125
    item <2126> & "co"'q' & <angle> "d" こんにちは 2126
    item <2127> & "co"'q' & <angle> "d" こんにちは 2127
    item <2128> & "co"'q' & <angle> "d" こんにちは 2128
    item <2129> & "co"'q' & <angle> "d" こんにちは 2129
    item <2130> & "co"'q' & <angle> "d" こんにちは 2130
    item <2131> & "co"'q' & <angle> "d" こんにちは 2131
    item <2132> & "co"'q' & <angle> "d" こんにちは 2132
    item <2133> & "co"'q' & <angle> "d" こんにちは 2133
    item <2134> & "co"'q' & <angle> "d" こんにちは 2134
    item <2135> & "co"'q' & <angle> "d" こんにちは 2135
    item <2136> & "co"'q' & <angle> "d" こんにちは 2136
    item <2137> & "co"'q' & <angle> "d" こんにちは 2137
    item <2138> & "co"'q' & <angle> "d" こんにちは 2138
    item <2139> & "co"'q' & <angle> "d" こんにちは 2139
    item <2140> & "co"'q' & <angle> "d" こんにちは 2140
    item <2141> & "co"'q' & <angle> "d" こんにちは 2141
    item <2142> & "co"'q' & <angle> "d" こんにちは 2142
    item <2143> & "co"'q' & <angle> "d" こんにちは 2143
    item <2144> & "co"'q' & <angle> "d" こんにちは 2144
    item <2145> & "co"'q' & <angle> "d" こんにちは 2145
    item <2146> & "co"'q' & <angle> "d" こんにちは 2146
    item <2147> & "co"'q' & <angle> "d" こんにちは 2147
    item <2148> & "co"'q' & <angle> "d" こんにちは 2148
    item <2149> & "co"'q' & <angle> "d" こんにちは 2149
    item <2150> & "co"'q' & <angle> "d" こんにちは 2150
    item <2151> & "co"'q' & <angle> "d" こんにちは 2151
    item <2152> & "co"'q' & <angle> "d" こんにちは 2152
    item <2153> & "co"'q' & <angle> "d" こんにちは 2153
    item <2154> & "co"'q' & <angle> "d" こんにちは 2154
    item <2155> & "co"'q' & <angle> "d" こんにちは 2155
    item <2156> & "co"'q' & <angle> "d" こんにちは 2156
    item <2157> & "co"'q' & <angle> "d" こんにちは 2157
    item <2158> & "co"'q' & <angle> "d" こんにちは 2158
    item <2159> & "co"'q' & <angle> "d" こんにちは 2159
    item <2160> & "co"'q' & <angle> "d" こんにちは 2160
    item <2161> & "co"'q' & <angle> "d" こんにちは 2161
    item <2162> & "co"'q' & <angle> "d" こんにちは 2162
    item <2163> & "co"'q' & <angle> "d" こんにちは 2163
    item <2164> & "co"'q' & <angle> "d" こんにちは 2164
    item <2165> & "co"'q' & <angle> "d" こんにちは 2165
    item <2166> & "co"'q' & <angle> "d" こんにちは 2166
    item <2167> & "co"'q' & <angle> "d" こんにちは 2167
    item <2168> & "co"'q' & <angle> "d" こんにちは 2168
    item <2169> & "co"'q' & <angle> "d" こんにちは 2169
    item <2170> & "co"'q' & <angle> "d" こんにちは 2170
    item <2171> & "co"'q' & <angle> "d" こんにちは 2171
    item <2172> & "co"'q' & <angle> "d" こんにちは 2172
    item <2173> & "co"'q' & <angle> "d" こんにちは 2173
    item <2174> & "co"'q' & <angle> "d" こんにちは 2174
    item <2175> & "co"'q' & <angle> "d" こんにちは 2175
    item <2176> & "co"'q' & <angle> "d" こんにちは 2176
    item <2177> & "co"'q' & <angle> "d" こんにちは 2177
    item <2178> & "co"'q' & <angle> "d" こんにちは 2178
    item <2179> & "co"'q' & <angle> "d" こんにちは 2179
    item <2180> & "co"'q' & <angle> "d" こんにちは 2180
    item <2181> & "co"'q' & <angle> "d" こんにちは 2181
    item <2182> & "co"'q' & <angle> "d" こんにちは 2182
    item <2183> & "co"'q' & <angle> "d" こんにちは 2183
    item <2184> & "co"'q' & <angle> "d" こんにちは 2184
    item <2185> & "co"'q' & <angle> "d" こんにちは 2185
    item <2186> & "co"'q' & <angle> "d" こんにちは 2186
    item <2187> & "co"'q' & <angle> "d" こんにちは 2187
    item <2188> & "co"'q' & <angle> "d" こんにちは 2188
    item <2189> & "co"'q' & <angle> "d" こんにちは 2189
    item <2190> & "co"'q' & <angle> "d" こんにちは 2190
    item <2191> & "co"'q' & <angle> "d" こんにちは 2191
    item <2192> & "co"'q' & <angle> "d" こんにちは 2192
    item <2193> & "co"'q' & <angle> "d" こんにちは 2193
    item <2194> & "co"'q' & <angle> "d" こんにちは 2194
    item <2195> & "co"'q' & <angle> "d" こんにちは 2195
    item <2196> & "co"'q' & <angle> "d" こんにちは 2196
    item <2197> & "co"'q' & <angle> "d" こんにちは 2197
    item <2198> & "co"'q' & <angle> "d" こんにちは 2198
    item <2199> & "co"'q' & <angle> "d" こんにちは 2199
    item <2200> & "co"'q' & <angle> "d" こんにちは 2200
    item <2201> & "co"'q' & <angle> "d" こんにちは 2201
    item <2202> & "co"'q' & <angle> "d" こんにちは 2202
    item <2203> & "co"'q' & <angle> "d" こんにちは 2203
    item <2204> & "co"'q' & <angle> "d" こんにちは 2204
    item <2205> & "co"'q' & <angle> "d" こんにちは 2205
    item <2206> & "co"'q' & <angle> "d" こんにちは 2206
    item <2207> & "co"'q' & <angle> "d" こんにちは 2207
    item <2208> & "co"'q' & <angle> "d" こんにちは 2208
    item <2209> & "co"'q' & <angle> "d" こんにちは 2209
    item <2210> & "co"'q' & <angle> "d" こんにちは 2210
    item <2211> & "co"'q' & <angle> "d" こんにちは 2211
    item <2212> & "co"'q' & <angle> "d" こんにちは 2212
    item <2213> & "co"'q' & <angle> "d" こんにちは 2213
    item <2214> & "co"'q' & <angle> "d" こんにちは 2214
    item <2215> & "co"'q' & <angle> "d" こんにちは 2215
    item <2216> & "co"'q' & <angle> "d" こんにちは 2216
    item <2217> & "co"'q' & <angle> "d" こんにちは 2217
    item <2218> & "co"'q' & <angle> "d" こんにちは 2218
    item <2219> & "co"'q' & <angle> "d" こんにちは 2219
    item <2220> & "co"'q' & <angle> "d" こんにちは 2220
    item <2221> & "co"'q' & <angle> "d" こんにちは 2221
    item <2222> & "co"'q' & <angle> "d" こんにちは 2222
    item <2223> & "co"'q' & <angle> "d" こんにちは 2223
    item <2224> & "co"'q' & <angle> "d" こんにちは 2224
    item <2225> & "co"'q' & <angle> "d" こんにちは 2225
    item <2226> & "co"'q' & <angle> "d" こんにちは 2226
    item <2227> & "co"'q' & <angle> "d" こんにちは 2227
    item <2228> & "co"'q' & <angle> "d" こんにちは 2228
    item <2229> & "co"'q' & <angle> "d" こんにちは 2229
    item <2230> & "co"'q' & <angle> "d" こんにちは 2230
    item <2231> & "co"'q' & <angle> "d" こんにちは 2231
    item <2232> & "co"'q' & <angle> "d" こんにちは 2232
    item <2233> & "co"'q' & <angle> "d" こんにちは 2233
    item <2234> & "co"'q' & <angle> "d" こんにちは 2234
    item <2235> & "co"'q' & <angle> "d" こんにちは 2235
    item <2236> & "co"'q' & <angle> "d" こんにちは 2236
    item <2237> & "co"'q' & <angle> "d" こんにちは 2237
    item <2238> & "co"'q' & <angle> "d" こんにちは 2238
    item <2239> & "co"'q' & <angle> "d" こんにちは 2239
    item <2240> & "co"'q' & <angle> "d" こんにちは 2240
    item <2241> & "co"'q' & <angle> "d" こんにちは 2241
    item <2242> & "co"'q' & <angle> "d" こんにちは 2242
    item <2243> & "co"'q' & <angle> "d" こんにちは 2243
    item <2244> & "co"'q' & <angle> "d" こんにちは 2244
    item <2245> & "co"'q' & <angle> "d" こんにちは 2245
    item <2246> & "co"'q' & <angle> "d" こんにちは 2246
    item <2247> & "co"'q' & <angle> "d" こんにちは 2247
    item <2248> & "co"'q' & <angle> "d" こんにちは 2248
    item <2249> & "co"'q' & <angle> "d" こんにちは 2249
    item <2250> & "co"'q' & <angle> "d" こんにちは 2250
    item <2251> & "co"'q' & <angle> "d" こんにちは 2251
    item <2252> & "co"'q' & <angle> "d" こんにちは 2252
    item <2253> & "co"'q' & <angle> "d" こんにちは 2253
    item <2254> & "co"'q' & <angle> "d" こんにちは 2254
    item <2255> & "co"'q' & <angle> "d" こんにちは 2255
    item <2256> & "co"'q' & <angle> "d" こんにちは 2256
    item <2257> & "co"'q' & <angle> "d" こんにちは 2257
    item <2258> & "co"'q' & <angle> "d" こんにちは 2258
    item <2259> & "co"'q' & <angle> "d" こんにちは 2259
    item <2260> & "co"'q' & <angle> "d" こんにちは 2260
    item <2261> & "co"'q' & <angle> "d" こんにちは 2261
    item <2262> & "co"'q' & <angle> "d" こんにちは 2262
    item <2263> & "co"'q' & <angle> "d" こんにちは 2263
    item <2264> & "co"'q' & <angle> "d" こんにちは 2264
    item <2265> & "co"'q' & <angle> "d" こんにちは 2265
    item <2266> & "co"'q' & <angle> "d" こんにちは 2266
    item <2267> & "co"'q' & <angle> "d" こんにちは 2267
    item <2268> & "co"'q' & <angle> "d" こんにちは 2268
    item <2269> & "co"'q' & <angle> "d" こんにちは 2269
    item <2270> & "co"'q' & <angle> "d" こんにちは 2270
    item <2271> & "co"'q' & <angle> "d" こんにちは 2271
    item <2272> & "co"'q' & <angle> "d" こんにちは 2272
    item <2273> & "co"'q' & <angle> "d" こんにちは 2273
    item <2274> & "co"'q' & <angle> "d" こんにちは 2274
    item <2275> & "co"'q' & <angle> "d" こんにちは 2275
    item <2276> & "co"'q' & <angle> "d" こんにちは 2276
    item <2277> & "co"'q' & <angle> "d" こんにちは 2277
    item <2278> & "co"'q' & <angle> "d" こんにちは 2278
    item <2279> & "co"'q' & <angle> "d" こんにちは 2279
    item <2280> & "co"'q' & <angle> "d" こんにちは 2280
    item <2281> & "co"'q' & <angle> "d" こんにちは 2281
    item <2282> & "co"'q' & <angle> "d" こんにちは 2282
    item <2283> & "co"'q' & <angle> "d" こんにちは 2283
    item <2284> & "co"'q' & <angle> "d" こんにちは 2284
    item <2285> & "co"'q' & <angle> "d" こんにちは 2285
    item <2286> & "co"'q' & <angle> "d" こんにちは 2286
    item <2287> & "co"'q' & <angle> "d" こんにちは 2287
    item <2288> & "co"'q' & <angle> "d" こんにちは 2288
    item <2289> & "co"'q' & <angle> "d" こんにちは 2289
    item <2290> & "co"'q' & <angle> "d" こんにちは 2290
    item <2291> & "co"'q' & <angle> "d" こんにちは 2291
    item <2292> & "co"'q' & <angle> "d" こんにちは 2292
    item <2293> & "co"'q' & <angle> "d" こんにちは 2293
    item <2294> & "co"'q' & <angle> "d" こんにちは 2294
    item <2295> & "co"'q' & <angle> "d" こんにちは 2295
    item <2296> & "co"'q' & <angle> "d" こんにちは 2296
    item <2297> & "co"'q' & <angle> "d" こんにちは 2297
    item <2298> & "co"'q' & <angle> "d" こんにちは 2298
    item <2299> & "co"'q' & <angle> "d" こんにちは 2299
    item <2300> & "co"'q' & <angle> "d" こんにちは 2300
    item <2301> & "co"'q' & <angle> "d" こんにちは 2301
    item <2302> & "co"'q' & <angle> "d" こんにちは 2302
    item <2303> & "co"'q' & <angle> "d" こんにちは 2303
    item <2304> & "co"'q' & <angle> "d" こんにちは 2304
    item <2305> & "co"'q' & <angle> "d" こんにちは 2305
    item <2306> & "co"'q' & <angle> "d" こんにちは 2306
    item <2307> & "co"'q' & <angle> "d" こんにちは 2307
    item <2308> & "co"'q' & <angle> "d" こんにちは 2308
    item <2309> & "co"'q' & <angle> "d" こんにちは 2309
    item <2310> & "co"'q' & <angle> "d" こんにちは 2310
    item <2311> & "co"'q' & <angle> "d" こんにちは 2311
    item <2312> & "co"'q' & <angle> "d" こんにちは 2312
    item <2313> & "co"'q' & <angle> "d" こんにちは 2313
    item <2314> & "co"'q' & <angle> "d" こんにちは 2314
    item <2315> & "co"'q' & <angle> "d" こんにちは 2315
    item <2316> & "co"'q' & <angle> "d" こんにちは 2316
    item <2317> & "co"'q' & <angle> "d" こんにちは 2317
    item <2318> & "co"'q' & <angle> "d" こんにちは 2318
    item <2319> & "co"'q' & <angle> "d" こんにちは 2319
    item <2320> & "co"'q' & <angle> "d" こんにちは 2320
    item <2321> & "co"'q' & <angle> "d" こんにちは 2321
    item <2322> & "co"'q' & <angle> "d" こんにちは 2322
    item <2323> & "co"'q' & <angle> "d" こんにちは 2323
    item <2324> & "co"'q' & <angle> "d" こんにちは 2324
    item <2325> & "co"'q' & <angle> "d" こんにちは 2325
    item <2326> & "co"'q' & <angle> "d" こんにちは 2326
    item <2327> & "co"'q' & <angle> "d" こんにちは 2327
    item <2328> & "co"'q' & <angle> "d" こんにちは 2328
    item <2329> & "co"'q' & <angle> "d" こんにちは 2329
    item <2330> & "co"'q' & <angle> "d" こんにちは 2330
    item <2331> & "co"'q' & <angle> "d" こんにちは 2331
    item <2332> & "co"'q' & <angle> "d" こんにちは 2332
    item <2333> & "co"'q' & <angle> "d" こんにちは 2333
    item <2334> & "co"'q' & <angle> "d" こんにちは 2334
    item <2335> & "co"'q' & <angle> "d" こんにちは 2335
    item <2336> & "co"'q' & <angle> "d" こんにちは 2336
    item <2337> & "co"'q' & <angle> "d" こんにちは 2337
    item <2338> & "co"'q' & <angle> "d" こんにちは 2338
    item <2339> & "co"'q' & <angle> "d" こんにちは 2339
    item <2340> & "co"'q' & <angle> "d" こんにちは 2340
    item <2341> & "co"'q' & <angle> "d" こんにちは 2341
    item <2342> & "co"'q' & <angle> "d" こんにちは 2342
    item <2343> & "co"'q' & <angle> "d" こんにちは 2343
    item <2344> & "co"'q' & <angle> "d" こんにちは 2344
    item <2345> & "co"'q' & <angle> "d" こんにちは 2345
    item <2346> & "co"'q' & <angle> "d" こんにちは 2346
    item <2347> & "co"'q' & <angle> "d" こんにちは 2347
    item <2348> & "co"'q' & <angle> "d" こんにちは 2348
    item <2349> & "co"'q' & <angle> "d" こんにちは 2349
    item <2350> & "co"'q' & <angle> "d" こんにちは 2350
    item <2351> & "co"'q' & <angle> "d" こんにちは 2351
    item <2352> & "co"'q' & <angle> "d" こんにちは 2352
    item <2353> & "co"'q' & <angle> "d" こんにちは 2353
    item <2354> & "co"'q' & <angle> "d" こんにちは 2354
    item <2355> & "co"'q' & <angle> "d" こんにちは 2355
    item <2356> & "co"'q' & <angle> "d" こんにちは 2356
    item <2357> & "co"'q' & <angle> "d" こんにちは 2357
    item <2358> & "co"'q' & <angle> "d" こんにちは 2358
    item <2359> & "co"'q' & <angle> "d" こんにちは 2359
    item <2360> & "co"'q' & <angle> "d" こんにちは 2360
    item <2361> & "co"'q' & <angle> "d" こんにちは 2361
    item <2362> & "co"'q' & <angle> "d" こんにちは 2362
    item <2363> & "co"'q' & <angle> "d" こんにちは 2363
    item <2364> & "co"'q' & <angle> "d" こんにちは 2364
    item <2365> & "co"'q' & <angle> "d" こんにちは 2365
    item <2366> & "co"'q' & <angle> "d" こんにちは 2366
    item <2367> & "co"'q' & <angle> "d" こんにちは 2367
    item <2368> & "co"'q' & <angle> "d" こんにちは 2368
    item <2369> & "co"'q' & <angle> "d" こんにちは 2369
    item <2370> & "co"'q' & <angle> "d" こんにちは 2370
    item <2371> & "co"'q' & <angle> "d" こんにちは 2371
    item <2372> & "co"'q' & <angle> "d" こんにちは 2372
    item <2373> & "co"'q' & <angle> "d" こんにちは 2373
    item <2374> & "co"'q' & <angle> "d" こんにちは 2374
    item <2375> & "co"'q' & <angle> "d" こんにちは 2375
    item <2376> & "co"'q' & <angle> "d" こんにちは 2376
    item <2377> & "co"'q' & <angle> "d" こんにちは 2377
    item <2378> & "co"'q' & <angle> "d" こんにちは 2378
    item <2379> & "co"'q' & <angle> "d" こんにちは 2379
    item <2380> & "co"'q' & <angle> "d" こんにちは 2380
    item <2381> & "co"'q' & <angle> "d" こんにちは 2381
    item <2382> & "co"'q' & <angle> "d" こんにちは 2382
    item <2383> & "co"'q' & <angle> "d" こんにちは 2383
    item <2384> & "co"'q' & <angle> "d" こんにちは 2384
    item <2385> & "co"'q' & <angle> "d" こんにちは 2385
    item <2386> & "co"'q' & <angle> "d" こんにちは 2386
    item <2387> & "co"'q' & <angle> "d" こんにちは 2387
    item <2388> & "co"'q' & <angle> "d" こんにちは 2388
    item <2389> & "co"'q' & <angle> "d" こんにちは 2389
    item <2390> & "co"'q' & <angle> "d" こんにちは 2390
    item <2391> & "co"'q' & <angle> "d" こんにちは 2391
    item <2392> & "co"'q' & <angle> "d" こんにちは 2392
    item <2393> & "co"'q' & <angle> "d" こんにちは 2393
    item <2394> & "co"'q' & <angle> "d" こんにちは 2394
    item <2395> & "co"'q' & <angle> "d" こんにちは 2395
    item <2396> & "co"'q' & <angle> "d" こんにちは 2396
    item <2397> & "co"'q' & <angle> "d" こんにちは 2397
    item <2398> & "co"'q' & <angle> "d" こんにちは 2398
    item <2399> & "co"'q' & <angle> "d" こんにちは 2399
    item <2400> & "co"'q' & <angle> "d" こんにちは 2400
    item <2401> & "co"'q' & <angle> "d" こんにちは 2401
    item <2402> & "co"'q' & <angle> "d" こんにちは 2402
    item <2403> & "co"'q' & <angle> "d" こんにちは 2403
    item <2404> & "co"'q' & <angle> "d" こんにちは 2404
    item <2405> & "co"'q' & <angle> "d" こんにちは 2405
    item <2406> & "co"'q' & <angle> "d" こんにちは 2406
    item <2407> & "co"'q' & <angle> "d" こんにちは 2407
    item <2408> & "co"'q' & <angle> "d" こんにちは 2408
    item <2409> & "co"'q' & <angle> "d" こんにちは 2409
    item <2410> & "co"'q' & <angle> "d" こんにちは 2410
    item <2411> & "co"'q' & <angle> "d" こんにちは 2411
    item <2412> & "co"'q' & <angle> "d" こんにちは 2412
    item <2413> & "co"'q' & <angle> "d" こんにちは 2413
    item <2414> & "co"'q' & <angle> "d" こんにちは 2414
    item <2415> & "co"'q' & <angle> "d" こんにちは 2415
    item <2416> & "co"'q' & <angle> "d" こんにちは 2416
    item <2417> & "co"'q' & <angle> "d" こんにちは 2417
    item <2418> & "co"'q' & <angle> "d" こんにちは 2418
    item <2419> & "co"'q' & <angle> "d" こんにちは 2419
    item <2420> & "co"'q' & <angle> "d" こんにちは 2420
    item <2421> & "co"'q' & <angle> "d" こんにちは 2421
    item <2422> & "co"'q' & <angle> "d" こんにちは 2422
    item <2423> & "co"'q' & <angle> "d" こんにちは 2423
    item <2424> & "co"'q' & <angle> "d" こんにちは 2424
    item <2425> & "co"'q' & <angle> "d" こんにちは 2425
    item <2426> & "co"'q' & <angle> "d" こんにちは 2426
    item <2427> & "co"'q' & <angle> "d" こんにちは 2427
    item <2428> & "co"'q' & <angle> "d" こんにちは 2428
    item <2429> & "co"'q' & <angle> "d" こんにちは 2429
    item <2430> & "co"'q' & <angle> "d" こんにちは 2430
    item <2431> & "co"'q' & <angle> "d" こんにちは 2431
    item <2432> & "co"'q' & <angle> "d" こんにちは 2432
    item <2433> & "co"'q' & <angle> "d" こんにちは 2433
    item <2434> & "co"'q' & <angle> "d" こんにちは 2434
    item <2435> & "co"'q' & <angle> "d" こんにちは 2435
    item <2436> & "co"'q' & <angle> "d" こんにちは 2436
    item <2437> & "co"'q' & <angle> "d" こんにちは 2437
    item <2438> & "co"'q' & <angle> "d" こんにちは 2438
    item <2439> & "co"'q' & <angle> "d" こんにちは 2439
    item <2440> & "co"'q' & <angle> "d" こんにちは 2440
    item <2441> & "co"'q' & <angle> "d" こんにちは 2441
    item <2442> & "co"'q' & <angle> "d" こんにちは 2442
    item <2443> & "co"'q' & <angle> "d" こんにちは 2443
    item <2444> & "co"'q' & <angle> "d" こんにちは 2444
    item <2445> & "co"'q' & <angle> "d" こんにちは 2445
    item <2446> & "co"'q' & <angle> "d" こんにちは 2446
    item <2447> & "co"'q' & <angle> "d" こんにちは 2447
    item <2448> & "co"'q' & <angle> "d" こんにちは 2448
    item <2449> & "co"'q' & <angle> "d" こんにちは 2449
    item <2450> & "co"'q' & <angle> "d" こんにちは 2450
    item <2451> & "co"'q' & <angle> "d" こんにちは 2451
    item <2452> & "co"'q' & <angle> "d" こんにちは 2452
    item <2453> & "co"'q' & <angle> "d" こんにちは 2453
    item <2454> & "co"'q' & <angle> "d" こんにちは 2454
    item <2455> & "co"'q' & <angle> "d" こんにちは 2455
    item <2456> & "co"'q' & <angle> "d" こんにちは 2456
    item <2457> & "co"'q' & <angle> "d" こんにちは 2457
    item <2458> & "co"'q' & <angle> "d" こんにちは 2458
    item <2459> & "co"'q' & <angle> "d" こんにちは 2459
    item <2460> & "co"'q' & <angle> "d" こんにちは 2460
    item <2461> & "co"'q' & <angle> "d" こんにちは 2461
    item <2462> & "co"'q' & <angle> "d" こんにちは 2462
    item <2463> & "co"'q' & <angle> "d" こんにちは 2463
    item <2464> & "co"'q' & <angle> "d" こんにちは 2464
    item <2465> & "co"'q' & <angle> "d" こんにちは 2465
    item <2466> & "co"'q' & <angle> "d" こんにちは 2466
    item <2467> & "co"'q' & <angle> "d" こんにちは 2467
    item <2468> & "co"'q' & <angle> "d" こんにちは 2468
    item <2469> & "co"'q' & <angle> "d" こんにちは 2469
    item <2470> & "co"'q' & <angle> "d" こんにちは 2470
    item <2471> & "co"'q' & <angle> "d" こんにちは 2471
    item <2472> & "co"'q' & <angle> "d" こんにちは 2472
    item <2473> & "co"'q' & <angle> "d" こんにちは 2473
    item <2474> & "co"'q' & <angle> "d" こんにちは 2474
    item <2475> & "co"'q' & <angle> "d" こんにちは 2475
    item <2476> & "co"'q' & <angle> "d" こんにちは 2476
    item <2477> & "co"'q' & <angle> "d" こんにちは 2477
    item <2478> & "co"'q' & <angle> "d" こんにちは 2478
    item <2479> & "co"'q' & <angle> "d" こんにちは 2479
    item <2480> & "co"'q' & <angle> "d" こんにちは 2480
    item <2481> & "co"'q' & <angle> "d" こんにちは 2481
    item <2482> & "co"'q' & <angle> "d" こんにちは 2482
    item <2483> & "co"'q' & <angle> "d" こんにちは 2483
    item <2484> & "co"'q' & <angle> "d" こんにちは 2484
    item <2485> & "co"'q' & <angle> "d" こんにちは 2485
    item <2486> & "co"'q' & <angle> "d" こんにちは 2486
    item <2487> & "co"'q' & <angle> "d" こんにちは 2487
    item <2488> & "co"'q' & <angle> "d" こんにちは 2488
    item <2489> & "co"'q' & <angle> "d" こんにちは 2489
    item <2490> & "co"'q' & <angle> "d" こんにちは 2490
    item <2491> & "co"'q' & <angle> "d" こんにちは 2491
    item <2492> & "co"'q' & <angle> "d" こんにちは 2492
    item <2493> & "co"'q' & <angle> "d" こんにちは 2493
    item <2494> & "co"'q' & <angle> "d" こんにちは 2494
    item <2495> & "co"'q' & <angle> "d" こんにちは 2495
    item <2496> & "co"'q' & <angle> "d" こんにちは 2496
    item <2497> & "co"'q' & <angle> "d" こんにちは 2497
    item <2498> & "co"'q' & <angle> "d" こんにちは 2498
    item <2499> & "co"'q' & <angle> "d" こんにちは 2499
    item <2500> & "co"'q' & <angle> "d" こんにちは 2500
    item <2501> & "co"'q' & <angle> "d" こんにちは 2501
    item <2502> & "co"'q' & <angle> "d" こんにちは 2502
    item <2503> & "co"'q' & <angle> "d" こんにちは 2503
    item <2504> & "co"'q' & <angle> "d" こんにちは 2504
    item <2505> & "co"'q' & <angle> "d" こんにちは 2505
    item <2506> & "co"'q' & <angle> "d" こんにちは 2506
    item <2507> & "co"'q' & <angle> "d" こんにちは 2507
    item <2508> & "co"'q' & <angle> "d" こんにちは 2508
    item <2509> & "co"'q' & <angle> "d" こんにちは 2509
    item <2510> & "co"'q' & <angle> "d" こんにちは 2510
    item <2511> & "co"'q' & <angle> "d" こんにちは 2511
    item <2512> & "co"'q' & <angle> "d" こんにちは 2512
    item <2513> & "co"'q' & <angle> "d" こんにちは 2513
    item <2514> & "co"'q' & <angle> "d" こんにちは 2514
    item <2515> & "co"'q' & <angle> "d" こんにちは 2515
    item <2516> & "co"'q' & <angle> "d" こんにちは 2516
    item <2517> & "co"'q' & <angle> "d" こんにちは 2517
    item <2518> & "co"'q' & <angle> "d" こんにちは 2518
    item <2519> & "co"'q' & <angle> "d" こんにちは 2519
    item <2520> & "co"'q' & <angle> "d" こんにちは 2520
    item <2521> & "co"'q' & <angle> "d" こんにちは 2521
    item <2522> & "co"'q' & <angle> "d" こんにちは 2522
    item <2523> & "co"'q' & <angle> "d" こんにちは 2523
    item <2524> & "co"'q' & <angle> "d" こんにちは 2524
    item <2525> & "co"'q' & <angle> "d" こんにちは 2525
    item <2526> & "co"'q' & <angle> "d" こんにちは 2526
    item <2527> & "co"'q' & <angle> "d" こんにちは 2527
    item <2528> & "co"'q' & <angle> "d" こんにちは 2528
    item <2529> & "co"'q' & <angle> "d" こんにちは 2529
    item <2530> & "co"'q' & <angle> "d" こんにちは 2530
    item <2531> & "co"'q' & <angle> "d" こんにちは 2531
    item <2532> & "co"'q' & <angle> "d" こんにちは 2532
    item <2533> & "co"'q' & <angle> "d" こんにちは 2533
    item <2534> & "co"'q' & <angle> "d" こんにちは 2534
    item <2535> & "co"'q' & <angle> "d" こんにちは 2535
    item <2536> & "co"'q' & <angle> "d" こんにちは 2536
    item <2537> & "co"'q' & <angle> "d" こんにちは 2537
    item <2538> & "co"'q' & <angle> "d" こんにちは 2538
    item <2539> & "co"'q' & <angle> "d" こんにちは 2539
    item <2540> & "co"'q' & <angle> "d" こんにちは 2540
    item <2541> & "co"'q' & <angle> "d" こんにちは 2541
    item <2542> & "co"'q' & <angle> "d" こんにちは 2542
    item <2543> & "co"'q' & <angle> "d" こんにちは 2543
    item <2544> & "co"'q' & <angle> "d" こんにちは 2544
    item <2545> & "co"'q' & <angle> "d" こんにちは 2545
    item <2546> & "co"'q' & <angle> "d" こんにちは 2546
    item <2547> & "co"'q' & <angle> "d" こんにちは 2547
    item <2548> & "co"'q' & <angle> "d" こんにちは 2548
    item <2549> & "co"'q' & <angle> "d" こんにちは 2549
    item <2550> & "co"'q' & <angle> "d" こんにちは 2550
    item <2551> & "co"'q' & <angle> "d" こんにちは 2551
    item <2552> & "co"'q' & <angle> "d" こんにちは 2552
    item <2553> & "co"'q' & <angle> "d" こんにちは 2553
    item <2554> & "co"'q' & <angle> "d" こんにちは 2554
    item <2555> & "co"'q' & <angle> "d" こんにちは 2555
    item <2556> & "co"'q' & <angle> "d" こんにちは 2556
    item <2557> & "co"'q' & <angle> "d" こんにちは 2557
    item <2558> & "co"'q' & <angle> "d" こんにちは 2558
    item <2559> & "co"'q' & <angle> "d" こんにちは 2559
    item <2560> & "co"'q' & <angle> "d" こんにちは 2560
    item <2561> & "co"'q' & <angle> "d" こんにちは 2561
    item <2562> & "co"'q' & <angle> "d" こんにちは 2562
    item <2563> & "co"'q' & <angle> "d" こんにちは 2563
    item <2564> & "co"'q' & <angle> "d" こんにちは 2564
    item <2565> & "co"'q' & <angle> "d" こんにちは 2565
    item <2566> & "co"'q' & <angle> "d" こんにちは 2566
    item <2567> & "co"'q' & <angle> "d" こんにちは 2567
    item <2568> & "co"'q' & <angle> "d" こんにちは 2568
    item <2569> & "co"'q' & <angle> "d" こんにちは 2569
    item <2570> & "co"'q' & <angle> "d" こんにちは 2570
    item <2571> & "co"'q' & <angle> "d" こんにちは 2571
    item <2572> & "co"'q' & <angle> "d" こんにちは 2572
    item <2573> & "co"'q' & <angle> "d" こんにちは 2573
    item <2574> & "co"'q' & <angle> "d" こんにちは 2574
    item <2575> & "co"'q' & <angle> "d" こんにちは 2575
    item <2576> & "co"'q' & <angle> "d" こんにちは 2576
    item <2577> & "co"'q' & <angle> "d" こんにちは 2577
    item <2578> & "co"'q' & <angle> "d" こんにちは 2578
    item <2579> & "co"'q' & <angle> "d" こんにちは 2579
    item <2580> & "co"'q' & <angle> "d" こんにちは 2580
    item <2581> & "co"'q' & <angle> "d" こんにちは 2581
    item <2582> & "co"'q' & <angle> "d" こんにちは 2582
    item <2583> & "co"'q' & <angle> "d" こんにちは 2583
    item <2584> & "co"'q' & <angle> "d" こんにちは 2584
    item <2585> & "co"'q' & <angle> "d" こんにちは 2585
    item <2586> & "co"'q' & <angle> "d" こんにちは 2586
    item <2587> & "co"'q' & <angle> "d" こんにちは 2587
    item <2588> & "co"'q' & <angle> "d" こんにちは 2588
    item <2589> & "co"'q' & <angle> "d" こんにちは 2589
    item <2590> & "co"'q' & <angle> "d" こんにちは 2590
    item <2591> & "co"'q' & <angle> "d" こんにちは 2591
    item <2592> & "co"'q' & <angle> "d" こんにちは 2592
    item <2593> & "co"'q' & <angle> "d" こんにちは 2593
    item <2594> & "co"'q' & <angle> "d" こんにちは 2594
    item <2595> & "co"'q' & <angle> "d" こんにちは 2595
    item <2596> & "co"'q' & <angle> "d" こんにちは 2596
    item <2597> & "co"'q' & <angle> "d" こんにちは 2597
    item <2598> & "co"'q' & <angle> "d" こんにちは 2598
    item <2599> & "co"'q' & <angle> "d" こんにちは 2599
    item <2600> & "co"'q' & <angle> "d" こんにちは 2600
    item <2601> & "co"'q' & <angle> "d" こんにちは 2601
    item <2602> & "co"'q' & <angle> "d" こんにちは 2602
    item <2603> & "co"'q' & <angle> "d" こんにちは 2603
    item <2604> & "co"'q' & <angle> "d" こんにちは 2604
    item <2605> & "co"'q' & <angle> "d" こんにちは 2605
    item <2606> & "co"'q' & <angle> "d" こんにちは 2606
    item <2607> & "co"'q' & <angle> "d" こんにちは 2607
    item <2608> & "co"'q' & <angle> "d" こんにちは 2608
    item <2609> & "co"'q' & <angle> "d" こんにちは 2609
    item <2610> & "co"'q' & <angle> "d" こんにちは 2610
    item <2611> & "co"'q' & <angle> "d" こんにちは 2611
    item <2612> & "co"'q' & <angle> "d" こんにちは 2612
    item <2613> & "co"'q' & <angle> "d" こんにちは 2613
    item <2614> & "co"'q' & <angle> "d" こんにちは 2614
    item <2615> & "co"'q' & <angle> "d" こんにちは 2615
    item <2616> & "co"'q' & <angle> "d" こんにちは 2616
    item <2617> & "co"'q' & <angle> "d" こんにちは 2617
    item <2618> & "co"'q' & <angle> "d" こんにちは 2618
    item <2619> & "co"'q' & <angle> "d" こんにちは 2619
    item <2620> & "co"'q' & <angle> "d" こんにちは 2620
    item <2621> & "co"'q' & <angle> "d" こんにちは 2621
    item <2622> & "co"'q' & <angle> "d" こんにちは 2622
    item <2623> & "co"'q' & <angle> "d" こんにちは 2623
    item <2624> & "co"'q' & <angle> "d" こんにちは 2624
    item <2625> & "co"'q' & <angle> "d" こんにちは 2625
    item <2626> & "co"'q' & <angle> "d" こんにちは 2626
    item <2627> & "co"'q' & <angle> "d" こんにちは 2627
    item <2628> & "co"'q' & <angle> "d" こんにちは 2628
    item <2629> & "co"'q' & <angle> "d" こんにちは 2629
    item <2630> & "co"'q' & <angle> "d" こんにちは 2630
    item <2631> & "co"'q' & <angle> "d" こんにちは 2631
    item <2632> & "co"'q' & <angle> "d" こんにちは 2632
    item <2633> & "co"'q' & <angle> "d" こんにちは 2633
    item <2634> & "co"'q' & <angle> "d" こんにちは 2634
    item <2635> & "co"'q' & <angle> "d" こんにちは 2635
    item <2636> & "co"'q' & <angle> "d" こんにちは 2636
    item <2637> & "co"'q' & <angle> "d" こんにちは 2637
    item <2638> & "co"'q' & <angle> "d" こんにちは 2638
    item <2639> & "co"'q' & <angle> "d" こんにちは 2639
    item <2640> & "co"'q' & <angle> "d" こんにちは 2640
    item <2641> & "co"'q' & <angle> "d" こんにちは 2641
    item <2642> & "co"'q' & <angle> "d" こんにちは 2642
    item <2643> & "co"'q' & <angle> "d" こんにちは 2643
    item <2644> & "co"'q' & <angle> "d" こんにちは 2644
    item <2645> & "co"'q' & <angle> "d" こんにちは 2645
    item <2646> & "co"'q' & <angle> "d" こんにちは 2646
    item <2647> & "co"'q' & <angle> "d" こんにちは 2647
    item <2648> & "co"'q' & <angle> "d" こんにちは 2648
    item <2649> & "co"'q' & <angle> "d" こんにちは 2649
    item <2650> & "co"'q' & <angle> "d" こんにちは 2650
    item <2651> & "co"'q' & <angle> "d" こんにちは 2651
    item <2652> & "co"'q' & <angle> "d" こんにちは 2652
    item <2653> & "co"'q' & <angle> "d" こんにちは 2653
    item <2654> & "co"'q' & <angle> "d" こんにちは 2654
    item <2655> & "co"'q' & <angle> "d" こんにちは 2655
    item <2656> & "co"'q' & <angle> "d" こんにちは 2656
    item <2657> & "co"'q' & <angle> "d" こんにちは 2657
    item <2658> & "co"'q' & <angle> "d" こんにちは 2658
    item <2659> & "co"'q' & <angle> "d" こんにちは 2659
    item <2660> & "co"'q' & <angle> "d" こんにちは 2660
    item <2661> & "co"'q' & <angle> "d" こんにちは 2661
    item <2662> & "co"'q' & <angle> "d" こんにちは 2662
    item <2663> & "co"'q' & <angle> "d" こんにちは 2663
    item <2664> & "co"'q' & <angle> "d" こんにちは 2664
    item <2665> & "co"'q' & <angle> "d" こんにちは 2665
    item <2666> & "co"'q' & <angle> "d" こんにちは 2666
    item <2667> & "co"'q' & <angle> "d" こんにちは 2667
    item <2668> & "co"'q' & <angle> "d" こんにちは 2668
    item <2669> & "co"'q' & <angle> "d" こんにちは 2669
    item <2670> & "co"'q' & <angle> "d" こんにちは 2670
    item <2671> & "co"'q' & <angle> "d" こんにちは 2671
    item <2672> & "co"'q' & <angle> "d" こんにちは 2672
    item <2673> & "co"'q' & <angle> "d" こんにちは 2673
    item <2674> & "co"'q' & <angle> "d" こんにちは 2674
    item <2675> & "co"'q' & <angle> "d" こんにちは 2675
    item <2676> & "co"'q' & <angle> "d" こんにちは 2676
    item <2677> & "co"'q' & <angle> "d" こんにちは 2677
    item <2678> & "co"'q' & <angle> "d" こんにちは 2678
    item <2679> & "co"'q' & <angle> "d" こんにちは 2679
    item <2680> & "co"'q' & <angle> "d" こんにちは 2680
    item <2681> & "co"'q' & <angle> "d" こんにちは 2681
    item <2682> & "co"'q' & <angle> "d" こんにちは 2682
    item <2683> & "co"'q' & <angle> "d" こんにちは 2683
    item <2684> & "co"'q' & <angle> "d" こんにちは 2684
    item <2685> & "co"'q' & <angle> "d" こんにちは 2685
    item <2686> & "co"'q' & <angle> "d" こんにちは 2686
    item <2687> & "co"'q' & <angle> "d" こんにちは 2687
    item <2688> & "co"'q' & <angle> "d" こんにちは 2688
    item <2689> & "co"'q' & <angle> "d" こんにちは 2689
    item <2690> & "co"'q' & <angle> "d" こんにちは 2690
    item <2691> & "co"'q' & <angle> "d" こんにちは 2691
    item <2692> & "co"'q' & <angle> "d" こんにちは 2692
    item <2693> & "co"'q' & <angle> "d" こんにちは 2693
    item <2694> & "co"'q' & <angle> "d" こんにちは 2694
    item <2695> & "co"'q' & <angle> "d" こんにちは 2695
    item <2696> & "co"'q' & <angle> "d" こんにちは 2696
    item <2697> & "co"'q' & <angle> "d" こんにちは 2697
    item <2698> & "co"'q' & <angle> "d" こんにちは 2698
    item <2699> & "co"'q' & <angle> "d" こんにちは 2699
    item <2700> & "co"'q' & <angle> "d" こんにちは 2700
    item <2701> & "co"'q' & <angle> "d" こんにちは 2701
    item <2702> & "co"'q' & <angle> "d" こんにちは 2702
    item <2703> & "co"'q' & <angle> "d" こんにちは 2703
    item <2704> & "co"'q' & <angle> "d" こんにちは 2704
    item <2705> & "co"'q' & <angle> "d" こんにちは 2705
    item <2706> & "co"'q' & <angle> "d" こんにちは 2706
    item <2707> & "co"'q' & <angle> "d" こんにちは 2707
    item <2708> & "co"'q' & <angle> "d" こんにちは 2708
    item <2709> & "co"'q' & <angle> "d" こんにちは 2709
    item <2710> & "co"'q' & <angle> "d" こんにちは 2710
    item <2711> & "co"'q' & <angle> "d" こんにちは 2711
    item <2712> & "co"'q' & <angle> "d" こんにちは 2712
    item <2713> & "co"'q' & <angle> "d" こんにちは 2713
    item <2714> & "co"'q' & <angle> "d" こんにちは 2714
    item <2715> & "co"'q' & <angle> "d" こんにちは 2715
    item <2716> & "co"'q' & <angle> "d" こんにちは 2716
    item <2717> & "co"'q' & <angle> "d" こんにちは 2717
    item <2718> & "co"'q' & <angle> "d" こんにちは 2718
    item <2719> & "co"'q' & <angle> "d" こんにちは 2719
    item <2720> & "co"'q' & <angle> "d" こんにちは 2720
    item <2721> & "co"'q' & <angle> "d" こんにちは 2721
    item <2722> & "co"'q' & <angle> "d" こんにちは 2722
    item <2723> & "co"'q' & <angle> "d" こんにちは 2723
    item <2724> & "co"'q' & <angle> "d" こんにちは 2724
    item <2725> & "co"'q' & <angle> "d" こんにちは 2725
    item <2726> & "co"'q' & <angle> "d" こんにちは 2726
    item <2727> & "co"'q' & <angle> "d" こんにちは 2727
    item <2728> & "co"'q' & <angle> "d" こんにちは 2728
    item <2729> & "co"'q' & <angle> "d" こんにちは 2729
    item <2730> & "co"'q' & <angle> "d" こんにちは 2730
    item <2731> & "co"'q' & <angle> "d" こんにちは 2731
    item <2732> & "co"'q' & <angle> "d" こんにちは 2732
    item <2733> & "co"'q' & <angle> "d" こんにちは 2733
    item <2734> & "co"'q' & <angle> "d" こんにちは 2734
    item <2735> & "co"'q' & <angle> "d" こんにちは 2735
    item <2736> & "co"'q' & <angle> "d" こんにちは 2736
    item <2737> & "co"'q' & <angle> "d" こんにちは 2737
    item <2738> & "co"'q' & <angle> "d" こんにちは 2738
    item <2739> & "co"'q' & <angle> "d" こんにちは 2739
    item <2740> & "co"'q' & <angle> "d" こんにちは 2740
    item <2741> & "co"'q' & <angle> "d" こんにちは 2741
    item <2742> & "co"'q' & <angle> "d" こんにちは 2742
    item <2743> & "co"'q' & <angle> "d" こんにちは 2743
    item <2744> & "co"'q' & <angle> "d" こんにちは 2744
    item <2745> & "co"'q' & <angle> "d" こんにちは 2745
    item <2746> & "co"'q' & <angle> "d" こんにちは 2746
    item <2747> & "co"'q' & <angle> "d" こんにちは 2747
    item <2748> & "co"'q' & <angle> "d" こんにちは 2748
    item <2749> & "co"'q' & <angle> "d" こんにちは 2749
    item <2750> & "co"'q' & <angle> "d" こんにちは 2750
    item <2751> & "co"'q' & <angle> "d" こんにちは 2751
    item <2752> & "co"'q' & <angle> "d" こんにちは 2752
    item <2753> & "co"'q' & <angle> "d" こんにちは 2753
    item <2754> & "co"'q' & <angle> "d" こんにちは 2754
    item <2755> & "co"'q' & <angle> "d" こんにちは 2755
    item <2756> & "co"'q' & <angle> "d" こんにちは 2756
    item <2757> & "co"'q' & <angle> "d" こんにちは 2757
    item <2758> & "co"'q' & <angle> "d" こんにちは 2758
    item <2759> & "co"'q' & <angle> "d" こんにちは 2759
    item <2760> & "co"'q' & <angle> "d" こんにちは 2760
    item <2761> & "co"'q' & <angle> "d" こんにちは 2761
    item <2762> & "co"'q' & <angle> "d" こんにちは 2762
    item <2763> & "co"'q' & <angle> "d" こんにちは 2763
    item <2764> & "co"'q' & <angle> "d" こんにちは 2764
    item <2765> & "co"'q' & <angle> "d" こんにちは 2765
    item <2766> & "co"'q' & <angle> "d" こんにちは 2766
    item <2767> & "co"'q' & <angle> "d" こんにちは 2767
    item <2768> & "co"'q' & <angle> "d" こんにちは 2768
    item <2769> & "co"'q' & <angle> "d" こんにちは 2769
    item <2770> & "co"'q' & <angle> "d" こんにちは 2770
    item <2771> & "co"'q' & <angle> "d" こんにちは 2771
    item <2772> & "co"'q' & <angle> "d" こんにちは 2772
    item <2773> & "co"'q' & <angle> "d" こんにちは 2773
    item <2774> & "co"'q' & <angle> "d" こんにちは 2774
    item <2775> & "co"'q' & <angle> "d" こんにちは 2775
    item <2776> & "co"'q' & <angle> "d" こんにちは 2776
    item <2777> & "co"'q' & <angle> "d" こんにちは 2777
    item <2778> & "co"'q' & <angle> "d" こんにちは 2778
    item <2779> & "co"'q' & <angle> "d" こんにちは 2779
    item <2780> & "co"'q' & <angle> "d" こんにちは 2780
    item <2781> & "co"'q' & <angle> "d" こんにちは 2781
    item <2782> & "co"'q' & <angle> "d" こんにちは 2782
    item <2783> & "co"'q' & <angle> "d" こんにちは 2783
    item <2784> & "co"'q' & <angle> "d" こんにちは 2784
    item <2785> & "co"'q' & <angle> "d" こんにちは 2785
    item <2786> & "co"'q' & <angle> "d" こんにちは 2786
    item <2787> & "co"'q' & <angle> "d" こんにちは 2787
    item <2788> & "co"'q' & <angle> "d" こんにちは 2788
    item <2789> & "co"'q' & <angle> "d" こんにちは 2789
    item <2790> & "co"'q' & <angle> "d" こんにちは 2790
    item <2791> & "co"'q' & <angle> "d" こんにちは 2791
    item <2792> & "co"'q' & <angle> "d" こんにちは 2792
    item <2793> & "co"'q' & <angle> "d" こんにちは 2793
    item <2794> & "co"'q' & <angle> "d" こんにちは 2794
    item <2795> & "co"'q' & <angle> "d" こんにちは 2795
    item <2796> & "co"'q' & <angle> "d" こんにちは 2796
    item <2797> & "co"'q' & <angle> "d" こんにちは 2797
    item <2798> & "co"'q' & <angle> "d" こんにちは 2798
    item <2799> & "co"'q' & <angle> "d" こんにちは 2799
    item <2800> & "co"'q' & <angle> "d" こんにちは 2800
    item <2801> & "co"'q' & <angle> "d" こんにちは 2801
    item <2802> & "co"'q' & <angle> "d" こんにちは 2802
    item <2803> & "co"'q' & <angle> "d" こんにちは 2803
    item <2804> & "co"'q' & <angle> "d" こんにちは 2804
    item <2805> & "co"'q' & <angle> "d" こんにちは 2805
    item <2806> & "co"'q' & <angle> "d" こんにちは 2806
    item <2807> & "co"'q' & <angle> "d" こんにちは 2807
    item <2808> & "co"'q' & <angle> "d" こんにちは 2808
    item <2809> & "co"'q' & <angle> "d" こんにちは 2809
    item <2810> & "co"'q' & <angle> "d" こんにちは 2810
    item <2811> & "co"'q' & <angle> "d" こんにちは 2811
    item <2812> & "co"'q' & <angle> "d" こんにちは 2812
    item <2813> & "co"'q' & <angle> "d" こんにちは 2813
    item <2814> & "co"'q' & <angle> "d" こんにちは 2814
    item <2815> & "co"'q' & <angle> "d" こんにちは 2815
    item <2816> & "co"'q' & <angle> "d" こんにちは 2816
    item <2817> & "co"'q' & <angle> "d" こんにちは 2817
    item <2818> & "co"'q' & <angle> "d" こんにちは 2818
    item <2819> & "co"'q' & <angle> "d" こんにちは 2819
    item <2820> & "co"'q' & <angle> "d" こんにちは 2820
    item <2821> & "co"'q' & <angle> "d" こんにちは 2821
    item <2822> & "co"'q' & <angle> "d" こんにちは 2822
    item <2823> & "co"'q' & <angle> "d" こんにちは 2823
    item <2824> & "co"'q' & <angle> "d" こんにちは 2824
    item <2825> & "co"'q' & <angle> "d" こんにちは 2825
    item <2826> & "co"'q' & <angle> "d" こんにちは 2826
    item <2827> & "co"'q' & <angle> "d" こんにちは 2827
    item <2828> & "co"'q' & <angle> "d" こんにちは 2828
    item <2829> & "co"'q' & <angle> "d" こんにちは 2829
    item <2830> & "co"'q' & <angle> "d" こんにちは 2830
    item <2831> & "co"'q' & <angle> "d" こんにちは 2831
    item <2832> & "co"'q' & <angle> "d" こんにちは 2832
    item <2833> & "co"'q' & <angle> "d" こんにちは 2833
    item <2834> & "co"'q' & <angle> "d" こんにちは 2834
    item <2835> & "co"'q' & <angle> "d" こんにちは 2835
    item <2836> & "co"'q' & <angle> "d" こんにちは 2836
    item <2837> & "co"'q' & <angle> "d" こんにちは 2837
    item <2838> & "co"'q' & <angle> "d" こんにちは 2838
    item <2839> & "co"'q' & <angle> "d" こんにちは 2839
    item <2840> & "co"'q' & <angle> "d" こんにちは 2840
    item <2841> & "co"'q' & <angle> "d" こんにちは 2841
    item <2842> & "co"'q' & <angle> "d" こんにちは 2842
    item <2843> & "co"'q' & <angle> "d" こんにちは 2843
    item <2844> & "co"'q' & <angle> "d" こんにちは 2844
    item <2845> & "co"'q' & <angle> "d" こんにちは 2845
    item <2846> & "co"'q' & <angle> "d" こんにちは 2846
    item <2847> & "co"'q' & <angle> "d" こんにちは 2847
    item <2848> & "co"'q' & <angle> "d" こんにちは 2848
    item <2849> & "co"'q' & <angle> "d" こんにちは 2849
    item <2850> & "co"'q' & <angle> "d" こんにちは 2850
    item <2851> & "co"'q' & <angle> "d" こんにちは 2851
    item <2852> & "co"'q' & <angle> "d" こんにちは 2852
    item <2853> & "co"'q' & <angle> "d" こんにちは 2853
    item <2854> & "co"'q' & <angle> "d" こんにちは 2854
    item <2855> & "co"'q' & <angle> "d" こんにちは 2855
    item <2856> & "co"'q' & <angle> "d" こんにちは 2856
    item <2857> & "co"'q' & <angle> "d" こんにちは 2857
    item <2858> & "co"'q' & <angle> "d" こんにちは 2858
    item <2859> & "co"'q' & <angle> "d" こんにちは 2859
    item <2860> & "co"'q' & <angle> "d" こんにちは 2860
    item <2861> & "co"'q' & <angle> "d" こんにちは 2861
    item <2862> & "co"'q' & <angle> "d" こんにちは 2862
    item <2863> & "co"'q' & <angle> "d" こんにちは 2863
    item <2864> & "co"'q' & <angle> "d" こんにちは 2864
    item <2865> & "co"'q' & <angle> "d" こんにちは 2865
    item <2866> & "co"'q' & <angle> "d" こんにちは 2866
    item <2867> & "co"'q' & <angle> "d" こんにちは 2867
    item <2868> & "co"'q' & <angle> "d" こんにちは 2868
    item <2869> & "co"'q' & <angle> "d" こんにちは 2869
    item <2870> & "co"'q' & <angle> "d" こんにちは 2870
    item <2871> & "co"'q' & <angle> "d" こんにちは 2871
    item <2872> & "co"'q' & <angle> "d" こんにちは 2872
    item <2873> & "co"'q' & <angle> "d" こんにちは 2873
    item <2874> & "co"'q' & <angle> "d" こんにちは 2874
    item <2875> & "co"'q' & <angle> "d" こんにちは 2875
    item <2876> & "co"'q' & <angle> "d" こんにちは 2876
    item <2877> & "co"'q' & <angle> "d" こんにちは 2877
    item <2878> & "co"'q' & <angle> "d" こんにちは 2878
    item <2879> & "co"'q' & <angle> "d" こんにちは 2879
    item <2880> & "co"'q' & <angle> "d" こんにちは 2880
    item <2881> & "co"'q' & <angle> "d" こんにちは 2881
    item <2882> & "co"'q' & <angle> "d" こんにちは 2882
    item <2883> & "co"'q' & <angle> "d" こんにちは 2883
    item <2884> & "co"'q' & <angle> "d" こんにちは 2884
    item <2885> & "co"'q' & <angle> "d" こんにちは 2885
    item <2886> & "co"'q' & <angle> "d" こんにちは 2886
    item <2887> & "co"'q' & <angle> "d" こんにちは 2887
    item <2888> & "co"'q' & <angle> "d" こんにちは 2888
    item <2889> & "co"'q' & <angle> "d" こんにちは 2889
    item <2890> & "co"'q' & <angle> "d" こんにちは 2890
    item <2891> & "co"'q' & <angle> "d" こんにちは 2891
    item <2892> & "co"'q' & <angle> "d" こんにちは 2892
    item <2893> & "co"'q' & <angle> "d" こんにちは 2893
    item <2894> & "co"'q' & <angle> "d" こんにちは 2894
    item <2895> & "co"'q' & <angle> "d" こんにちは 2895
    item <2896> & "co"'q' & <angle> "d" こんにちは 2896
    item <2897> & "co"'q' & <angle> "d" こんにちは 2897
    item <2898> & "co"'q' & <angle> "d" こんにちは 2898
    item <2899> & "co"'q' & <angle> "d" こんにちは 2899
    item <2900> & "co"'q' & <angle> "d" こんにちは 2900
    item <2901> & "co"'q' & <angle> "d" こんにちは 2901
    item <2902> & "co"'q' & <angle> "d" こんにちは 2902
    item <2903> & "co"'q' & <angle> "d" こんにちは 2903
    item <2904> & "co"'q' & <angle> "d" こんにちは 2904
    item <2905> & "co"'q' & <angle> "d" こんにちは 2905
    item <2906> & "co"'q' & <angle> "d" こんにちは 2906
    item <2907> & "co"'q' & <angle> "d" こんにちは 2907
    item <2908> & "co"'q' & <angle> "d" こんにちは 2908
    item <2909> & "co"'q' & <angle> "d" こんにちは 2909
    item <2910> & "co"'q' & <angle> "d" こんにちは 2910
    item <2911> & "co"'q' & <angle> "d" こんにちは 2911
    item <2912> & "co"'q' & <angle> "d" こんにちは 2912
    item <2913> & "co"'q' & <angle> "d" こんにちは 2913
    item <2914> & "co"'q' & <angle> "d" こんにちは 2914
    item <2915> & "co"'q' & <angle> "d" こんにちは 2915
    item <2916> & "co"'q' & <angle> "d" こんにちは 2916
    item <2917> & "co"'q' & <angle> "d" こんにちは 2917
    item <2918> & "co"'q' & <angle> "d" こんにちは 2918
    item <2919> & "co"'q' & <angle> "d" こんにちは 2919
    item <2920> & "co"'q' & <angle> "d" こんにちは 2920
    item <2921> & "co"'q' & <angle> "d" こんにちは 2921
    item <2922> & "co"'q' & <angle> "d" こんにちは 2922
    item <2923> & "co"'q' & <angle> "d" こんにちは 2923
    item <2924> & "co"'q' & <angle> "d" こんにちは 2924
    item <2925> & "co"'q' & <angle> "d" こんにちは 2925
    item <2926> & "co"'q' & <angle> "d" こんにちは 2926
    item <2927> & "co"'q' & <angle> "d" こんにちは 2927
    item <2928> & "co"'q' & <angle> "d" こんにちは 2928
    item <2929> & "co"'q' & <angle> "d" こんにちは 2929
    item <2930> & "co"'q' & <angle> "d" こんにちは 2930
    item <2931> & "co"'q' & <angle> "d" こんにちは 2931
    item <2932> & "co"'q' & <angle> "d" こんにちは 2932
    item <2933> & "co"'q' & <angle> "d" こんにちは 2933
    item <2934> & "co"'q' & <angle> "d" こんにちは 2934
    item <2935> & "co"'q' & <angle> "d" こんにちは 2935
    item <2936> & "co"'q' & <angle> "d" こんにちは 2936
    item <2937> & "co"'q' & <angle> "d" こんにちは 2937
    item <2938> & "co"'q' & <angle> "d" こんにちは 2938
    item <2939> & "co"'q' & <angle> "d" こんにちは 2939
    item <2940> & "co"'q' & <angle> "d" こんにちは 2940
    item <2941> & "co"'q' & <angle> "d" こんにちは 2941
    item <2942> & "co"'q' & <angle> "d" こんにちは 2942
    item <2943> & "co"'q' & <angle> "d" こんにちは 2943
    item <2944> & "co"'q' & <angle> "d" こんにちは 2944
    item <2945> & "co"'q' & <angle> "d" こんにちは 2945
    item <2946> & "co"'q' & <angle> "d" こんにちは 2946
    item <2947> & "co"'q' & <angle> "d" こんにちは 2947
    item <2948> & "co"'q' & <angle> "d" こんにちは 2948
    item <2949> & "co"'q' & <angle> "d" こんにちは 2949
    item <2950> & "co"'q' & <angle> "d" こんにちは 2950
    item <2951> & "co"'q' & <angle> "d" こんにちは 2951
    item <2952> & "co"'q' & <angle> "d" こんにちは 2952
    item <2953> & "co"'q' & <angle> "d" こんにちは 2953
    item <2954> & "co"'q' & <angle> "d" こんにちは 2954
    item <2955> & "co"'q' & <angle> "d" こんにちは 2955
    item <2956> & "co"'q' & <angle> "d" こんにちは 2956
    item <2957> & "co"'q' & <angle> "d" こんにちは 2957
    item <2958> & "co"'q' & <angle> "d" こんにちは 2958
    item <2959> & "co"'q' & <angle> "d" こんにちは 2959
    item <2960> & "co"'q' & <angle> "d" こんにちは 2960
    item <2961> & "co"'q' & <angle> "d" こんにちは 2961
    item <2962> & "co"'q' & <angle> "d" こんにちは 2962
    item <2963> & "co"'q' & <angle> "d" こんにちは 2963
    item <2964> & "co"'q' & <angle> "d" こんにちは 2964
    item <2965> & "co"'q' & <angle> "d" こんにちは 2965
    item <2966> & "co"'q' & <angle> "d" こんにちは 2966
    item <2967> & "co"'q' & <angle> "d" こんにちは 2967
    item <2968> & "co"'q' & <angle> "d" こんにちは 2968
    item <2969> & "co"'q' & <angle> "d" こんにちは 2969
    item <2970> & "co"'q' & <angle> "d" こんにちは 2970
    item <2971> & "co"'q' & <angle> "d" こんにちは 2971
    item <2972> & "co"'q' & <angle> "d" こんにちは 2972
    item <2973> & "co"'q' & <angle> "d" こんにちは 2973
    item <2974> & "co"'q' & <angle> "d" こんにちは 2974
    item <2975> & "co"'q' & <angle> "d" こんにちは 2975
    item <2976> & "co"'q' & <angle> "d" こんにちは 2976
    item <2977> & "co"'q' & <angle> "d" こんにちは 2977
    item <2978> & "co"'q' & <angle> "d" こんにちは 2978
    item <2979> & "co"'q' & <angle> "d" こんにちは 2979
    item <2980> & "co"'q' & <angle> "d" こんにちは 2980
    item <2981> & "co"'q' & <angle> "d" こんにちは 2981
    item <2982> & "co"'q' & <angle> "d" こんにちは 2982
    item <2983> & "co"'q' & <angle> "d" こんにちは 2983
    item <2984> & "co"'q' & <angle> "d" こんにちは 2984
    item <2985> & "co"'q' & <angle> "d" こんにちは 2985
    item <2986> & "co"'q' & <angle> "d" こんにちは 2986
    item <2987> & "co"'q' & <angle> "d" こんにちは 2987
    item <2988> & "co"'q' & <angle> "d" こんにちは 2988
    item <2989> & "co"'q' & <angle> "d" こんにちは 2989
    item <2990> & "co"'q' & <angle> "d" こんにちは 2990
    item <2991> & "co"'q' & <angle> "d" こんにちは 2991
    item <2992> & "co"'q' & <angle> "d" こんにちは 2992
    item <2993> & "co"'q' & <angle> "d" こんにちは 2993
    item <2994> & "co"'q' & <angle> "d" こんにちは 2994
    item <2995> & "co"'q' & <angle> "d" こんにちは 2995
    item <2996> & "co"'q' & <angle> "d" こんにちは 2996
    item <2997> & "co"'q' & <angle> "d" こんにちは 2997
    item <2998> & "co"'q' & <angle> "d" こんにちは 2998
    item <2999> & "co"'q' & <angle> "d" こんにちは 2999
    item <3000> & "co"'q' & <angle> "d" こんにちは 3000
    item <3001> & "co"'q' & <angle> "d" こんにちは 3001
    item <3002> & "co"'q' & <angle> "d" こんにちは 3002
    item <3003> & "co"'q' & <angle> "d" こんにちは 3003
    item <3004> & "co"'q' & <angle> "d" こんにちは 3004
    item <3005> & "co"'q' & <angle> "d" こんにちは 3005
    item <3006> & "co"'q' & <angle> "d" こんにちは 3006
    item <3007> & "co"'q' & <angle> "d" こんにちは 3007
    item <3008> & "co"'q' & <angle> "d" こんにちは 3008
    item <3009> & "co"'q' & <angle> "d" こんにちは 3009
    item <3010> & "co"'q' & <angle> "d" こんにちは 3010
    item <3011> & "co"'q' & <angle> "d" こんにちは 3011
    item <3012> & "co"'q' & <angle> "d" こんにちは 3012
    item <3013> & "co"'q' & <angle> "d" こんにちは 3013
    item <3014> & "co"'q' & <angle> "d" こんにちは 3014
    item <3015> & "co"'q' & <angle> "d" こんにちは 3015
    item <3016> & "co"'q' & <angle> "d" こんにちは 3016
    item <3017> & "co"'q' & <angle> "d" こんにちは 3017
    item <3018> & "co"'q' & <angle> "d" こんにちは 3018
    item <3019> & "co"'q' & <angle> "d" こんにちは 3019
    item <3020> & "co"'q' & <angle> "d" こんにちは 3020
    item <3021> & "co"'q' & <angle> "d" こんにちは 3021
    item <3022> & "co"'q' & <angle> "d" こんにちは 3022
    item <3023> & "co"'q' & <angle> "d" こんにちは 3023
    item <3024> & "co"'q' & <angle> "d" こんにちは 3024
    item <3025> & "co"'q' & <angle> "d" こんにちは 3025
    item <3026> & "co"'q' & <angle> "d" こんにちは 3026
    item <3027> & "co"'q' & <angle> "d" こんにちは 3027
    item <3028> & "co"'q' & <angle> "d" こんにちは 3028
    item <3029> & "co"'q' & <angle> "d" こんにちは 3029
    item <3030> & "co"'q' & <angle> "d" こんにちは 3030
    item <3031> & "co"'q' & <angle> "d" こんにちは 3031
    item <3032> & "co"'q' & <angle> "d" こんにちは 3032
    item <3033> & "co"'q' & <angle> "d" こんにちは 3033
    item <3034> & "co"'q' & <angle> "d" こんにちは 3034
    item <3035> & "co"'q' & <angle> "d" こんにちは 3035
    item <3036> & "co"'q' & <angle> "d" こんにちは 3036
    item <3037> & "co"'q' & <angle> "d" こんにちは 3037
    item <3038> & "co"'q' & <angle> "d" こんにちは 3038
    item <3039> & "co"'q' & <angle> "d" こんにちは 3039
    item <3040> & "co"'q' & <angle> "d" こんにちは 3040
    item <3041> & "co"'q' & <angle> "d" こんにちは 3041
    item <3042> & "co"'q' & <angle> "d" こんにちは 3042
    item <3043> & "co"'q' & <angle> "d" こんにちは 3043
    item <3044> & "co"'q' & <angle> "d" こんにちは 3044
    item <3045> & "co"'q' & <angle> "d" こんにちは 3045
    item <3046> & "co"'q' & <angle> "d" こんにちは 3046
    item <3047> & "co"'q' & <angle> "d" こんにちは 3047
    item <3048> & "co"'q' & <angle> "d" こんにちは 3048
    item <3049> & "co"'q' & <angle> "d" こんにちは 3049
    item <3050> & "co"'q' & <angle> "d" こんにちは 3050
    item <3051> & "co"'q' & <angle> "d" こんにちは 3051
    item <3052> & "co"'q' & <angle> "d" こんにちは 3052
    item <3053> & "co"'q' & <angle> "d" こんにちは 3053
    item <3054> & "co"'q' & <angle> "d" こんにちは 3054
    item <3055> & "co"'q' & <angle> "d" こんにちは 3055
    item <3056> & "co"'q' & <angle> "d" こんにちは 3056
    item <3057> & "co"'q' & <angle> "d" こんにちは 3057
    item <3058> & "co"'q' & <angle> "d" こんにちは 3058
    item <3059> & "co"'q' & <angle> "d" こんにちは 3059
    item <3060> & "co"'q' & <angle> "d" こんにちは 3060
    item <3061> & "co"'q' & <angle> "d" こんにちは 3061
    item <3062> & "co"'q' & <angle> "d" こんにちは 3062
    item <3063> & "co"'q' & <angle> "d" こんにちは 3063
    item <3064> & "co"'q' & <angle> "d" こんにちは 3064
    item <3065> & "co"'q' & <angle> "d" こんにちは 3065
    item <3066> & "co"'q' & <angle> "d" こんにちは 3066
    item <3067> & "co"'q' & <angle> "d" こんにちは 3067
    item <3068> & "co"'q' & <angle> "d" こんにちは 3068
    item <3069> & "co"'q' & <angle> "d" こんにちは 3069
    item <3070> & "co"'q' & <angle> "d" こんにちは 3070
    item <3071> & "co"'q' & <angle> "d" こんにちは 3071
    item <3072> & "co"'q' & <angle> "d" こんにちは 3072
    item <3073> & "co"'q' & <angle> "d" こんにちは 3073
    item <3074> & "co"'q' & <angle> "d" こんにちは 3074
    item <3075> & "co"'q' & <angle> "d" こんにちは 3075
    item <3076> & "co"'q' & <angle> "d" こんにちは 3076
    item <3077> & "co"'q' & <angle> "d" こんにちは 3077
    item <3078> & "co"'q' & <angle> "d" こんにちは 3078
    item <3079> & "co"'q' & <angle> "d" こんにちは 3079
    item <3080> & "co"'q' & <angle> "d" こんにちは 3080
    item <3081> & "co"'q' & <angle> "d" こんにちは 3081
    item <3082> & "co"'q' & <angle> "d" こんにちは 3082
    item <3083> & "co"'q' & <angle> "d" こんにちは 3083
    item <3084> & "co"'q' & <angle> "d" こんにちは 3084
    item <3085> & "co"'q' & <angle> "d" こんにちは 3085
    item <3086> & "co"'q' & <angle> "d" こんにちは 3086
    item <3087> & "co"'q' & <angle> "d" こんにちは 3087
    item <3088> & "co"'q' & <angle> "d" こんにちは 3088
    item <3089> & "co"'q' & <angle> "d" こんにちは 3089
    item <3090> & "co"'q' & <angle> "d" こんにちは 3090
    item <3091> & "co"'q' & <angle> "d" こんにちは 3091
    item <3092> & "co"'q' & <angle> "d" こんにちは 3092
    item <3093> & "co"'q' & <angle> "d" こんにちは 3093
    item <3094> & "co"'q' & <angle> "d" こんにちは 3094
    item <3095> & "co"'q' & <angle> "d" こんにちは 3095
    item <3096> & "co"'q' & <angle> "d" こんにちは 3096
    item <3097> & "co"'q' & <angle> "d" こんにちは 3097
    item <3098> & "co"'q' & <angle> "d" こんにちは 3098
    item <3099> & "co"'q' & <angle> "d" こんにちは 3099
    item <3100> & "co"'q' & <angle> "d" こんにちは 3100
    item <3101> & "co"'q' & <angle> "d" こんにちは 3101
    item <3102> & "co"'q' & <angle> "d" こんにちは 3102
    item <3103> & "co"'q' & <angle> "d" こんにちは 3103
    item <3104> & "co"'q' & <angle> "d" こんにちは 3104
    item <3105> & "co"'q' & <angle> "d" こんにちは 3105
    item <3106> & "co"'q' & <angle> "d" こんにちは 3106
    item <3107> & "co"'q' & <angle> "d" こんにちは 3107
    item <3108> & "co"'q' & <angle> "d" こんにちは 3108
    item <3109> & "co"'q' & <angle> "d" こんにちは 3109
    item <3110> & "co"'q' & <angle> "d" こんにちは 3110
    item <3111> & "co"'q' & <angle> "d" こんにちは 3111
    item <3112> & "co"'q' & <angle> "d" こんにちは 3112
    item <3113> & "co"'q' & <angle> "d" こんにちは 3113
    item <3114> & "co"'q' & <angle> "d" こんにちは 3114
    item <3115> & "co"'q' & <angle> "d" こんにちは 3115
    item <3116> & "co"'q' & <angle> "d" こんにちは 3116
    item <3117> & "co"'q' & <angle> "d" こんにちは 3117
    item <3118> & "co"'q' & <angle> "d" こんにちは 3118
    item <3119> & "co"'q' & <angle> "d" こんにちは 3119
    item <3120> & "co"'q' & <angle> "d" こんにちは 3120
    item <3121> & "co"'q' & <angle> "d" こんにちは 3121
    item <3122> & "co"'q' & <angle> "d" こんにちは 3122
    item <3123> & "co"'q' & <angle> "d" こんにちは 3123
    item <3124> & "co"'q' & <angle> "d" こんにちは 3124
    item <3125> & "co"'q' & <angle> "d" こんにちは 3125
    item <3126> & "co"'q' & <angle> "d" こんにちは 3126
    item <3127> & "co"'q' & <angle> "d" こんにちは 3127
    item <3128> & "co"'q' & <angle> "d" こんにちは 3128
    item <3129> & "co"'q' & <angle> "d" こんにちは 3129
    item <3130> & "co"'q' & <angle> "d" こんにちは 3130
    item <3131> & "co"'q' & <angle> "d" こんにちは 3131
    item <3132> & "co"'q' & <angle> "d" こんにちは 3132
    item <3133> & "co"'q' & <angle> "d" こんにちは 3133
    item <3134> & "co"'q' & <angle> "d" こんにちは 3134
    item <3135> & "co"'q' & <angle> "d" こんにちは 3135
    item <3136> & "co"'q' & <angle> "d" こんにちは 3136
    item <3137> & "co"'q' & <angle> "d" こんにちは 3137
    item <3138> & "co"'q' & <angle> "d" こんにちは 3138
    item <3139> & "co"'q' & <angle> "d" こんにちは 3139
    item <3140> & "co"'q' & <angle> "d" こんにちは 3140
    item <3141> & "co"'q' & <angle> "d" こんにちは 3141
    item <3142> & "co"'q' & <angle> "d" こんにちは 3142
    item <3143> & "co"'q' & <angle> "d" こんにちは 3143
    item <3144> & "co"'q' & <angle> "d" こんにちは 3144
    item <3145> & "co"'q' & <angle> "d" こんにちは 3145
    item <3146> & "co"'q' & <angle> "d" こんにちは 3146
    item <3147> & "co"'q' & <angle> "d" こんにちは 3147
    item <3148> & "co"'q' & <angle> "d" こんにちは 3148
    item <3149> & "co"'q' & <angle> "d" こんにちは 3149
    item <3150> & "co"'q' & <angle> "d" こんにちは 3150
    item <3151> & "co"'q' & <angle> "d" こんにちは 3151
    item <3152> & "co"'q' & <angle> "d" こんにちは 3152
    item <3153> & "co"'q' & <angle> "d" こんにちは 3153
    item <3154> & "co"'q' & <angle> "d" こんにちは 3154
    item <3155> & "co"'q' & <angle> "d" こんにちは 3155
    item <3156> & "co"'q' & <angle> "d" こんにちは 3156
    item <3157> & "co"'q' & <angle> "d" こんにちは 3157
    item <3158> & "co"'q' & <angle> "d" こんにちは 3158
    item <3159> & "co"'q' & <angle> "d" こんにちは 3159
    item <3160> & "co"'q' & <angle> "d" こんにちは 3160
    item <3161> & "co"'q' & <angle> "d" こんにちは 3161
    item <3162> & "co"'q' & <angle> "d" こんにちは 3162
    item <3163> & "co"'q' & <angle> "d" こんにちは 3163
    item <3164> & "co"'q' & <angle> "d" こんにちは 3164
    item <3165> & "co"'q' & <angle> "d" こんにちは 3165
    item <3166> & "co"'q' & <angle> "d" こんにちは 3166
    item <3167> & "co"'q' & <angle> "d" こんにちは 3167
    item <3168> & "co"'q' & <angle> "d" こんにちは 3168
    item <3169> & "co"'q' & <angle> "d" こんにちは 3169
    item <3170> & "co"'q' & <angle> "d" こんにちは 3170
    item <3171> & "co"'q' & <angle> "d" こんにちは 3171
    item <3172> & "co"'q' & <angle> "d" こんにちは 3172
    item <3173> & "co"'q' & <angle> "d" こんにちは 3173
    item <3174> & "co"'q' & <angle> "d" こんにちは 3174
    item <3175> & "co"'q' & <angle> "d" こんにちは 3175
    item <3176> & "co"'q' & <angle> "d" こんにちは 3176
    item <3177> & "co"'q' & <angle> "d" こんにちは 3177
    item <3178> & "co"'q' & <angle> "d" こんにちは 3178
    item <3179> & "co"'q' & <angle> "d" こんにちは 3179
    item <3180> & "co"'q' & <angle> "d" こんにちは 3180
    item <3181> & "co"'q' & <angle> "d" こんにちは 3181
    item <3182> & "co"'q' & <angle> "d" こんにちは 3182
    item <3183> & "co"'q' & <angle> "d" こんにちは 3183
    item <3184> & "co"'q' & <angle> "d" こんにちは 3184
    item <3185> & "co"'q' & <angle> "d" こんにちは 3185
    item <3186> & "co"'q' & <angle> "d" こんにちは 3186
    item <3187> & "co"'q' & <angle> "d" こんにちは 3187
    item <3188> & "co"'q' & <angle> "d" こんにちは 3188
    item <3189> & "co"'q' & <angle> "d" こんにちは 3189
    item <3190> & "co"'q' & <angle> "d" こんにちは 3190
    item <3191> & "co"'q' & <angle> "d" こんにちは 3191
    item <3192> & "co"'q' & <angle> "d" こんにちは 3192
    item <3193> & "co"'q' & <angle> "d" こんにちは 3193
    item <3194> & "co"'q' & <angle> "d" こんにちは 3194
    item <3195> & "co"'q' & <angle> "d" こんにちは 3195
    item <3196> & "co"'q' & <angle> "d" こんにちは 3196
    item <3197> & "co"'q' & <angle> "d" こんにちは 3197
    item <3198> & "co"'q' & <angle> "d" こんにちは 3198
    item <3199> & "co"'q' & <angle> "d" こんにちは 3199
    item <3200> & "co"'q' & <angle> "d" こんにちは 3200
    item <3201> & "co"'q' & <angle> "d" こんにちは 3201
    item <3202> & "co"'q' & <angle> "d" こんにちは 3202
    item <3203> & "co"'q' & <angle> "d" こんにちは 3203
    item <3204> & "co"'q' & <angle> "d" こんにちは 3204
    item <3205> & "co"'q' & <angle> "d" こんにちは 3205
    item <3206> & "co"'q' & <angle> "d" こんにちは 3206
    item <3207> & "co"'q' & <angle> "d" こんにちは 3207
    item <3208> & "co"'q' & <angle> "d" こんにちは 3208
    item <3209> & "co"'q' & <angle> "d" こんにちは 3209
    item <3210> & "co"'q' & <angle> "d" こんにちは 3210
    item <3211> & "co"'q' & <angle> "d" こんにちは 3211
    item <3212> & "co"'q' & <angle> "d" こんにちは 3212
    item <3213> & "co"'q' & <angle> "d" こんにちは 3213
    item <3214> & "co"'q' & <angle> "d" こんにちは 3214
    item <3215> & "co"'q' & <angle> "d" こんにちは 3215
    item <3216> & "co"'q' & <angle> "d" こんにちは 3216
    item <3217> & "co"'q' & <angle> "d" こんにちは 3217
    item <3218> & "co"'q' & <angle> "d" こんにちは 3218
    item <3219> & "co"'q' & <angle> "d" こんにちは 3219
    item <3220> & "co"'q' & <angle> "d" こんにちは 3220
    item <3221> & "co"'q' & <angle> "d" こんにちは 3221
    item <3222> & "co"'q' & <angle> "d" こんにちは 3222
    item <3223> & "co"'q' & <angle> "d" こんにちは 3223
    item <3224> & "co"'q' & <angle> "d" こんにちは 3224
    item <3225> & "co"'q' & <angle> "d" こんにちは 3225
    item <3226> & "co"'q' & <angle> "d" こんにちは 3226
    item <3227> & "co"'q' & <angle> "d" こんにちは 3227
    item <3228> & "co"'q' & <angle> "d" こんにちは 3228
    item <3229> & "co"'q' & <angle> "d" こんにちは 3229
    item <3230> & "co"'q' & <angle> "d" こんにちは 3230
    item <3231> & "co"'q' & <angle> "d" こんにちは 3231
    item <3232> & "co"'q' & <angle> "d" こんにちは 3232
    item <3233> & "co"'q' & <angle> "d" こんにちは 3233
    item <3234> & "co"'q' & <angle> "d" こんにちは 3234
    item <3235> & "co"'q' & <angle> "d" こんにちは 3235
    item <3236> & "co"'q' & <angle> "d" こんにちは 3236
    item <3237> & "co"'q' & <angle> "d" こんにちは 3237
    item <3238> & "co"'q' & <angle> "d" こんにちは 3238
    item <3239> & "co"'q' & <angle> "d" こんにちは 3239
    item <3240> & "co"'q' & <angle> "d" こんにちは 3240
    item <3241> & "co"'q' & <angle> "d" こんにちは 3241
    item <3242> & "co"'q' & <angle> "d" こんにちは 3242
    item <3243> & "co"'q' & <angle> "d" こんにちは 3243
    item <3244> & "co"'q' & <angle> "d" こんにちは 3244
    item <3245> & "co"'q' & <angle> "d" こんにちは 3245
    item <3246> & "co"'q' & <angle> "d" こんにちは 3246
    item <3247> & "co"'q' & <angle> "d" こんにちは 3247
    item <3248> & "co"'q' & <angle> "d" こんにちは 3248
    item <3249> & "co"'q' & <angle> "d" こんにちは 3249
    item <3250> & "co"'q' & <angle> "d" こんにちは 3250
    item <3251> & "co"'q' & <angle> "d" こんにちは 3251
    item <3252> & "co"'q' & <angle> "d" こんにちは 3252
    item <3253> & "co"'q' & <angle> "d" こんにちは 3253
    item <3254> & "co"'q' & <angle> "d" こんにちは 3254
    item <3255> & "co"'q' & <angle> "d" こんにちは 3255
    item <3256> & "co"'q' & <angle> "d" こんにちは 3256
    item <3257> & "co"'q' & <angle> "d" こんにちは 3257
    item <3258> & "co"'q' & <angle> "d" こんにちは 3258
    item <3259> & "co"'q' & <angle> "d" こんにちは 3259
    item <3260> & "co"'q' & <angle> "d" こんにちは 3260
    item <3261> & "co"'q' & <angle> "d" こんにちは 3261
    item <3262> & "co"'q' & <angle> "d" こんにちは 3262
    item <3263> & "co"'q' & <angle> "d" こんにちは 3263
    item <3264> & "co"'q' & <angle> "d" こんにちは 3264
    item <3265> & "co"'q' & <angle> "d" こんにちは 3265
    item <3266> & "co"'q' & <angle> "d" こんにちは 3266
    item <3267> & "co"'q' & <angle> "d" こんにちは 3267
    item <3268> & "co"'q' & <angle> "d" こんにちは 3268
    item <3269> & "co"'q' & <angle> "d" こんにちは 3269
    item <3270> & "co"'q' & <angle> "d" こんにちは 3270
    item <3271> & "co"'q' & <angle> "d" こんにちは 3271
    item <3272> & "co"'q' & <angle> "d" こんにちは 3272
    item <3273> & "co"'q' & <angle> "d" こんにちは 3273
    item <3274> & "co"'q' & <angle> "d" こんにちは 3274
    item <3275> & "co"'q' & <angle> "d" こんにちは 3275
    item <3276> & "co"'q' & <angle> "d" こんにちは 3276
    item <3277> & "co"'q' & <angle> "d" こんにちは 3277
    item <3278> & "co"'q' & <angle> "d" こんにちは 3278
    item <3279> & "co"'q' & <angle> "d" こんにちは 3279
    item <3280> & "co"'q' & <angle> "d" こんにちは 3280
    item <3281> & "co"'q' & <angle> "d" こんにちは 3281
    item <3282> & "co"'q' & <angle> "d" こんにちは 3282
    item <3283> & "co"'q' & <angle> "d" こんにちは 3283
    item <3284> & "co"'q' & <angle> "d" こんにちは 3284
    item <3285> & "co"'q' & <angle> "d" こんにちは 3285
    item <3286> & "co"'q' & <angle> "d" こんにちは 3286
    item <3287> & "co"'q' & <angle> "d" こんにちは 3287
    item <3288> & "co"'q' & <angle> "d" こんにちは 3288
    item <3289> & "co"'q' & <angle> "d" こんにちは 3289
    item <3290> & "co"'q' & <angle> "d" こんにちは 3290
    item <3291> & "co"'q' & <angle> "d" こんにちは 3291
    item <3292> & "co"'q' & <angle> "d" こんにちは 3292
    item <3293> & "co"'q' & <angle> "d" こんにちは 3293
    item <3294> & "co"'q' & <angle> "d" こんにちは 3294
    item <3295> & "co"'q' & <angle> "d" こんにちは 3295
    item <3296> & "co"'q' & <angle> "d" こんにちは 3296
    item <3297> & "co"'q' & <angle> "d" こんにちは 3297
    item <3298> & "co"'q' & <angle> "d" こんにちは 3298
    item <3299> & "co"'q' & <angle> "d" こんにちは 3299
    item <3300> & "co"'q' & <angle> "d" こんにちは 3300
    item <3301> & "co"'q' & <angle> "d" こんにちは 3301
    item <3302> & "co"'q' & <angle> "d" こんにちは 3302
    item <3303> & "co"'q' & <angle> "d" こんにちは 3303
    item <3304> & "co"'q' & <angle> "d" こんにちは 3304
    item <3305> & "co"'q' & <angle> "d" こんにちは 3305
    item <3306> & "co"'q' & <angle> "d" こんにちは 3306
    item <3307> & "co"'q' & <angle> "d" こんにちは 3307
    item <3308> & "co"'q' & <angle> "d" こんにちは 3308
    item <3309> & "co"'q' & <angle> "d" こんにちは 3309
    item <3310> & "co"'q' & <angle> "d" こんにちは 3310
    item <3311> & "co"'q' & <angle> "d" こんにちは 3311
    item <3312> & "co"'q' & <angle> "d" こんにちは 3312
    item <3313> & "co"'q' & <angle> "d" こんにちは 3313
    item <3314> & "co"'q' & <angle> "d" こんにちは 3314
    item <3315> & "co"'q' & <angle> "d" こんにちは 3315
    item <3316> & "co"'q' & <angle> "d" こんにちは 3316
    item <3317> & "co"'q' & <angle> "d" こんにちは 3317
    item <3318> & "co"'q' & <angle> "d" こんにちは 3318
    item <3319> & "co"'q' & <angle> "d" こんにちは 3319
    item <3320> & "co"'q' & <angle> "d" こんにちは 3320
    item <3321> & "co"'q' & <angle> "d" こんにちは 3321
    item <3322> & "co"'q' & <angle> "d" こんにちは 3322
    item <3323> & "co"'q' & <angle> "d" こんにちは 3323
    item <3324> & "co"'q' & <angle> "d" こんにちは 3324
    item <3325> & "co"'q' & <angle> "d" こんにちは 3325
    item <3326> & "co"'q' & <angle> "d" こんにちは 3326
    item <3327> & "co"'q' & <angle> "d" こんにちは 3327
    item <3328> & "co"'q' & <angle> "d" こんにちは 3328
    item <3329> & "co"'q' & <angle> "d" こんにちは 3329
    item <3330> & "co"'q' & <angle> "d" こんにちは 3330
    item <3331> & "co"'q' & <angle> "d" こんにちは 3331
    item <3332> & "co"'q' & <angle> "d" こんにちは 3332
    item <3333> & "co"'q' & <angle> "d" こんにちは 3333
    item <3334> & "co"'q' & <angle> "d" こんにちは 3334
    item <3335> & "co"'q' & <angle> "d" こんにちは 3335
    item <3336> & "co"'q' & <angle> "d" こんにちは 3336
    item <3337> & "co"'q' & <angle> "d" こんにちは 3337
    item <3338> & "co"'q' & <angle> "d" こんにちは 3338
    item <3339> & "co"'q' & <angle> "d" こんにちは 3339
    item <3340> & "co"'q' & <angle> "d" こんにちは 3340
    item <3341> & "co"'q' & <angle> "d" こんにちは 3341
    item <3342> & "co"'q' & <angle> "d" こんにちは 3342
    item <3343> & "co"'q' & <angle> "d" こんにちは 3343
    item <3344> & "co"'q' & <angle> "d" こんにちは 3344
    item <3345> & "co"'q' & <angle> "d" こんにちは 3345
    item <3346> & "co"'q' & <angle> "d" こんにちは 3346
    item <3347> & "co"'q' & <angle> "d" こんにちは 3347
    item <3348> & "co"'q' & <angle> "d" こんにちは 3348
    item <3349> & "co"'q' & <angle> "d" こんにちは 3349
    item <3350> & "co"'q' & <angle> "d" こんにちは 3350
    item <3351> & "co"'q' & <angle> "d" こんにちは 3351
    item <3352> & "co"'q' & <angle> "d" こんにちは 3352
    item <3353> & "co"'q' & <angle> "d" こんにちは 3353
    item <3354> & "co"'q' & <angle> "d" こんにちは 3354
    item <3355> & "co"'q' & <angle> "d" こんにちは 3355
    item <3356> & "co"'q' & <angle> "d" こんにちは 3356
    item <3357> & "co"'q' & <angle> "d" こんにちは 3357
    item <3358> & "co"'q' & <angle> "d" こんにちは 3358
    item <3359> & "co"'q' & <angle> "d" こんにちは 3359
    item <3360> & "co"'q' & <angle> "d" こんにちは 3360
    item <3361> & "co"'q' & <angle> "d" こんにちは 3361
    item <3362> & "co"'q' & <angle> "d" こんにちは 3362
    item <3363> & "co"'q' & <angle> "d" こんにちは 3363
    item <3364> & "co"'q' & <angle> "d" こんにちは 3364
    item <3365> & "co"'q' & <angle> "d" こんにちは 3365
    item <3366> & "co"'q' & <angle> "d" こんにちは 3366
    item <3367> & "co"'q' & <angle> "d" こんにちは 3367
    item <3368> & "co"'q' & <angle> "d" こんにちは 3368
    item <3369> & "co"'q' & <angle> "d" こんにちは 3369
    item <3370> & "co"'q' & <angle> "d" こんにちは 3370
    item <3371> & "co"'q' & <angle> "d" こんにちは 3371
    item <3372> & "co"'q' & <angle> "d" こんにちは 3372
    item <3373> & "co"'q' & <angle> "d" こんにちは 3373
    item <3374> & "co"'q' & <angle> "d" こんにちは 3374
    item <3375> & "co"'q' & <angle> "d" こんにちは 3375
    item <3376> & "co"'q' & <angle> "d" こんにちは 3376
    item <3377> & "co"'q' & <angle> "d" こんにちは 3377
    item <3378> & "co"'q' & <angle> "d" こんにちは 3378
    item <3379> & "co"'q' & <angle> "d" こんにちは 3379
    item <3380> & "co"'q' & <angle> "d" こんにちは 3380
    item <3381> & "co"'q' & <angle> "d" こんにちは 3381
    item <3382> & "co"'q' & <angle> "d" こんにちは 3382
    item <3383> & "co"'q' & <angle> "d" こんにちは 3383
    item <3384> & "co"'q' & <angle> "d" こんにちは 3384
    item <3385> & "co"'q' & <angle> "d" こんにちは 3385
    item <3386> & "co"'q' & <angle> "d" こんにちは 3386
    item <3387> & "co"'q' & <angle> "d" こんにちは 3387
    item <3388> & "co"'q' & <angle> "d" こんにちは 3388
    item <3389> & "co"'q' & <angle> "d" こんにちは 3389
    item <3390> & "co"'q' & <angle> "d" こんにちは 3390
    item <3391> & "co"'q' & <angle> "d" こんにちは 3391
    item <3392> & "co"'q' & <angle> "d" こんにちは 3392
    item <3393> & "co"'q' & <angle> "d" こんにちは 3393
    item <3394> & "co"'q' & <angle> "d" こんにちは 3394
    item <3395> & "co"'q' & <angle> "d" こんにちは 3395
    item <3396> & "co"'q' & <angle> "d" こんにちは 3396
    item <3397> & "co"'q' & <angle> "d" こんにちは 3397
    item <3398> & "co"'q' & <angle> "d" こんにちは 3398
    item <3399> & "co"'q' & <angle> "d" こんにちは 3399
    item <3400> & "co"'q' & <angle> "d" こんにちは 3400
    item <3401> & "co"'q' & <angle> "d" こんにちは 3401
    item <3402> & "co"'q' & <angle> "d" こんにちは 3402
    item <3403> & "co"'q' & <angle> "d" こんにちは 3403
    item <3404> & "co"'q' & <angle> "d" こんにちは 3404
    item <3405> & "co"'q' & <angle> "d" こんにちは 3405
    item <3406> & "co"'q' & <angle> "d" こんにちは 3406
    item <3407> & "co"'q' & <angle> "d" こんにちは 3407
    item <3408> & "co"'q' & <angle> "d" こんにちは 3408
    item <3409> & "co"'q' & <angle> "d" こんにちは 3409
    item <3410> & "co"'q' & <angle> "d" こんにちは 3410
    item <3411> & "co"'q' & <angle> "d" こんにちは 3411
    item <3412> & "co"'q' & <angle> "d" こんにちは 3412
    item <3413> & "co"'q' & <angle> "d" こんにちは 3413
    item <3414> & "co"'q' & <angle> "d" こんにちは 3414
    item <3415> & "co"'q' & <angle> "d" こんにちは 3415
    item <3416> & "co"'q' & <angle> "d" こんにちは 3416
    item <3417> & "co"'q' & <angle> "d" こんにちは 3417
    item <3418> & "co"'q' & <angle> "d" こんにちは 3418
    item <3419> & "co"'q' & <angle> "d" こんにちは 3419
    item <3420> & "co"'q' & <angle> "d" こんにちは 3420
    item <3421> & "co"'q' & <angle> "d" こんにちは 3421
    item <3422> & "co"'q' & <angle> "d" こんにちは 3422
    item <3423> & "co"'q' & <angle> "d" こんにちは 3423
    item <3424> & "co"'q' & <angle> "d" こんにちは 3424
    item <3425> & "co"'q' & <angle> "d" こんにちは 3425
    item <3426> & "co"'q' & <angle> "d" こんにちは 3426
    item <3427> & "co"'q' & <angle> "d" こんにちは 3427
    item <3428> & "co"'q' & <angle> "d" こんにちは 3428
    item <3429> & "co"'q' & <angle> "d" こんにちは 3429
    item <3430> & "co"'q' & <angle> "d" こんにちは 3430
    item <3431> & "co"'q' & <angle> "d" こんにちは 3431
    item <3432> & "co"'q' & <angle> "d" こんにちは 3432
    item <3433> & "co"'q' & <angle> "d" こんにちは 3433
    item <3434> & "co"'q' & <angle> "d" こんにちは 3434
    item <3435> & "co"'q' & <angle> "d" こんにちは 3435
    item <3436> & "co"'q' & <angle> "d" こんにちは 3436
    item <3437> & "co"'q' & <angle> "d" こんにちは 3437
    item <3438> & "co"'q' & <angle> "d" こんにちは 3438
    item <3439> & "co"'q' & <angle> "d" こんにちは 3439
    item <3440> & "co"'q' & <angle> "d" こんにちは 3440
    item <3441> & "co"'q' & <angle> "d" こんにちは 3441
    item <3442> & "co"'q' & <angle> "d" こんにちは 3442
    item <3443> & "co"'q' & <angle> "d" こんにちは 3443
    item <3444> & "co"'q' & <angle> "d" こんにちは 3444
    item <3445> & "co"'q' & <angle> "d" こんにちは 3445
    item <3446> & "co"'q' & <angle> "d" こんにちは 3446
    item <3447> & "co"'q' & <angle> "d" こんにちは 3447
    item <3448> & "co"'q' & <angle> "d" こんにちは 3448
    item <3449> & "co"'q' & <angle> "d" こんにちは 3449
    item <3450> & "co"'q' & <angle> "d" こんにちは 3450
    item <3451> & "co"'q' & <angle> "d" こんにちは 3451
    item <3452> & "co"'q' & <angle> "d" こんにちは 3452
    item <3453> & "co"'q' & <angle> "d" こんにちは 3453
    item <3454> & "co"'q' & <angle> "d" こんにちは 3454
    item <3455> & "co"'q' & <angle> "d" こんにちは 3455
    item <3456> & "co"'q' & <angle> "d" こんにちは 3456
    item <3457> & "co"'q' & <angle> "d" こんにちは 3457
    item <3458> & "co"'q' & <angle> "d" こんにちは 3458
    item <3459> & "co"'q' & <angle> "d" こんにちは 3459
    item <3460> & "co"'q' & <angle> "d" こんにちは 3460
    item <3461> & "co"'q' & <angle> "d" こんにちは 3461
    item <3462> & "co"'q' & <angle> "d" こんにちは 3462
    item <3463> & "co"'q' & <angle> "d" こんにちは 3463
    item <3464> & "co"'q' & <angle> "d" こんにちは 3464
    item <3465> & "co"'q' & <angle> "d" こんにちは 3465
    item <3466> & "co"'q' & <angle> "d" こんにちは 3466
    item <3467> & "co"'q' & <angle> "d" こんにちは 3467
    item <3468> & "co"'q' & <angle> "d" こんにちは 3468
    item <3469> & "co"'q' & <angle> "d" こんにちは 3469
    item <3470> & "co"'q' & <angle> "d" こんにちは 3470
    item <3471> & "co"'q' & <angle> "d" こんにちは 3471
    item <3472> & "co"'q' & <angle> "d" こんにちは 3472
    item <3473> & "co"'q' & <angle> "d" こんにちは 3473
    item <3474> & "co"'q' & <angle> "d" こんにちは 3474
    item <3475> & "co"'q' & <angle> "d" こんにちは 3475
    item <3476> & "co"'q' & <angle> "d" こんにちは 3476
    item <3477> & "co"'q' & <angle> "d" こんにちは 3477
    item <3478> & "co"'q' & <angle> "d" こんにちは 3478
    item <3479> & "co"'q' & <angle> "d" こんにちは 3479
    item <3480> & "co"'q' & <angle> "d" こんにちは 3480
    item <3481> & "co"'q' & <angle> "d" こんにちは 3481
    item <3482> & "co"'q' & <angle> "d" こんにちは 3482
    item <3483> & "co"'q' & <angle> "d" こんにちは 3483
    item <3484> & "co"'q' & <angle> "d" こんにちは 3484
    item <3485> & "co"'q' & <angle> "d" こんにちは 3485
    item <3486> & "co"'q' & <angle> "d" こんにちは 3486
    item <3487> & "co"'q' & <angle> "d" こんにちは 3487
    item <3488> & "co"'q' & <angle> "d" こんにちは 3488
    item <3489> & "co"'q' & <angle> "d" こんにちは 3489
    item <3490> & "co"'q' & <angle> "d" こんにちは 3490
    item <3491> & "co"'q' & <angle> "d" こんにちは 3491
    item <3492> & "co"'q' & <angle> "d" こんにちは 3492
    item <3493> & "co"'q' & <angle> "d" こんにちは 3493
    item <3494> & "co"'q' & <angle> "d" こんにちは 3494
    item <3495> & "co"'q' & <angle> "d" こんにちは 3495
    item <3496> & "co"'q' & <angle> "d" こんにちは 3496
    item <3497> & "co"'q' & <angle> "d" こんにちは 3497
    item <3498> & "co"'q' & <angle> "d" こんにちは 3498
    item <3499> & "co"'q' & <angle> "d" こんにちは 3499
    item <3500> & "co"'q' & <angle> "d" こんにちは 3500
    item <3501> & "co"'q' & <angle> "d" こんにちは 3501
    item <3502> & "co"'q' & <angle> "d" こんにちは 3502
    item <3503> & "co"'q' & <angle> "d" こんにちは 3503
    item <3504> & "co"'q' & <angle> "d" こんにちは 3504
    item <3505> & "co"'q' & <angle> "d" こんにちは 3505
    item <3506> & "co"'q' & <angle> "d" こんにちは 3506
    item <3507> & "co"'q' & <angle> "d" こんにちは 3507
    item <3508> & "co"'q' & <angle> "d" こんにちは 3508
    item <3509> & "co"'q' & <angle> "d" こんにちは 3509
    item <3510> & "co"'q' & <angle> "d" こんにちは 3510
    item <3511> & "co"'q' & <angle> "d" こんにちは 3511
    item <3512> & "co"'q' & <angle> "d" こんにちは 3512
    item <3513> & "co"'q' & <angle> "d" こんにちは 3513
    item <3514> & "co"'q' & <angle> "d" こんにちは 3514
    item <3515> & "co"'q' & <angle> "d" こんにちは 3515
    item <3516> & "co"'q' & <angle> "d" こんにちは 3516
    item <3517> & "co"'q' & <angle> "d" こんにちは 3517
    item <3518> & "co"'q' & <angle> "d" こんにちは 3518
    item <3519> & "co"'q' & <angle> "d" こんにちは 3519
    item <3520> & "co"'q' & <angle> "d" こんにちは 3520
    item <3521> & "co"'q' & <angle> "d" こんにちは 3521
    item <3522> & "co"'q' & <angle> "d" こんにちは 3522
    item <3523> & "co"'q' & <angle> "d" こんにちは 3523
    item <3524> & "co"'q' & <angle> "d" こんにちは 3524
    item <3525> & "co"'q' & <angle> "d" こんにちは 3525
    item <3526> & "co"'q' & <angle> "d" こんにちは 3526
    item <3527> & "co"'q' & <angle> "d" こんにちは 3527
    item <3528> & "co"'q' & <angle> "d" こんにちは 3528
    item <3529> & "co"'q' & <angle> "d" こんにちは 3529
    item <3530> & "co"'q' & <angle> "d" こんにちは 3530
    item <3531> & "co"'q' & <angle> "d" こんにちは 3531
    item <3532> & "co"'q' & <angle> "d" こんにちは 3532
    item <3533> & "co"'q' & <angle> "d" こんにちは 3533
    item <3534> & "co"'q' & <angle> "d" こんにちは 3534
    item <3535> & "co"'q' & <angle> "d" こんにちは 3535
    item <3536> & "co"'q' & <angle> "d" こんにちは 3536
    item <3537> & "co"'q' & <angle> "d" こんにちは 3537
    item <3538> & "co"'q' & <angle> "d" こんにちは 3538
    item <3539> & "co"'q' & <angle> "d" こんにちは 3539
    item <3540> & "co"'q' & <angle> "d" こんにちは 3540
    item <3541> & "co"'q' & <angle> "d" こんにちは 3541
    item <3542> & "co"'q' & <angle> "d" こんにちは 3542
    item <3543> & "co"'q' & <angle> "d" こんにちは 3543
    item <3544> & "co"'q' & <angle> "d" こんにちは 3544
    item <3545> & "co"'q' & <angle> "d" こんにちは 3545
    item <3546> & "co"'q' & <angle> "d" こんにちは 3546
    item <3547> & "co"'q' & <angle> "d" こんにちは 3547
    item <3548> & "co"'q' & <angle> "d" こんにちは 3548
    item <3549> & "co"'q' & <angle> "d" こんにちは 3549
    item <3550> & "co"'q' & <angle> "d" こんにちは 3550
    item <3551> & "co"'q' & <angle> "d" こんにちは 3551
    item <3552> & "co"'q' & <angle> "d" こんにちは 3552
    item <3553> & "co"'q' & <angle> "d" こんにちは 3553
    item <3554> & "co"'q' & <angle> "d" こんにちは 3554
    item <3555> & "co"'q' & <angle> "d" こんにちは 3555
    item <3556> & "co"'q' & <angle> "d" こんにちは 3556
    item <3557> & "co"'q' & <angle> "d" こんにちは 3557
    item <3558> & "co"'q' & <angle> "d" こんにちは 3558
    item <3559> & "co"'q' & <angle> "d" こんにちは 3559
    item <3560> & "co"'q' & <angle> "d" こんにちは 3560
    item <3561> & "co"'q' & <angle> "d" こんにちは 3561
    item <3562> & "co"'q' & <angle> "d" こんにちは 3562
    item <3563> & "co"'q' & <angle> "d" こんにちは 3563
    item <3564> & "co"'q' & <angle> "d" こんにちは 3564
    item <3565> & "co"'q' & <angle> "d" こんにちは 3565
    item <3566> & "co"'q' & <angle> "d" こんにちは 3566
    item <3567> & "co"'q' & <angle> "d" こんにちは 3567
    item <3568> & "co"'q' & <angle> "d" こんにちは 3568
    item <3569> & "co"'q' & <angle> "d" こんにちは 3569
    item <3570> & "co"'q' & <angle> "d" こんにちは 3570
    item <3571> & "co"'q' & <angle> "d" こんにちは 3571
    item <3572> & "co"'q' & <angle> "d" こんにちは 3572
    item <3573> & "co"'q' & <angle> "d" こんにちは 3573
    item <3574> & "co"'q' & <angle> "d" こんにちは 3574
    item <3575> & "co"'q' & <angle> "d" こんにちは 3575
    item <3576> & "co"'q' & <angle> "d" こんにちは 3576
    item <3577> & "co"'q' & <angle> "d" こんにちは 3577
    item <3578> & "co"'q' & <angle> "d" こんにちは 3578
    item <3579> & "co"'q' & <angle> "d" こんにちは 3579
    item <3580> & "co"'q' & <angle> "d" こんにちは 3580
    item <3581> & "co"'q' & <angle> "d" こんにちは 3581
    item <3582> & "co"'q' & <angle> "d" こんにちは 3582
    item <3583> & "co"'q' & <angle> "d" こんにちは 3583
    item <3584> & "co"'q' & <angle> "d" こんにちは 3584
    item <3585> & "co"'q' & <angle> "d" こんにちは 3585
    item <3586> & "co"'q' & <angle> "d" こんにちは 3586
    item <3587> & "co"'q' & <angle> "d" こんにちは 3587
    item <3588> & "co"'q' & <angle> "d" こんにちは 3588
    item <3589> & "co"'q' & <angle> "d" こんにちは 3589
    item <3590> & "co"'q' & <angle> "d" こんにちは 3590
    item <3591> & "co"'q' & <angle> "d" こんにちは 3591
    item <3592> & "co"'q' & <angle> "d" こんにちは 3592
    item <3593> & "co"'q' & <angle> "d" こんにちは 3593
    item <3594> & "co"'q' & <angle> "d" こんにちは 3594
    item <3595> & "co"'q' & <angle> "d" こんにちは 3595
    item <3596> & "co"'q' & <angle> "d" こんにちは 3596
    item <3597> & "co"'q' & <angle> "d" こんにちは 3597
    item <3598> & "co"'q' & <angle> "d" こんにちは 3598
    item <3599> & "co"'q' & <angle> "d" こんにちは 3599
    item <3600> & "co"'q' & <angle> "d" こんにちは 3600
    item <3601> & "co"'q' & <angle> "d" こんにちは 3601
    item <3602> & "co"'q' & <angle> "d" こんにちは 3602
    item <3603> & "co"'q' & <angle> "d" こんにちは 3603
    item <3604> & "co"'q' & <angle> "d" こんにちは 3604
    item <3605> & "co"'q' & <angle> "d" こんにちは 3605
    item <3606> & "co"'q' & <angle> "d" こんにちは 3606
    item <3607> & "co"'q' & <angle> "d" こんにちは 3607
    item <3608> & "co"'q' & <angle> "d" こんにちは 3608
    item <3609> & "co"'q' & <angle> "d" こんにちは 3609
    item <3610> & "co"'q' & <angle> "d" こんにちは 3610
    item <3611> & "co"'q' & <angle> "d" こんにちは 3611
    item <3612> & "co"'q' & <angle> "d" こんにちは 3612
    item <3613> & "co"'q' & <angle> "d" こんにちは 3613
    item <3614> & "co"'q' & <angle> "d" こんにちは 3614
    item <3615> & "co"'q' & <angle> "d" こんにちは 3615
    item <3616> & "co"'q' & <angle> "d" こんにちは 3616
    item <3617> & "co"'q' & <angle> "d" こんにちは 3617
    item <3618> & "co"'q' & <angle> "d" こんにちは 3618
    item <3619> & "co"'q' & <angle> "d" こんにちは 3619
    item <3620> & "co"'q' & <angle> "d" こんにちは 3620
    item <3621> & "co"'q' & <angle> "d" こんにちは 3621
    item <3622> & "co"'q' & <angle> "d" こんにちは 3622
    item <3623> & "co"'q' & <angle> "d" こんにちは 3623
    item <3624> & "co"'q' & <angle> "d" こんにちは 3624
    item <3625> & "co"'q' & <angle> "d" こんにちは 3625
    item <3626> & "co"'q' & <angle> "d" こんにちは 3626
    item <3627> & "co"'q' & <angle> "d" こんにちは 3627
    item <3628> & "co"'q' & <angle> "d" こんにちは 3628
    item <3629> & "co"'q' & <angle> "d" こんにちは 3629
    item <3630> & "co"'q' & <angle> "d" こんにちは 3630
    item <3631> & "co"'q' & <angle> "d" こんにちは 3631
    item <3632> & "co"'q' & <angle> "d" こんにちは 3632
    item <3633> & "co"'q' & <angle> "d" こんにちは 3633
    item <3634> & "co"'q' & <angle> "d" こんにちは 3634
    item <3635> & "co"'q' & <angle> "d" こんにちは 3635
    item <3636> & "co"'q' & <angle> "d" こんにちは 3636
    item <3637> & "co"'q' & <angle> "d" こんにちは 3637
    item <3638> & "co"'q' & <angle> "d" こんにちは 3638
    item <3639> & "co"'q' & <angle> "d" こんにちは 3639
    item <3640> & "co"'q' & <angle> "d" こんにちは 3640
    item <3641> & "co"'q' & <angle> "d" こんにちは 3641
    item <3642> & "co"'q' & <angle> "d" こんにちは 3642
    item <3643> & "co"'q' & <angle> "d" こんにちは 3643
    item <3644> & "co"'q' & <angle> "d" こんにちは 3644
    item <3645> & "co"'q' & <angle> "d" こんにちは 3645
    item <3646> & "co"'q' & <angle> "d" こんにちは 3646
    item <3647> & "co"'q' & <angle> "d" こんにちは 3647
    item <3648> & "co"'q' & <angle> "d" こんにちは 3648
    item <3649> & "co"'q' & <angle> "d" こんにちは 3649
    item <3650> & "co"'q' & <angle> "d" こんにちは 3650
    item <3651> & "co"'q' & <angle> "d" こんにちは 3651
    item <3652> & "co"'q' & <angle> "d" こんにちは 3652
    item <3653> & "co"'q' & <angle> "d" こんにちは 3653
    item <3654> & "co"'q' & <angle> "d" こんにちは 3654
    item <3655> & "co"'q' & <angle> "d" こんにちは 3655
    item <3656> & "co"'q' & <angle> "d" こんにちは 3656
    item <3657> & "co"'q' & <angle> "d" こんにちは 3657
    item <3658> & "co"'q' & <angle> "d" こんにちは 3658
    item <3659> & "co"'q' & <angle> "d" こんにちは 3659
    item <3660> & "co"'q' & <angle> "d" こんにちは 3660
    item <3661> & "co"'q' & <angle> "d" こんにちは 3661
    item <3662> & "co"'q' & <angle> "d" こんにちは 3662
    item <3663> & "co"'q' & <angle> "d" こんにちは 3663
    item <3664> & "co"'q' & <angle> "d" こんにちは 3664
    item <3665> & "co"'q' & <angle> "d" こんにちは 3665
    item <3666> & "co"'q' & <angle> "d" こんにちは 3666
    item <3667> & "co"'q' & <angle> "d" こんにちは 3667
    item <3668> & "co"'q' & <angle> "d" こんにちは 3668
    item <3669> & "co"'q' & <angle> "d" こんにちは 3669
    item <3670> & "co"'q' & <angle> "d" こんにちは 3670
    item <3671> & "co"'q' & <angle> "d" こんにちは 3671
    item <3672> & "co"'q' & <angle> "d" こんにちは 3672
    item <3673> & "co"'q' & <angle> "d" こんにちは 3673
    item <3674> & "co"'q' & <angle> "d" こんにちは 3674
    item <3675> & "co"'q' & <angle> "d" こんにちは 3675
    item <3676> & "co"'q' & <angle> "d" こんにちは 3676
    item <3677> & "co"'q' & <angle> "d" こんにちは 3677
    item <3678> & "co"'q' & <angle> "d" こんにちは 3678
    item <3679> & "co"'q' & <angle> "d" こんにちは 3679
    item <3680> & "co"'q' & <angle> "d" こんにちは 3680
    item <3681> & "co"'q' & <angle> "d" こんにちは 3681
    item <3682> & "co"'q' & <angle> "d" こんにちは 3682
    item <3683> & "co"'q' & <angle> "d" こんにちは 3683
    item <3684> & "co"'q' & <angle> "d" こんにちは 3684
    item <3685> & "co"'q' & <angle> "d" こんにちは 3685
    item <3686> & "co"'q' & <angle> "d" こんにちは 3686
    item <3687> & "co"'q' & <angle> "d" こんにちは 3687
    item <3688> & "co"'q' & <angle> "d" こんにちは 3688
    item <3689> & "co"'q' & <angle> "d" こんにちは 3689
    item <3690> & "co"'q' & <angle> "d" こんにちは 3690
    item <3691> & "co"'q' & <angle> "d" こんにちは 3691
    item <3692> & "co"'q' & <angle> "d" こんにちは 3692
    item <3693> & "co"'q' & <angle> "d" こんにちは 3693
    item <3694> & "co"'q' & <angle> "d" こんにちは 3694
    item <3695> & "co"'q' & <angle> "d" こんにちは 3695
    item <3696> & "co"'q' & <angle> "d" こんにちは 3696
    item <3697> & "co"'q' & <angle> "d" こんにちは 3697
    item <3698> & "co"'q' & <angle> "d" こんにちは 3698
    item <3699> & "co"'q' & <angle> "d" こんにちは 3699
    item <3700> & "co"'q' & <angle> "d" こんにちは 3700
    item <3701> & "co"'q' & <angle> "d" こんにちは 3701
    item <3702> & "co"'q' & <angle> "d" こんにちは 3702
    item <3703> & "co"'q' & <angle> "d" こんにちは 3703
    item <3704> & "co"'q' & <angle> "d" こんにちは 3704
    item <3705> & "co"'q' & <angle> "d" こんにちは 3705
    item <3706> & "co"'q' & <angle> "d" こんにちは 3706
    item <3707> & "co"'q' & <angle> "d" こんにちは 3707
    item <3708> & "co"'q' & <angle> "d" こんにちは 3708
    item <3709> & "co"'q' & <angle> "d" こんにちは 3709
    item <3710> & "co"'q' & <angle> "d" こんにちは 3710
    item <3711> & "co"'q' & <angle> "d" こんにちは 3711
    item <3712> & "co"'q' & <angle> "d" こんにちは 3712
    item <3713> & "co"'q' & <angle> "d" こんにちは 3713
    item <3714> & "co"'q' & <angle> "d" こんにちは 3714
    item <3715> & "co"'q' & <angle> "d" こんにちは 3715
    item <3716> & "co"'q' & <angle> "d" こんにちは 3716
    item <3717> & "co"'q' & <angle> "d" こんにちは 3717
    item <3718> & "co"'q' & <angle> "d" こんにちは 3718
    item <3719> & "co"'q' & <angle> "d" こんにちは 3719
    item <3720> & "co"'q' & <angle> "d" こんにちは 3720
    item <3721> & "co"'q' & <angle> "d" こんにちは 3721
    item <3722> & "co"'q' & <angle> "d" こんにちは 3722
    item <3723> & "co"'q' & <angle> "d" こんにちは 3723
    item <3724> & "co"'q' & <angle> "d" こんにちは 3724
    item <3725> & "co"'q' & <angle> "d" こんにちは 3725
    item <3726> & "co"'q' & <angle> "d" こんにちは 3726
    item <3727> & "co"'q' & <angle> "d" こんにちは 3727
    item <3728> & "co"'q' & <angle> "d" こんにちは 3728
    item <3729> & "co"'q' & <angle> "d" こんにちは 3729
    item <3730> & "co"'q' & <angle> "d" こんにちは 3730
    item <3731> & "co"'q' & <angle> "d" こんにちは 3731
    item <3732> & "co"'q' & <angle> "d" こんにちは 3732
    item <3733> & "co"'q' & <angle> "d" こんにちは 3733
    item <3734> & "co"'q' & <angle> "d" こんにちは 3734
    item <3735> & "co"'q' & <angle> "d" こんにちは 3735
    item <3736> & "co"'q' & <angle> "d" こんにちは 3736
    item <3737> & "co"'q' & <angle> "d" こんにちは 3737
    item <3738> & "co"'q' & <angle> "d" こんにちは 3738
    item <3739> & "co"'q' & <angle> "d" こんにちは 3739
    item <3740> & "co"'q' & <angle> "d" こんにちは 3740
    item <3741> & "co"'q' & <angle> "d" こんにちは 3741
    item <3742> & "co"'q' & <angle> "d" こんにちは 3742
    item <3743> & "co"'q' & <angle> "d" こんにちは 3743
    item <3744> & "co"'q' & <angle> "d" こんにちは 3744
    item <3745> & "co"'q' & <angle> "d" こんにちは 3745
    item <3746> & "co"'q' & <angle> "d" こんにちは 3746
    item <3747> & "co"'q' & <angle> "d" こんにちは 3747
    item <3748> & "co"'q' & <angle> "d" こんにちは 3748
    item <3749> & "co"'q' & <angle> "d" こんにちは 3749
    item <3750> & "co"'q' & <angle> "d" こんにちは 3750
    item <3751> & "co"'q' & <angle> "d" こんにちは 3751
    item <3752> & "co"'q' & <angle> "d" こんにちは 3752
    item <3753> & "co"'q' & <angle> "d" こんにちは 3753
    item <3754> & "co"'q' & <angle> "d" こんにちは 3754
    item <3755> & "co"'q' & <angle> "d" こんにちは 3755
    item <3756> & "co"'q' & <angle> "d" こんにちは 3756
    item <3757> & "co"'q' & <angle> "d" こんにちは 3757
    item <3758> & "co"'q' & <angle> "d" こんにちは 3758
    item <3759> & "co"'q' & <angle> "d" こんにちは 3759
    item <3760> & "co"'q' & <angle> "d" こんにちは 3760
    item <3761> & "co"'q' & <angle> "d" こんにちは 3761
    item <3762> & "co"'q' & <angle> "d" こんにちは 3762
    item <3763> & "co"'q' & <angle> "d" こんにちは 3763
    item <3764> & "co"'q' & <angle> "d" こんにちは 3764
    item <3765> & "co"'q' & <angle> "d" こんにちは 3765
    item <3766> & "co"'q' & <angle> "d" こんにちは 3766
    item <3767> & "co"'q' & <angle> "d" こんにちは 3767
    item <3768> & "co"'q' & <angle> "d" こんにちは 3768
    item <3769> & "co"'q' & <angle> "d" こんにちは 3769
    item <3770> & "co"'q' & <angle> "d" こんにちは 3770
    item <3771> & "co"'q' & <angle> "d" こんにちは 3771
    item <3772> & "co"'q' & <angle> "d" こんにちは 3772
    item <3773> & "co"'q' & <angle> "d" こんにちは 3773
    item <3774> & "co"'q' & <angle> "d" こんにちは 3774
    item <3775> & "co"'q' & <angle> "d" こんにちは 3775
    item <3776> & "co"'q' & <angle> "d" こんにちは 3776
    item <3777> & "co"'q' & <angle> "d" こんにちは 3777
    item <3778> & "co"'q' & <angle> "d" こんにちは 3778
    item <3779> & "co"'q' & <angle> "d" こんにちは 3779
    item <3780> & "co"'q' & <angle> "d" こんにちは 3780
    item <3781> & "co"'q' & <angle> "d" こんにちは 3781
    item <3782> & "co"'q' & <angle> "d" こんにちは 3782
    item <3783> & "co"'q' & <angle> "d" こんにちは 3783
    item <3784> & "co"'q' & <angle> "d" こんにちは 3784
    item <3785> & "co"'q' & <angle> "d" こんにちは 3785
    item <3786> & "co"'q' & <angle> "d" こんにちは 3786
    item <3787> & "co"'q' & <angle> "d" こんにちは 3787
    item <3788> & "co"'q' & <angle> "d" こんにちは 3788
    item <3789> & "co"'q' & <angle> "d" こんにちは 3789
    item <3790> & "co"'q' & <angle> "d" こんにちは 3790
    item <3791> & "co"'q' & <angle> "d" こんにちは 3791
    item <3792> & "co"'q' & <angle> "d" こんにちは 3792
    item <3793> & "co"'q' & <angle> "d" こんにちは 3793
    item <3794> & "co"'q' & <angle> "d" こんにちは 3794
    item <3795> & "co"'q' & <angle> "d" こんにちは 3795
    item <3796> & "co"'q' & <angle> "d" こんにちは 3796
    item <3797> & "co"'q' & <angle> "d" こんにちは 3797
    item <3798> & "co"'q' & <angle> "d" こんにちは 3798
    item <3799> & "co"'q' & <angle> "d" こんにちは 3799
    item <3800> & "co"'q' & <angle> "d" こんにちは 3800
    item <3801> & "co"'q' & <angle> "d" こんにちは 3801
    item <3802> & "co"'q' & <angle> "d" こんにちは 3802
    item <3803> & "co"'q' & <angle> "d" こんにちは 3803
    item <3804> & "co"'q' & <angle> "d" こんにちは 3804
    item <3805> & "co"'q' & <angle> "d" こんにちは 3805
    item <3806> & "co"'q' & <angle> "d" こんにちは 3806
    item <3807> & "co"'q' & <angle> "d" こんにちは 3807
    item <3808> & "co"'q' & <angle> "d" こんにちは 3808
    item <3809> & "co"'q' & <angle> "d" こんにちは 3809
    item <3810> & "co"'q' & <angle> "d" こんにちは 3810
    item <3811> & "co"'q' & <angle> "d" こんにちは 3811
    item <3812> & "co"'q' & <angle> "d" こんにちは 3812
    item <3813> & "co"'q' & <angle> "d" こんにちは 3813
    item <3814> & "co"'q' & <angle> "d" こんにちは 3814
    item <3815> & "co"'q' & <angle> "d" こんにちは 3815
    item <3816> & "co"'q' & <angle> "d" こんにちは 3816
    item <3817> & "co"'q' & <angle> "d" こんにちは 3817
    item <3818> & "co"'q' & <angle> "d" こんにちは 3818
    item <3819> & "co"'q' & <angle> "d" こんにちは 3819
    item <3820> & "co"'q' & <angle> "d" こんにちは 3820
    item <3821> & "co"'q' & <angle> "d" こんにちは 3821
    item <3822> & "co"'q' & <angle> "d" こんにちは 3822
    item <3823> & "co"'q' & <angle> "d" こんにちは 3823
    item <3824> & "co"'q' & <angle> "d" こんにちは 3824
    item <3825> & "co"'q' & <angle> "d" こんにちは 3825
    item <3826> & "co"'q' & <angle> "d" こんにちは 3826
    item <3827> & "co"'q' & <angle> "d" こんにちは 3827
    item <3828> & "co"'q' & <angle> "d" こんにちは 3828
    item <3829> & "co"'q' & <angle> "d" こんにちは 3829
    item <3830> & "co"'q' & <angle> "d" こんにちは 3830
    item <3831> & "co"'q' & <angle> "d" こんにちは 3831
    item <3832> & "co"'q' & <angle> "d" こんにちは 3832
    item <3833> & "co"'q' & <angle> "d" こんにちは 3833
    item <3834> & "co"'q' & <angle> "d" こんにちは 3834
    item <3835> & "co"'q' & <angle> "d" こんにちは 3835
    item <3836> & "co"'q' & <angle> "d" こんにちは 3836
    item <3837> & "co"'q' & <angle> "d" こんにちは 3837
    item <3838> & "co"'q' & <angle> "d" こんにちは 3838
    item <3839> & "co"'q' & <angle> "d" こんにちは 3839
    item <3840> & "co"'q' & <angle> "d" こんにちは 3840
    item <3841> & "co"'q' & <angle> "d" こんにちは 3841
    item <3842> & "co"'q' & <angle> "d" こんにちは 3842
    item <3843> & "co"'q' & <angle> "d" こんにちは 3843
    item <3844> & "co"'q' & <angle> "d" こんにちは 3844
    item <3845> & "co"'q' & <angle> "d" こんにちは 3845
    item <3846> & "co"'q' & <angle> "d" こんにちは 3846
    item <3847> & "co"'q' & <angle> "d" こんにちは 3847
    item <3848> & "co"'q' & <angle> "d" こんにちは 3848
    item <3849> & "co"'q' & <angle> "d" こんにちは 3849
    item <3850> & "co"'q' & <angle> "d" こんにちは 3850
    item <3851> & "co"'q' & <angle> "d" こんにちは 3851
    item <3852> & "co"'q' & <angle> "d" こんにちは 3852
    item <3853> & "co"'q' & <angle> "d" こんにちは 3853
    item <3854> & "co"'q' & <angle> "d" こんにちは 3854
    item <3855> & "co"'q' & <angle> "d" こんにちは 3855
    item <3856> & "co"'q' & <angle> "d" こんにちは 3856
    item <3857> & "co"'q' & <angle> "d" こんにちは 3857
    item <3858> & "co"'q' & <angle> "d" こんにちは 3858
    item <3859> & "co"'q' & <angle> "d" こんにちは 3859
    item <3860> & "co"'q' & <angle> "d" こんにちは 3860
    item <3861> & "co"'q' & <angle> "d" こんにちは 3861
    item <3862> & "co"'q' & <angle> "d" こんにちは 3862
    item <3863> & "co"'q' & <angle> "d" こんにちは 3863
    item <3864> & "co"'q' & <angle> "d" こんにちは 3864
    item <3865> & "co"'q' & <angle> "d" こんにちは 3865
    item <3866> & "co"'q' & <angle> "d" こんにちは 3866
    item <3867> & "co"'q' & <angle> "d" こんにちは 3867
    item <3868> & "co"'q' & <angle> "d" こんにちは 3868
    item <3869> & "co"'q' & <angle> "d" こんにちは 3869
    item <3870> & "co"'q' & <angle> "d" こんにちは 3870
    item <3871> & "co"'q' & <angle> "d" こんにちは 3871
    item <3872> & "co"'q' & <angle> "d" こんにちは 3872
    item <3873> & "co"'q' & <angle> "d" こんにちは 3873
    item <3874> & "co"'q' & <angle> "d" こんにちは 3874
    item <3875> & "co"'q' & <angle> "d" こんにちは 3875
    item <3876> & "co"'q' & <angle> "d" こんにちは 3876
    item <3877> & "co"'q' & <angle> "d" こんにちは 3877
    item <3878> & "co"'q' & <angle> "d" こんにちは 3878
    item <3879> & "co"'q' & <angle> "d" こんにちは 3879
    item <3880> & "co"'q' & <angle> "d" こんにちは 3880
    item <3881> & "co"'q' & <angle> "d" こんにちは 3881
    item <3882> & "co"'q' & <angle> "d" こんにちは 3882
    item <3883> & "co"'q' & <angle> "d" こんにちは 3883
    item <3884> & "co"'q' & <angle> "d" こんにちは 3884
    item <3885> & "co"'q' & <angle> "d" こんにちは 3885
    item <3886> & "co"'q' & <angle> "d" こんにちは 3886
    item <3887> & "co"'q' & <angle> "d" こんにちは 3887
    item <3888> & "co"'q' & <angle> "d" こんにちは 3888
    item <3889> & "co"'q' & <angle> "d" こんにちは 3889
    item <3890> & "co"'q' & <angle> "d" こんにちは 3890
    item <3891> & "co"'q' & <angle> "d" こんにちは 3891
    item <3892> & "co"'q' & <angle> "d" こんにちは 3892
    item <3893> & "co"'q' & <angle> "d" こんにちは 3893
    item <3894> & "co"'q' & <angle> "d" こんにちは 3894
    item <3895> & "co"'q' & <angle> "d" こんにちは 3895
    item <3896> & "co"'q' & <angle> "d" こんにちは 3896
    item <3897> & "co"'q' & <angle> "d" こんにちは 3897
    item <3898> & "co"'q' & <angle> "d" こんにちは 3898
    item <3899> & "co"'q' & <angle> "d" こんにちは 3899
    item <3900> & "co"'q' & <angle> "d" こんにちは 3900
    item <3901> & "co"'q' & <angle> "d" こんにちは 3901
    item <3902> & "co"'q' & <angle> "d" こんにちは 3902
    item <3903> & "co"'q' & <angle> "d" こんにちは 3903
    item <3904> & "co"'q' & <angle> "d" こんにちは 3904
    item <3905> & "co"'q' & <angle> "d" こんにちは 3905
    item <3906> & "co"'q' & <angle> "d" こんにちは 3906
    item <3907> & "co"'q' & <angle> "d" こんにちは 3907
    item <3908> & "co"'q' & <angle> "d" こんにちは 3908
    item <3909> & "co"'q' & <angle> "d" こんにちは 3909
    item <3910> & "co"'q' & <angle> "d" こんにちは 3910
    item <3911> & "co"'q' & <angle> "d" こんにちは 3911
    item <3912> & "co"'q' & <angle> "d" こんにちは 3912
    item <3913> & "co"'q' & <angle> "d" こんにちは 3913
    item <3914> & "co"'q' & <angle> "d" こんにちは 3914
    item <3915> & "co"'q' & <angle> "d" こんにちは 3915
    item <3916> & "co"'q' & <angle> "d" こんにちは 3916
    item <3917> & "co"'q' & <angle> "d" こんにちは 3917
    item <3918> & "co"'q' & <angle> "d" こんにちは 3918
    item <3919> & "co"'q' & <angle> "d" こんにちは 3919
    item <3920> & "co"'q' & <angle> "d" こんにちは 3920
    item <3921> & "co"'q' & <angle> "d" こんにちは 3921
    item <3922> & "co"'q' & <angle> "d" こんにちは 3922
    item <3923> & "co"'q' & <angle> "d" こんにちは 3923
    item <3924> & "co"'q' & <angle> "d" こんにちは 3924
    item <3925> & "co"'q' & <angle> "d" こんにちは 3925
    item <3926> & "co"'q' & <angle> "d" こんにちは 3926
    item <3927> & "co"'q' & <angle> "d" こんにちは 3927
    item <3928> & "co"'q' & <angle> "d" こんにちは 3928
    item <3929> & "co"'q' & <angle> "d" こんにちは 3929
    item <3930> & "co"'q' & <angle> "d" こんにちは 3930
    item <3931> & "co"'q' & <angle> "d" こんにちは 3931
    item <3932> & "co"'q' & <angle> "d" こんにちは 3932
    item <3933> & "co"'q' & <angle> "d" こんにちは 3933
    item <3934> & "co"'q' & <angle> "d" こんにちは 3934
    item <3935> & "co"'q' & <angle> "d" こんにちは 3935
    item <3936> & "co"'q' & <angle> "d" こんにちは 3936
    item <3937> & "co"'q' & <angle> "d" こんにちは 3937
    item <3938> & "co"'q' & <angle> "d" こんにちは 3938
    item <3939> & "co"'q' & <angle> "d" こんにちは 3939
    item <3940> & "co"'q' & <angle> "d" こんにちは 3940
    item <3941> & "co"'q' & <angle> "d" こんにちは 3941
    item <3942> & "co"'q' & <angle> "d" こんにちは 3942
    item <3943> & "co"'q' & <angle> "d" こんにちは 3943
    item <3944> & "co"'q' & <angle> "d" こんにちは 3944
    item <3945> & "co"'q' & <angle> "d" こんにちは 3945
    item <3946> & "co"'q' & <angle> "d" こんにちは 3946
    item <3947> & "co"'q' & <angle> "d" こんにちは 3947
    item <3948> & "co"'q' & <angle> "d" こんにちは 3948
    item <3949> & "co"'q' & <angle> "d" こんにちは 3949
    item <3950> & "co"'q' & <angle> "d" こんにちは 3950
    item <3951> & "co"'q' & <angle> "d" こんにちは 3951
    item <3952> & "co"'q' & <angle> "d" こんにちは 3952
    item <3953> & "co"'q' & <angle> "d" こんにちは 3953
    item <3954> & "co"'q' & <angle> "d" こんにちは 3954
    item <3955> & "co"'q' & <angle> "d" こんにちは 3955
    item <3956> & "co"'q' & <angle> "d" こんにちは 3956
    item <3957> & "co"'q' & <angle> "d" こんにちは 3957
    item <3958> & "co"'q' & <angle> "d" こんにちは 3958
    item <3959> & "co"'q' & <angle> "d" こんにちは 3959
    item <3960> & "co"'q' & <angle> "d" こんにちは 3960
    item <3961> & "co"'q' & <angle> "d" こんにちは 3961
    item <3962> & "co"'q' & <angle> "d" こんにちは 3962
    item <3963> & "co"'q' & <angle> "d" こんにちは 3963
    item <3964> & "co"'q' & <angle> "d" こんにちは 3964
    item <3965> & "co"'q' & <angle> "d" こんにちは 3965
    item <3966> & "co"'q' & <angle> "d" こんにちは 3966
    item <3967> & "co"'q' & <angle> "d" こんにちは 3967
    item <3968> & "co"'q' & <angle> "d" こんにちは 3968
    item <3969> & "co"'q' & <angle> "d" こんにちは 3969
    item <3970> & "co"'q' & <angle> "d" こんにちは 3970
    item <3971> & "co"'q' & <angle> "d" こんにちは 3971
    item <3972> & "co"'q' & <angle> "d" こんにちは 3972
    item <3973> & "co"'q' & <angle> "d" こんにちは 3973
    item <3974> & "co"'q' & <angle> "d" こんにちは 3974
    item <3975> & "co"'q' & <angle> "d" こんにちは 3975
    item <3976> & "co"'q' & <angle> "d" こんにちは 3976
    item <3977> & "co"'q' & <angle> "d" こんにちは 3977
    item <3978> & "co"'q' & <angle> "d" こんにちは 3978
    item <3979> & "co"'q' & <angle> "d" こんにちは 3979
    item <3980> & "co"'q' & <angle> "d" こんにちは 3980
    item <3981> & "co"'q' & <angle> "d" こんにちは 3981
    item <3982> & "co"'q' & <angle> "d" こんにちは 3982
    item <3983> & "co"'q' & <angle> "d" こんにちは 3983
    item <3984> & "co"'q' & <angle> "d" こんにちは 3984
    item <3985> & "co"'q' & <angle> "d" こんにちは 3985
    item <3986> & "co"'q' & <angle> "d" こんにちは 3986
    item <3987> & "co"'q' & <angle> "d" こんにちは 3987
    item <3988> & "co"'q' & <angle> "d" こんにちは 3988
    item <3989> & "co"'q' & <angle> "d" こんにちは 3989
    item <3990> & "co"'q' & <angle> "d" こんにちは 3990
    item <3991> & "co"'q' & <angle> "d" こんにちは 3991
    item <3992> & "co"'q' & <angle> "d" こんにちは 3992
    item <3993> & "co"'q' & <angle> "d" こんにちは 3993
    item <3994> & "co"'q' & <angle> "d" こんにちは 3994
    item <3995> & "co"'q' & <angle> "d" こんにちは 3995
    item <3996> & "co"'q' & <angle> "d" こんにちは 3996
    item <3997> & "co"'q' & <angle> "d" こんにちは 3997
    item <3998> & "co"'q' & <angle> "d" こんにちは 3998
    item <3999> & "co"'q' & <angle> "d" こんにちは 3999
    item <4000> & "co"'q' & <angle> "d" こんにちは 4000
    item <4001> & "co"'q' & <angle> "d" こんにちは 4001
    item <4002> & "co"'q' & <angle> "d" こんにちは 4002
    item <4003> & "co"'q' & <angle> "d" こんにちは 4003
    item <4004> & "co"'q' & <angle> "d" こんにちは 4004
    item <4005> & "co"'q' & <angle> "d" こんにちは 4005
    item <4006> & "co"'q' & <angle> "d" こんにちは 4006
    item <4007> & "co"'q' & <angle> "d" こんにちは 4007
    item <4008> & "co"'q' & <angle> "d" こんにちは 4008
    item <4009> & "co"'q' & <angle> "d" こんにちは 4009
    item <4010> & "co"'q' & <angle> "d" こんにちは 4010
    item <4011> & "co"'q' & <angle> "d" こんにちは 4011
    item <4012> & "co"'q' & <angle> "d" こんにちは 4012
    item <4013> & "co"'q' & <angle> "d" こんにちは 4013
    item <4014> & "co"'q' & <angle> "d" こんにちは 4014
    item <4015> & "co"'q' & <angle> "d" こんにちは 4015
    item <4016> & "co"'q' & <angle> "d" こんにちは 4016
    item <4017> & "co"'q' & <angle> "d" こんにちは 4017
    item <4018> & "co"'q' & <angle> "d" こんにちは 4018
    item <4019> & "co"'q' & <angle> "d" こんにちは 4019
    item <4020> & "co"'q' & <angle> "d" こんにちは 4020
    item <4021> & "co"'q' & <angle> "d" こんにちは 4021
    item <4022> & "co"'q' & <angle> "d" こんにちは 4022
    item <4023> & "co"'q' & <angle> "d" こんにちは 4023
    item <4024> & "co"'q' & <angle> "d" こんにちは 4024
    item <4025> & "co"'q' & <angle> "d" こんにちは 4025
    item <4026> & "co"'q' & <angle> "d" こんにちは 4026
    item <4027> & "co"'q' & <angle> "d" こんにちは 4027
    item <4028> & "co"'q' & <angle> "d" こんにちは 4028
    item <4029> & "co"'q' & <angle> "d" こんにちは 4029
    item <4030> & "co"'q' & <angle> "d" こんにちは 4030
    item <4031> & "co"'q' & <angle> "d" こんにちは 4031
    item <4032> & "co"'q' & <angle> "d" こんにちは 4032
    item <4033> & "co"'q' & <angle> "d" こんにちは 4033
    item <4034> & "co"'q' & <angle> "d" こんにちは 4034
    item <4035> & "co"'q' & <angle> "d" こんにちは 4035
    item <4036> & "co"'q' & <angle> "d" こんにちは 4036
    item <4037> & "co"'q' & <angle> "d" こんにちは 4037
    item <4038> & "co"'q' & <angle> "d" こんにちは 4038
    item <4039> & "co"'q' & <angle> "d" こんにちは 4039
    item <4040> & "co"'q' & <angle> "d" こんにちは 4040
    item <4041> & "co"'q' & <angle> "d" こんにちは 4041
    item <4042> & "co"'q' & <angle> "d" こんにちは 4042
    item <4043> & "co"'q' & <angle> "d" こんにちは 4043
    item <4044> & "co"'q' & <angle> "d" こんにちは 4044
    item <4045> & "co"'q' & <angle> "d" こんにちは 4045
    item <4046> & "co"'q' & <angle> "d" こんにちは 4046
    item <4047> & "co"'q' & <angle> "d" こんにちは 4047
    item <4048> & "co"'q' & <angle> "d" こんにちは 4048
    item <4049> & "co"'q' & <angle> "d" こんにちは 4049
    item <4050> & "co"'q' & <angle> "d" こんにちは 4050
    item <4051> & "co"'q' & <angle> "d" こんにちは 4051
    item <4052> & "co"'q' & <angle> "d" こんにちは 4052
    item <4053> & "co"'q' & <angle> "d" こんにちは 4053
    item <4054> & "co"'q' & <angle> "d" こんにちは 4054
    item <4055> & "co"'q' & <angle> "d" こんにちは 4055
    item <4056> & "co"'q' & <angle> "d" こんにちは 4056
    item <4057> & "co"'q' & <angle> "d" こんにちは 4057
    item <4058> & "co"'q' & <angle> "d" こんにちは 4058
    item <4059> & "co"'q' & <angle> "d" こんにちは 4059
    item <4060> & "co"'q' & <angle> "d" こんにちは 4060
    item <4061> & "co"'q' & <angle> "d" こんにちは 4061
    item <4062> & "co"'q' & <angle> "d" こんにちは 4062
    item <4063> & "co"'q' & <angle> "d" こんにちは 4063
    item <4064> & "co"'q' & <angle> "d" こんにちは 4064
    item <4065> & "co"'q' & <angle> "d" こんにちは 4065
    item <4066> & "co"'q' & <angle> "d" こんにちは 4066
    item <4067> & "co"'q' & <angle> "d" こんにちは 4067
    item <4068> & "co"'q' & <angle> "d" こんにちは 4068
    item <4069> & "co"'q' & <angle> "d" こんにちは 4069
    item <4070> & "co"'q' & <angle> "d" こんにちは 4070
    item <4071> & "co"'q' & <angle> "d" こんにちは 4071
    item <4072> & "co"'q' & <angle> "d" こんにちは 4072
    item <4073> & "co"'q' & <angle> "d" こんにちは 4073
    item <4074> & "co"'q' & <angle> "d" こんにちは 4074
    item <4075> & "co"'q' & <angle> "d" こんにちは 4075
    item <4076> & "co"'q' & <angle> "d" こんにちは 4076
    item <4077> & "co"'q' & <angle> "d" こんにちは 4077
    item <4078> & "co"'q' & <angle> "d" こんにちは 4078
    item <4079> & "co"'q' & <angle> "d" こんにちは 4079
    item <4080> & "co"'q' & <angle> "d" こんにちは 4080
    item <4081> & "co"'q' & <angle> "d" こんにちは 4081
    item <4082> & "co"'q' & <angle> "d" こんにちは 4082
    item <4083> & "co"'q' & <angle> "d" こんにちは 4083
    item <4084> & "co"'q' & <angle> "d" こんにちは 4084
    item <4085> & "co"'q' & <angle> "d" こんにちは 4085
    item <4086> & "co"'q' & <angle> "d" こんにちは 4086
    item <4087> & "co"'q' & <angle> "d" こんにちは 4087
    item <4088> & "co"'q' & <angle> "d" こんにちは 4088
    item <4089> & "co"'q' & <angle> "d" こんにちは 4089
    item <4090> & "co"'q' & <angle> "d" こんにちは 4090
    item <4091> & "co"'q' & <angle> "d" こんにちは 4091
    item <4092> & "co"'q' & <angle> "d" こんにちは 4092
    item <4093> & "co"'q' & <angle> "d" こんにちは 4093
    item <4094> & "co"'q' & <angle> "d" こんにちは 4094
    item <4095> & "co"'q' & <angle> "d" こんにちは 4095
    item <4096> & "co"'q' & <angle> "d" こんにちは 4096
    item <4097> & "co"'q' & <angle> "d" こんにちは 4097
    item <4098> & "co"'q' & <angle> "d" こんにちは 4098
    item <4099> & "co"'q' & <angle> "d" こんにちは 4099
    item <4100> & "co"'q' & <angle> "d" こんにちは 4100
    item <4101> & "co"'q' & <angle> "d" こんにちは 4101
    item <4102> & "co"'q' & <angle> "d" こんにちは 4102
    item <4103> & "co"'q' & <angle> "d" こんにちは 4103
    item <4104> & "co"'q' & <angle> "d" こんにちは 4104
    item <4105> & "co"'q' & <angle> "d" こんにちは 4105
    item <4106> & "co"'q' & <angle> "d" こんにちは 4106
    item <4107> & "co"'q' & <angle> "d" こんにちは 4107
    item <4108> & "co"'q' & <angle> "d" こんにちは 4108
    item <4109> & "co"'q' & <angle> "d" こんにちは 4109
    item <4110> & "co"'q' & <angle> "d" こんにちは 4110
    item <4111> & "co"'q' & <angle> "d" こんにちは 4111
    item <4112> & "co"'q' & <angle> "d" こんにちは 4112
    item <4113> & "co"'q' & <angle> "d" こんにちは 4113
    item <4114> & "co"'q' & <angle> "d" こんにちは 4114
    item <4115> & "co"'q' & <angle> "d" こんにちは 4115
    item <4116> & "co"'q' & <angle> "d" こんにちは 4116
    item <4117> & "co"'q' & <angle> "d" こんにちは 4117
    item <4118> & "co"'q' & <angle> "d" こんにちは 4118
    item <4119> & "co"'q' & <angle> "d" こんにちは 4119
    item <4120> & "co"'q' & <angle> "d" こんにちは 4120
    item <4121> & "co"'q' & <angle> "d" こんにちは 4121
    item <4122> & "co"'q' & <angle> "d" こんにちは 4122
    item <4123> & "co"'q' & <angle> "d" こんにちは 4123
    item <4124> & "co"'q' & <angle> "d" こんにちは 4124
    item <4125> & "co"'q' & <angle> "d" こんにちは 4125
    item <4126> & "co"'q' & <angle> "d" こんにちは 4126
    item <4127> & "co"'q' & <angle> "d" こんにちは 4127
    item <4128> & "co"'q' & <angle> "d" こんにちは 4128
    item <4129> & "co"'q' & <angle> "d" こんにちは 4129
    item <4130> & "co"'q' & <angle> "d" こんにちは 4130
    item <4131> & "co"'q' & <angle> "d" こんにちは 4131
    item <4132> & "co"'q' & <angle> "d" こんにちは 4132
    item <4133> & "co"'q' & <angle> "d" こんにちは 4133
    item <4134> & "co"'q' & <angle> "d" こんにちは 4134
    item <4135> & "co"'q' & <angle> "d" こんにちは 4135
    item <4136> & "co"'q' & <angle> "d" こんにちは 4136
    item <4137> & "co"'q' & <angle> "d" こんにちは 4137
    item <4138> & "co"'q' & <angle> "d" こんにちは 4138
    item <4139> & "co"'q' & <angle> "d" こんにちは 4139
    item <4140> & "co"'q' & <angle> "d" こんにちは 4140
    item <4141> & "co"'q' & <angle> "d" こんにちは 4141
    item <4142> & "co"'q' & <angle> "d" こんにちは 4142
    item <4143> & "co"'q' & <angle> "d" こんにちは 4143
    item <4144> & "co"'q' & <angle> "d" こんにちは 4144
    item <4145> & "co"'q' & <angle> "d" こんにちは 4145
    item <4146> & "co"'q' & <angle> "d" こんにちは 4146
    item <4147> & "co"'q' & <angle> "d" こんにちは 4147
    item <4148> & "co"'q' & <angle> "d" こんにちは 4148
    item <4149> & "co"'q' & <angle> "d" こんにちは 4149
    item <4150> & "co"'q' & <angle> "d" こんにちは 4150
    item <4151> & "co"'q' & <angle> "d" こんにちは 4151
    item <4152> & "co"'q' & <angle> "d" こんにちは 4152
    item <4153> & "co"'q' & <angle> "d" こんにちは 4153
    item <4154> & "co"'q' & <angle> "d" こんにちは 4154
    item <4155> & "co"'q' & <angle> "d" こんにちは 4155
    item <4156> & "co"'q' & <angle> "d" こんにちは 4156
    item <4157> & "co"'q' & <angle> "d" こんにちは 4157
    item <4158> & "co"'q' & <angle> "d" こんにちは 4158
    item <4159> & "co"'q' & <angle> "d" こんにちは 4159
    item <4160> & "co"'q' & <angle> "d" こんにちは 4160
    item <4161> & "co"'q' & <angle> "d" こんにちは 4161
    item <4162> & "co"'q' & <angle> "d" こんにちは 4162
    item <4163> & "co"'q' & <angle> "d" こんにちは 4163
    item <4164> & "co"'q' & <angle> "d" こんにちは 4164
    item <4165> & "co"'q' & <angle> "d" こんにちは 4165
    item <4166> & "co"'q' & <angle> "d" こんにちは 4166
    item <4167> & "co"'q' & <angle> "d" こんにちは 4167
    item <4168> & "co"'q' & <angle> "d" こんにちは 4168
    item <4169> & "co"'q' & <angle> "d" こんにちは 4169
    item <4170> & "co"'q' & <angle> "d" こんにちは 4170
    item <4171> & "co"'q' & <angle> "d" こんにちは 4171
    item <4172> & "co"'q' & <angle> "d" こんにちは 4172
    item <4173> & "co"'q' & <angle> "d" こんにちは 4173
    item <4174> & "co"'q' & <angle> "d" こんにちは 4174
    item <4175> & "co"'q' & <angle> "d" こんにちは 4175
    item <4176> & "co"'q' & <angle> "d" こんにちは 4176
    item <4177> & "co"'q' & <angle> "d" こんにちは 4177
    item <4178> & "co"'q' & <angle> "d" こんにちは 4178
    item <4179> & "co"'q' & <angle> "d" こんにちは 4179
    item <4180> & "co"'q' & <angle> "d" こんにちは 4180
    item <4181> & "co"'q' & <angle> "d" こんにちは 4181
    item <4182> & "co"'q' & <angle> "d" こんにちは 4182
    item <4183> & "co"'q' & <angle> "d" こんにちは 4183
    item <4184> & "co"'q' & <angle> "d" こんにちは 4184
    item <4185> & "co"'q' & <angle> "d" こんにちは 4185
    item <4186> & "co"'q' & <angle> "d" こんにちは 4186
    item <4187> & "co"'q' & <angle> "d" こんにちは 4187
    item <4188> & "co"'q' & <angle> "d" こんにちは 4188
    item <4189> & "co"'q' & <angle> "d" こんにちは 4189
    item <4190> & "co"'q' & <angle> "d" こんにちは 4190
    item <4191> & "co"'q' & <angle> "d" こんにちは 4191
    item <4192> & "co"'q' & <angle> "d" こんにちは 4192
    item <4193> & "co"'q' & <angle> "d" こんにちは 4193
    item <4194> & "co"'q' & <angle> "d" こんにちは 4194
    item <4195> & "co"'q' & <angle> "d" こんにちは 4195
    item <4196> & "co"'q' & <angle> "d" こんにちは 4196
    item <4197> & "co"'q' & <angle> "d" こんにちは 4197
    item <4198> & "co"'q' & <angle> "d" こんにちは 4198
    item <4199> & "co"'q' & <angle> "d" こんにちは 4199
    item <4200> & "co"'q' & <angle> "d" こんにちは 4200
    item <4201> & "co"'q' & <angle> "d" こんにちは 4201
    item <4202> & "co"'q' & <angle> "d" こんにちは 4202
    item <4203> & "co"'q' & <angle> "d" こんにちは 4203
    item <4204> & "co"'q' & <angle> "d" こんにちは 4204
    item <4205> & "co"'q' & <angle> "d" こんにちは 4205
    item <4206> & "co"'q' & <angle> "d" こんにちは 4206
    item <4207> & "co"'q' & <angle> "d" こんにちは 4207
    item <4208> & "co"'q' & <angle> "d" こんにちは 4208
    item <4209> & "co"'q' & <angle> "d" こんにちは 4209
    item <4210> & "co"'q' & <angle> "d" こんにちは 4210
    item <4211> & "co"'q' & <angle> "d" こんにちは 4211
    item <4212> & "co"'q' & <angle> "d" こんにちは 4212
    item <4213> & "co"'q' & <angle> "d" こんにちは 4213
    item <4214> & "co"'q' & <angle> "d" こんにちは 4214
    item <4215> & "co"'q' & <angle> "d" こんにちは 4215
    item <4216> & "co"'q' & <angle> "d" こんにちは 4216
    item <4217> & "co"'q' & <angle> "d" こんにちは 4217
    item <4218> & "co"'q' & <angle> "d" こんにちは 4218
    item <4219> & "co"'q' & <angle> "d" こんにちは 4219
    item <4220> & "co"'q' & <angle> "d" こんにちは 4220
    item <4221> & "co"'q' & <angle> "d" こんにちは 4221
    item <4222> & "co"'q' & <angle> "d" こんにちは 4222
    item <4223> & "co"'q' & <angle> "d" こんにちは 4223
    item <4224> & "co"'q' & <angle> "d" こんにちは 4224
    item <4225> & "co"'q' & <angle> "d" こんにちは 4225
    item <4226> & "co"'q' & <angle> "d" こんにちは 4226
    item <4227> & "co"'q' & <angle> "d" こんにちは 4227
    item <4228> & "co"'q' & <angle> "d" こんにちは 4228
    item <4229> & "co"'q' & <angle> "d" こんにちは 4229
    item <4230> & "co"'q' & <angle> "d" こんにちは 4230
    item <4231> & "co"'q' & <angle> "d" こんにちは 4231
    item <4232> & "co"'q' & <angle> "d" こんにちは 4232
    item <4233> & "co"'q' & <angle> "d" こんにちは 4233
    item <4234> & "co"'q' & <angle> "d" こんにちは 4234
    item <4235> & "co"'q' & <angle> "d" こんにちは 4235
    item <4236> & "co"'q' & <angle> "d" こんにちは 4236
    item <4237> & "co"'q' & <angle> "d" こんにちは 4237
    item <4238> & "co"'q' & <angle> "d" こんにちは 4238
    item <4239> & "co"'q' & <angle> "d" こんにちは 4239
    item <4240> & "co"'q' & <angle> "d" こんにちは 4240
    item <4241> & "co"'q' & <angle> "d" こんにちは 4241
    item <4242> & "co"'q' & <angle> "d" こんにちは 4242
    item <4243> & "co"'q' & <angle> "d" こんにちは 4243
    item <4244> & "co"'q' & <angle> "d" こんにちは 4244
    item <4245> & "co"'q' & <angle> "d" こんにちは 4245
    item <4246> & "co"'q' & <angle> "d" こんにちは 4246
    item <4247> & "co"'q' & <angle> "d" こんにちは 4247
    item <4248> & "co"'q' & <angle> "d" こんにちは 4248
    item <4249> & "co"'q' & <angle> "d" こんにちは 4249
    item <4250> & "co"'q' & <angle> "d" こんにちは 4250
    item <4251> & "co"'q' & <angle> "d" こんにちは 4251
    item <4252> & "co"'q' & <angle> "d" こんにちは 4252
    item <4253> & "co"'q' & <angle> "d" こんにちは 4253
    item <4254> & "co"'q' & <angle> "d" こんにちは 4254
    item <4255> & "co"'q' & <angle> "d" こんにちは 4255
    item <4256> & "co"'q' & <angle> "d" こんにちは 4256
    item <4257> & "co"'q' & <angle> "d" こんにちは 4257
    item <4258> & "co"'q' & <angle> "d" こんにちは 4258
    item <4259> & "co"'q' & <angle> "d" こんにちは 4259
    item <4260> & "co"'q' & <angle> "d" こんにちは 4260
    item <4261> & "co"'q' & <angle> "d" こんにちは 4261
    item <4262> & "co"'q' & <angle> "d" こんにちは 4262
    item <4263> & "co"'q' & <angle> "d" こんにちは 4263
    item <4264> & "co"'q' & <angle> "d" こんにちは 4264
    item <4265> & "co"'q' & <angle> "d" こんにちは 4265
    item <4266> & "co"'q' & <angle> "d" こんにちは 4266
    item <4267> & "co"'q' & <angle> "d" こんにちは 4267
    item <4268> & "co"'q' & <angle> "d" こんにちは 4268
    item <4269> & "co"'q' & <angle> "d" こんにちは 4269
    item <4270> & "co"'q' & <angle> "d" こんにちは 4270
    item <4271> & "co"'q' & <angle> "d" こんにちは 4271
    item <4272> & "co"'q' & <angle> "d" こんにちは 4272
    item <4273> & "co"'q' & <angle> "d" こんにちは 4273
    item <4274> & "co"'q' & <angle> "d" こんにちは 4274
    item <4275> & "co"'q' & <angle> "d" こんにちは 4275
    item <4276> & "co"'q' & <angle> "d" こんにちは 4276
    item <4277> & "co"'q' & <angle> "d" こんにちは 4277
    item <4278> & "co"'q' & <angle> "d" こんにちは 4278
    item <4279> & "co"'q' & <angle> "d" こんにちは 4279
    item <4280> & "co"'q' & <angle> "d" こんにちは 4280
    item <4281> & "co"'q' & <angle> "d" こんにちは 4281
    item <4282> & "co"'q' & <angle> "d" こんにちは 4282
    item <4283> & "co"'q' & <angle> "d" こんにちは 4283
    item <4284> & "co"'q' & <angle> "d" こんにちは 4284
    item <4285> & "co"'q' & <angle> "d" こんにちは 4285
    item <4286> & "co"'q' & <angle> "d" こんにちは 4286
    item <4287> & "co"'q' & <angle> "d" こんにちは 4287
    item <4288> & "co"'q' & <angle> "d" こんにちは 4288
    item <4289> & "co"'q' & <angle> "d" こんにちは 4289
    item <4290> & "co"'q' & <angle> "d" こんにちは 4290
    item <4291> & "co"'q' & <angle> "d" こんにちは 4291
    item <4292> & "co"'q' & <angle> "d" こんにちは 4292
    item <4293> & "co"'q' & <angle> "d" こんにちは 4293
    item <4294> & "co"'q' & <angle> "d" こんにちは 4294
    item <4295> & "co"'q' & <angle> "d" こんにちは 4295
    item <4296> & "co"'q' & <angle> "d" こんにちは 4296
    item <4297> & "co"'q' & <angle> "d" こんにちは 4297
    item <4298> & "co"'q' & <angle> "d" こんにちは 4298
    item <4299> & "co"'q' & <angle> "d" こんにちは 4299
    item <4300> & "co"'q' & <angle> "d" こんにちは 4300
    item <4301> & "co"'q' & <angle> "d" こんにちは 4301
    item <4302> & "co"'q' & <angle> "d" こんにちは 4302
    item <4303> & "co"'q' & <angle> "d" こんにちは 4303
    item <4304> & "co"'q' & <angle> "d" こんにちは 4304
    item <4305> & "co"'q' & <angle> "d" こんにちは 4305
    item <4306> & "co"'q' & <angle> "d" こんにちは 4306
    item <4307> & "co"'q' & <angle> "d" こんにちは 4307
    item <4308> & "co"'q' & <angle> "d" こんにちは 4308
    item <4309> & "co"'q' & <angle> "d" こんにちは 4309
    item <4310> & "co"'q' & <angle> "d" こんにちは 4310
    item <4311> & "co"'q' & <angle> "d" こんにちは 4311
    item <4312> & "co"'q' & <angle> "d" こんにちは 4312
    item <4313> & "co"'q' & <angle> "d" こんにちは 4313
    item <4314> & "co"'q' & <angle> "d" こんにちは 4314
    item <4315> & "co"'q' & <angle> "d" こんにちは 4315
    item <4316> & "co"'q' & <angle> "d" こんにちは 4316
    item <4317> & "co"'q' & <angle> "d" こんにちは 4317
    item <4318> & "co"'q' & <angle> "d" こんにちは 4318
    item <4319> & "co"'q' & <angle> "d" こんにちは 4319
    item <4320> & "co"'q' & <angle> "d" こんにちは 4320
    item <4321> & "co"'q' & <angle> "d" こんにちは 4321
    item <4322> & "co"'q' & <angle> "d" こんにちは 4322
    item <4323> & "co"'q' & <angle> "d" こんにちは 4323
    item <4324> & "co"'q' & <angle> "d" こんにちは 4324
    item <4325> & "co"'q' & <angle> "d" こんにちは 4325
    item <4326> & "co"'q' & <angle> "d" こんにちは 4326
    item <4327> & "co"'q' & <angle> "d" こんにちは 4327
    item <4328> & "co"'q' & <angle> "d" こんにちは 4328
    item <4329> & "co"'q' & <angle> "d" こんにちは 4329
    item <4330> & "co"'q' & <angle> "d" こんにちは 4330
    item <4331> & "co"'q' & <angle> "d" こんにちは 4331
    item <4332> & "co"'q' & <angle> "d" こんにちは 4332
    item <4333> & "co"'q' & <angle> "d" こんにちは 4333
    item <4334> & "co"'q' & <angle> "d" こんにちは 4334
    item <4335> & "co"'q' & <angle> "d" こんにちは 4335
    item <4336> & "co"'q' & <angle> "d" こんにちは 4336
    item <4337> & "co"'q' & <angle> "d" こんにちは 4337
    item <4338> & "co"'q' & <angle> "d" こんにちは 4338
    item <4339> & "co"'q' & <angle> "d" こんにちは 4339
    item <4340> & "co"'q' & <angle> "d" こんにちは 4340
    item <4341> & "co"'q' & <angle> "d" こんにちは 4341
    item <4342> & "co"'q' & <angle> "d" こんにちは 4342
    item <4343> & "co"'q' & <angle> "d" こんにちは 4343
    item <4344> & "co"'q' & <angle> "d" こんにちは 4344
    item <4345> & "co"'q' & <angle> "d" こんにちは 4345
    item <4346> & "co"'q' & <angle> "d" こんにちは 4346
    item <4347> & "co"'q' & <angle> "d" こんにちは 4347
    item <4348> & "co"'q' & <angle> "d" こんにちは 4348
    item <4349> & "co"'q' & <angle> "d" こんにちは 4349
    item <4350> & "co"'q' & <angle> "d" こんにちは 4350
    item <4351> & "co"'q' & <angle> "d" こんにちは 4351
    item <4352> & "co"'q' & <angle> "d" こんにちは 4352
    item <4353> & "co"'q' & <angle> "d" こんにちは 4353
    item <4354> & "co"'q' & <angle> "d" こんにちは 4354
    item <4355> & "co"'q' & <angle> "d" こんにちは 4355
    item <4356> & "co"'q' & <angle> "d" こんにちは 4356
    item <4357> & "co"'q' & <angle> "d" こんにちは 4357
    item <4358> & "co"'q' & <angle> "d" こんにちは 4358
    item <4359> & "co"'q' & <angle> "d" こんにちは 4359
    item <4360> & "co"'q' & <angle> "d" こんにちは 4360
    item <4361> & "co"'q' & <angle> "d" こんにちは 4361
    item <4362> & "co"'q' & <angle> "d" こんにちは 4362
    item <4363> & "co"'q' & <angle> "d" こんにちは 4363
    item <4364> & "co"'q' & <angle> "d" こんにちは 4364
    item <4365> & "co"'q' & <angle> "d" こんにちは 4365
    item <4366> & "co"'q' & <angle> "d" こんにちは 4366
    item <4367> & "co"'q' & <angle> "d" こんにちは 4367
    item <4368> & "co"'q' & <angle> "d" こんにちは 4368
    item <4369> & "co"'q' & <angle> "d" こんにちは 4369
    item <4370> & "co"'q' & <angle> "d" こんにちは 4370
    item <4371> & "co"'q' & <angle> "d" こんにちは 4371
    item <4372> & "co"'q' & <angle> "d" こんにちは 4372
    item <4373> & "co"'q' & <angle> "d" こんにちは 4373
    item <4374> & "co"'q' & <angle> "d" こんにちは 4374
    item <4375> & "co"'q' & <angle> "d" こんにちは 4375
    item <4376> & "co"'q' & <angle> "d" こんにちは 4376
    item <4377> & "co"'q' & <angle> "d" こんにちは 4377
    item <4378> & "co"'q' & <angle> "d" こんにちは 4378
    item <4379> & "co"'q' & <angle> "d" こんにちは 4379
    item <4380> & "co"'q' & <angle> "d" こんにちは 4380
    item <4381> & "co"'q' & <angle> "d" こんにちは 4381
    item <4382> & "co"'q' & <angle> "d" こんにちは 4382
    item <4383> & "co"'q' & <angle> "d" こんにちは 4383
    item <4384> & "co"'q' & <angle> "d" こんにちは 4384
    item <4385> & "co"'q' & <angle> "d" こんにちは 4385
    item <4386> & "co"'q' & <angle> "d" こんにちは 4386
    item <4387> & "co"'q' & <angle> "d" こんにちは 4387
    item <4388> & "co"'q' & <angle> "d" こんにちは 4388
    item <4389> & "co"'q' & <angle> "d" こんにちは 4389
    item <4390> & "co"'q' & <angle> "d" こんにちは 4390
    item <4391> & "co"'q' & <angle> "d" こんにちは 4391
    item <4392> & "co"'q' & <angle> "d" こんにちは 4392
    item <4393> & "co"'q' & <angle> "d" こんにちは 4393
    item <4394> & "co"'q' & <angle> "d" こんにちは 4394
    item <4395> & "co"'q' & <angle> "d" こんにちは 4395
    item <4396> & "co"'q' & <angle> "d" こんにちは 4396
    item <4397> & "co"'q' & <angle> "d" こんにちは 4397
    item <4398> & "co"'q' & <angle> "d" こんにちは 4398
    item <4399> & "co"'q' & <angle> "d" こんにちは 4399
    item <4400> & "co"'q' & <angle> "d" こんにちは 4400
    item <4401> & "co"'q' & <angle> "d" こんにちは 4401
    item <4402> & "co"'q' & <angle> "d" こんにちは 4402
    item <4403> & "co"'q' & <angle> "d" こんにちは 4403
    item <4404> & "co"'q' & <angle> "d" こんにちは 4404
    item <4405> & "co"'q' & <angle> "d" こんにちは 4405
    item <4406> & "co"'q' & <angle> "d" こんにちは 4406
    item <4407> & "co"'q' & <angle> "d" こんにちは 4407
    item <4408> & "co"'q' & <angle> "d" こんにちは 4408
    item <4409> & "co"'q' & <angle> "d" こんにちは 4409
    item <4410> & "co"'q' & <angle> "d" こんにちは 4410
    item <4411> & "co"'q' & <angle> "d" こんにちは 4411
    item <4412> & "co"'q' & <angle> "d" こんにちは 4412
    item <4413> & "co"'q' & <angle> "d" こんにちは 4413
    item <4414> & "co"'q' & <angle> "d" こんにちは 4414
    item <4415> & "co"'q' & <angle> "d" こんにちは 4415
    item <4416> & "co"'q' & <angle> "d" こんにちは 4416
    item <4417> & "co"'q' & <angle> "d" こんにちは 4417
    item <4418> & "co"'q' & <angle> "d" こんにちは 4418
    item <4419> & "co"'q' & <angle> "d" こんにちは 4419
    item <4420> & "co"'q' & <angle> "d" こんにちは 4420
    item <4421> & "co"'q' & <angle> "d" こんにちは 4421
    item <4422> & "co"'q' & <angle> "d" こんにちは 4422
    item <4423> & "co"'q' & <angle> "d" こんにちは 4423
    item <4424> & "co"'q' & <angle> "d" こんにちは 4424
    item <4425> & "co"'q' & <angle> "d" こんにちは 4425
    item <4426> & "co"'q' & <angle> "d" こんにちは 4426
    item <4427> & "co"'q' & <angle> "d" こんにちは 4427
    item <4428> & "co"'q' & <angle> "d" こんにちは 4428
    item <4429> & "co"'q' & <angle> "d" こんにちは 4429
    item <4430> & "co"'q' & <angle> "d" こんにちは 4430
    item <4431> & "co"'q' & <angle> "d" こんにちは 4431
    item <4432> & "co"'q' & <angle> "d" こんにちは 4432
    item <4433> & "co"'q' & <angle> "d" こんにちは 4433
    item <4434> & "co"'q' & <angle> "d" こんにちは 4434
    item <4435> & "co"'q' & <angle> "d" こんにちは 4435
    item <4436> & "co"'q' & <angle> "d" こんにちは 4436
    item <4437> & "co"'q' & <angle> "d" こんにちは 4437
    item <4438> & "co"'q' & <angle> "d" こんにちは 4438
    item <4439> & "co"'q' & <angle> "d" こんにちは 4439
    item <4440> & "co"'q' & <angle> "d" こんにちは 4440
    item <4441> & "co"'q' & <angle> "d" こんにちは 4441
    item <4442> & "co"'q' & <angle> "d" こんにちは 4442
    item <4443> & "co"'q' & <angle> "d" こんにちは 4443
    item <4444> & "co"'q' & <angle> "d" こんにちは 4444
    item <4445> & "co"'q' & <angle> "d" こんにちは 4445
    item <4446> & "co"'q' & <angle> "d" こんにちは 4446
    item <4447> & "co"'q' & <angle> "d" こんにちは 4447
    item <4448> & "co"'q' & <angle> "d" こんにちは 4448
    item <4449> & "co"'q' & <angle> "d" こんにちは 4449
    item <4450> & "co"'q' & <angle> "d" こんにちは 4450
    item <4451> & "co"'q' & <angle> "d" こんにちは 4451
    item <4452> & "co"'q' & <angle> "d" こんにちは 4452
    item <4453> & "co"'q' & <angle> "d" こんにちは 4453
    item <4454> & "co"'q' & <angle> "d" こんにちは 4454
    item <4455> & "co"'q' & <angle> "d" こんにちは 4455
    item <4456> & "co"'q' & <angle> "d" こんにちは 4456
    item <4457> & "co"'q' & <angle> "d" こんにちは 4457
    item <4458> & "co"'q' & <angle> "d" こんにちは 4458
    item <4459> & "co"'q' & <angle> "d" こんにちは 4459
    item <4460> & "co"'q' & <angle> "d" こんにちは 4460
    item <4461> & "co"'q' & <angle> "d" こんにちは 4461
    item <4462> & "co"'q' & <angle> "d" こんにちは 4462
    item <4463> & "co"'q' & <angle> "d" こんにちは 4463
    item <4464> & "co"'q' & <angle> "d" こんにちは 4464
    item <4465> & "co"'q' & <angle> "d" こんにちは 4465
    item <4466> & "co"'q' & <angle> "d" こんにちは 4466
    item <4467> & "co"'q' & <angle> "d" こんにちは 4467
    item <4468> & "co"'q' & <angle> "d" こんにちは 4468
    item <4469> & "co"'q' & <angle> "d" こんにちは 4469
    item <4470> & "co"'q' & <angle> "d" こんにちは 4470
    item <4471> & "co"'q' & <angle> "d" こんにちは 4471
    item <4472> & "co"'q' & <angle> "d" こんにちは 4472
    item <4473> & "co"'q' & <angle> "d" こんにちは 4473
    item <4474> & "co"'q' & <angle> "d" こんにちは 4474
    item <4475> & "co"'q' & <angle> "d" こんにちは 4475
    item <4476> & "co"'q' & <angle> "d" こんにちは 4476
    item <4477> & "co"'q' & <angle> "d" こんにちは 4477
    item <4478> & "co"'q' & <angle> "d" こんにちは 4478
    item <4479> & "co"'q' & <angle> "d" こんにちは 4479
    item <4480> & "co"'q' & <angle> "d" こんにちは 4480
    item <4481> & "co"'q' & <angle> "d" こんにちは 4481
    item <4482> & "co"'q' & <angle> "d" こんにちは 4482
    item <4483> & "co"'q' & <angle> "d" こんにちは 4483
    item <4484> & "co"'q' & <angle> "d" こんにちは 4484
    item <4485> & "co"'q' & <angle> "d" こんにちは 4485
    item <4486> & "co"'q' & <angle> "d" こんにちは 4486
    item <4487> & "co"'q' & <angle> "d" こんにちは 4487
    item <4488> & "co"'q' & <angle> "d" こんにちは 4488
    item <4489> & "co"'q' & <angle> "d" こんにちは 4489
    item <4490> & "co"'q' & <angle> "d" こんにちは 4490
    item <4491> & "co"'q' & <angle> "d" こんにちは 4491
    item <4492> & "co"'q' & <angle> "d" こんにちは 4492
    item <4493> & "co"'q' & <angle> "d" こんにちは 4493
    item <4494> & "co"'q' & <angle> "d" こんにちは 4494
    item <4495> & "co"'q' & <angle> "d" こんにちは 4495
    item <4496> & "co"'q' & <angle> "d" こんにちは 4496
    item <4497> & "co"'q' & <angle> "d" こんにちは 4497
    item <4498> & "co"'q' & <angle> "d" こんにちは 4498
    item <4499> & "co"'q' & <angle> "d" こんにちは 4499
    item <4500> & "co"'q' & <angle> "d" こんにちは 4500
    item <4501> & "co"'q' & <angle> "d" こんにちは 4501
    item <4502> & "co"'q' & <angle> "d" こんにちは 4502
    item <4503> & "co"'q' & <angle> "d" こんにちは 4503
    item <4504> & "co"'q' & <angle> "d" こんにちは 4504
    item <4505> & "co"'q' & <angle> "d" こんにちは 4505
    item <4506> & "co"'q' & <angle> "d" こんにちは 4506
    item <4507> & "co"'q' & <angle> "d" こんにちは 4507
    item <4508> & "co"'q' & <angle> "d" こんにちは 4508
    item <4509> & "co"'q' & <angle> "d" こんにちは 4509
    item <4510> & "co"'q' & <angle> "d" こんにちは 4510
    item <4511> & "co"'q' & <angle> "d" こんにちは 4511
    item <4512> & "co"'q' & <angle> "d" こんにちは 4512
    item <4513> & "co"'q' & <angle> "d" こんにちは 4513
    item <4514> & "co"'q' & <angle> "d" こんにちは 4514
    item <4515> & "co"'q' & <angle> "d" こんにちは 4515
    item <4516> & "co"'q' & <angle> "d" こんにちは 4516
    item <4517> & "co"'q' & <angle> "d" こんにちは 4517
    item <4518> & "co"'q' & <angle> "d" こんにちは 4518
    item <4519> & "co"'q' & <angle> "d" こんにちは 4519
    item <4520> & "co"'q' & <angle> "d" こんにちは 4520
    item <4521> & "co"'q' & <angle> "d" こんにちは 4521
    item <4522> & "co"'q' & <angle> "d" こんにちは 4522
    item <4523> & "co"'q' & <angle> "d" こんにちは 4523
    item <4524> & "co"'q' & <angle> "d" こんにちは 4524
    item <4525> & "co"'q' & <angle> "d" こんにちは 4525
    item <4526> & "co"'q' & <angle> "d" こんにちは 4526
    item <4527> & "co"'q' & <angle> "d" こんにちは 4527
    item <4528> & "co"'q' & <angle> "d" こんにちは 4528
    item <4529> & "co"'q' & <angle> "d" こんにちは 4529
    item <4530> & "co"'q' & <angle> "d" こんにちは 4530
    item <4531> & "co"'q' & <angle> "d" こんにちは 4531
    item <4532> & "co"'q' & <angle> "d" こんにちは 4532
    item <4533> & "co"'q' & <angle> "d" こんにちは 4533
    item <4534> & "co"'q' & <angle> "d" こんにちは 4534
    item <4535> & "co"'q' & <angle> "d" こんにちは 4535
    item <4536> & "co"'q' & <angle> "d" こんにちは 4536
    item <4537> & "co"'q' & <angle> "d" こんにちは 4537
    item <4538> & "co"'q' & <angle> "d" こんにちは 4538
    item <4539> & "co"'q' & <angle> "d" こんにちは 4539
    item <4540> & "co"'q' & <angle> "d" こんにちは 4540
    item <4541> & "co"'q' & <angle> "d" こんにちは 4541
    item <4542> & "co"'q' & <angle> "d" こんにちは 4542
    item <4543> & "co"'q' & <angle> "d" こんにちは 4543
    item <4544> & "co"'q' & <angle> "d" こんにちは 4544
    item <4545> & "co"'q' & <angle> "d" こんにちは 4545
    item <4546> & "co"'q' & <angle> "d" こんにちは 4546
    item <4547> & "co"'q' & <angle> "d" こんにちは 4547
    item <4548> & "co"'q' & <angle> "d" こんにちは 4548
    item <4549> & "co"'q' & <angle> "d" こんにちは 4549
    item <4550> & "co"'q' & <angle> "d" こんにちは 4550
    item <4551> & "co"'q' & <angle> "d" こんにちは 4551
    item <4552> & "co"'q' & <angle> "d" こんにちは 4552
    item <4553> & "co"'q' & <angle> "d" こんにちは 4553
    item <4554> & "co"'q' & <angle> "d" こんにちは 4554
    item <4555> & "co"'q' & <angle> "d" こんにちは 4555
    item <4556> & "co"'q' & <angle> "d" こんにちは 4556
    item <4557> & "co"'q' & <angle> "d" こんにちは 4557
    item <4558> & "co"'q' & <angle> "d" こんにちは 4558
    item <4559> & "co"'q' & <angle> "d" こんにちは 4559
    item <4560> & "co"'q' & <angle> "d" こんにちは 4560
    item <4561> & "co"'q' & <angle> "d" こんにちは 4561
    item <4562> & "co"'q' & <angle> "d" こんにちは 4562
    item <4563> & "co"'q' & <angle> "d" こんにちは 4563
    item <4564> & "co"'q' & <angle> "d" こんにちは 4564
    item <4565> & "co"'q' & <angle> "d" こんにちは 4565
    item <4566> & "co"'q' & <angle> "d" こんにちは 4566
    item <4567> & "co"'q' & <angle> "d" こんにちは 4567
    item <4568> & "co"'q' & <angle> "d" こんにちは 4568
    item <4569> & "co"'q' & <angle> "d" こんにちは 4569
    item <4570> & "co"'q' & <angle> "d" こんにちは 4570
    item <4571> & "co"'q' & <angle> "d" こんにちは 4571
    item <4572> & "co"'q' & <angle> "d" こんにちは 4572
    item <4573> & "co"'q' & <angle> "d" こんにちは 4573
    item <4574> & "co"'q' & <angle> "d" こんにちは 4574
    item <4575> & "co"'q' & <angle> "d" こんにちは 4575
    item <4576> & "co"'q' & <angle> "d" こんにちは 4576
    item <4577> & "co"'q' & <angle> "d" こんにちは 4577
    item <4578> & "co"'q' & <angle> "d" こんにちは 4578
    item <4579> & "co"'q' & <angle> "d" こんにちは 4579
    item <4580> & "co"'q' & <angle> "d" こんにちは 4580
    item <4581> & "co"'q' & <angle> "d" こんにちは 4581
    item <4582> & "co"'q' & <angle> "d" こんにちは 4582
    item <4583> & "co"'q' & <angle> "d" こんにちは 4583
    item <4584> & "co"'q' & <angle> "d" こんにちは 4584
    item <4585> & "co"'q' & <angle> "d" こんにちは 4585
    item <4586> & "co"'q' & <angle> "d" こんにちは 4586
    item <4587> & "co"'q' & <angle> "d" こんにちは 4587
    item <4588> & "co"'q' & <angle> "d" こんにちは 4588
    item <4589> & "co"'q' & <angle> "d" こんにちは 4589
    item <4590> & "co"'q' & <angle> "d" こんにちは 4590
    item <4591> & "co"'q' & <angle> "d" こんにちは 4591
    item <4592> & "co"'q' & <angle> "d" こんにちは 4592
    item <4593> & "co"'q' & <angle> "d" こんにちは 4593
    item <4594> & "co"'q' & <angle> "d" こんにちは 4594
    item <4595> & "co"'q' & <angle> "d" こんにちは 4595
    item <4596> & "co"'q' & <angle> "d" こんにちは 4596
    item <4597> & "co"'q' & <angle> "d" こんにちは 4597
    item <4598> & "co"'q' & <angle> "d" こんにちは 4598
    item <4599> & "co"'q' & <angle> "d" こんにちは 4599
    item <4600> & "co"'q' & <angle> "d" こんにちは 4600
    item <4601> & "co"'q' & <angle> "d" こんにちは 4601
    item <4602> & "co"'q' & <angle> "d" こんにちは 4602
    item <4603> & "co"'q' & <angle> "d" こんにちは 4603
    item <4604> & "co"'q' & <angle> "d" こんにちは 4604
    item <4605> & "co"'q' & <angle> "d" こんにちは 4605
    item <4606> & "co"'q' & <angle> "d" こんにちは 4606
    item <4607> & "co"'q' & <angle> "d" こんにちは 4607
    item <4608> & "co"'q' & <angle> "d" こんにちは 4608
    item <4609> & "co"'q' & <angle> "d" こんにちは 4609
    item <4610> & "co"'q' & <angle> "d" こんにちは 4610
    item <4611> & "co"'q' & <angle> "d" こんにちは 4611
    item <4612> & "co"'q' & <angle> "d" こんにちは 4612
    item <4613> & "co"'q' & <angle> "d" こんにちは 4613
    item <4614> & "co"'q' & <angle> "d" こんにちは 4614
    item <4615> & "co"'q' & <angle> "d" こんにちは 4615
    item <4616> & "co"'q' & <angle> "d" こんにちは 4616
    item <4617> & "co"'q' & <angle> "d" こんにちは 4617
    item <4618> & "co"'q' & <angle> "d" こんにちは 4618
    item <4619> & "co"'q' & <angle> "d" こんにちは 4619
    item <4620> & "co"'q' & <angle> "d" こんにちは 4620
    item <4621> & "co"'q' & <angle> "d" こんにちは 4621
    item <4622> & "co"'q' & <angle> "d" こんにちは 4622
    item <4623> & "co"'q' & <angle> "d" こんにちは 4623
    item <4624> & "co"'q' & <angle> "d" こんにちは 4624
    item <4625> & "co"'q' & <angle> "d" こんにちは 4625
    item <4626> & "co"'q' & <angle> "d" こんにちは 4626
    item <4627> & "co"'q' & <angle> "d" こんにちは 4627
    item <4628> & "co"'q' & <angle> "d" こんにちは 4628
    item <4629> & "co"'q' & <angle> "d" こんにちは 4629
    item <4630> & "co"'q' & <angle> "d" こんにちは 4630
    item <4631> & "co"'q' & <angle> "d" こんにちは 4631
    item <4632> & "co"'q' & <angle> "d" こんにちは 4632
    item <4633> & "co"'q' & <angle> "d" こんにちは 4633
    item <4634> & "co"'q' & <angle> "d" こんにちは 4634
    item <4635> & "co"'q' & <angle> "d" こんにちは 4635
    item <4636> & "co"'q' & <angle> "d" こんにちは 4636
    item <4637> & "co"'q' & <angle> "d" こんにちは 4637
    item <4638> & "co"'q' & <angle> "d" こんにちは 4638
    item <4639> & "co"'q' & <angle> "d" こんにちは 4639
    item <4640> & "co"'q' & <angle> "d" こんにちは 4640
    item <4641> & "co"'q' & <angle> "d" こんにちは 4641
    item <4642> & "co"'q' & <angle> "d" こんにちは 4642
    item <4643> & "co"'q' & <angle> "d" こんにちは 4643
    item <4644> & "co"'q' & <angle> "d" こんにちは 4644
    item <4645> & "co"'q' & <angle> "d" こんにちは 4645
    item <4646> & "co"'q' & <angle> "d" こんにちは 4646
    item <4647> & "co"'q' & <angle> "d" こんにちは 4647
    item <4648> & "co"'q' & <angle> "d" こんにちは 4648
    item <4649> & "co"'q' & <angle> "d" こんにちは 4649
    item <4650> & "co"'q' & <angle> "d" こんにちは 4650
    item <4651> & "co"'q' & <angle> "d" こんにちは 4651
    item <4652> & "co"'q' & <angle> "d" こんにちは 4652
    item <4653> & "co"'q' & <angle> "d" こんにちは 4653
    item <4654> & "co"'q' & <angle> "d" こんにちは 4654
    item <4655> & "co"'q' & <angle> "d" こんにちは 4655
    item <4656> & "co"'q' & <angle> "d" こんにちは 4656
    item <4657> & "co"'q' & <angle> "d" こんにちは 4657
    item <4658> & "co"'q' & <angle> "d" こんにちは 4658
    item <4659> & "co"'q' & <angle> "d" こんにちは 4659
    item <4660> & "co"'q' & <angle> "d" こんにちは 4660
    item <4661> & "co"'q' & <angle> "d" こんにちは 4661
    item <4662> & "co"'q' & <angle> "d" こんにちは 4662
    item <4663> & "co"'q' & <angle> "d" こんにちは 4663
    item <4664> & "co"'q' & <angle> "d" こんにちは 4664
    item <4665> & "co"'q' & <angle> "d" こんにちは 4665
    item <4666> & "co"'q' & <angle> "d" こんにちは 4666
    item <4667> & "co"'q' & <angle> "d" こんにちは 4667
    item <4668> & "co"'q' & <angle> "d" こんにちは 4668
    item <4669> & "co"'q' & <angle> "d" こんにちは 4669
    item <4670> & "co"'q' & <angle> "d" こんにちは 4670
    item <4671> & "co"'q' & <angle> "d" こんにちは 4671
    item <4672> & "co"'q' & <angle> "d" こんにちは 4672
    item <4673> & "co"'q' & <angle> "d" こんにちは 4673
    item <4674> & "co"'q' & <angle> "d" こんにちは 4674
    item <4675> & "co"'q' & <angle> "d" こんにちは 4675
    item <4676> & "co"'q' & <angle> "d" こんにちは 4676
    item <4677> & "co"'q' & <angle> "d" こんにちは 4677
    item <4678> & "co"'q' & <angle> "d" こんにちは 4678
    item <4679> & "co"'q' & <angle> "d" こんにちは 4679
    item <4680> & "co"'q' & <angle> "d" こんにちは 4680
    item <4681> & "co"'q' & <angle> "d" こんにちは 4681
    item <4682> & "co"'q' & <angle> "d" こんにちは 4682
    item <4683> & "co"'q' & <angle> "d" こんにちは 4683
    item <4684> & "co"'q' & <angle> "d" こんにちは 4684
    item <4685> & "co"'q' & <angle> "d" こんにちは 4685
    item <4686> & "co"'q' & <angle> "d" こんにちは 4686
    item <4687> & "co"'q' & <angle> "d" こんにちは 4687
    item <4688> & "co"'q' & <angle> "d" こんにちは 4688
    item <4689> & "co"'q' & <angle> "d" こんにちは 4689
    item <4690> & "co"'q' & <angle> "d" こんにちは 4690
    item <4691> & "co"'q' & <angle> "d" こんにちは 4691
    item <4692> & "co"'q' & <angle> "d" こんにちは 4692
    item <4693> & "co"'q' & <angle> "d" こんにちは 4693
    item <4694> & "co"'q' & <angle> "d" こんにちは 4694
    item <4695> & "co"'q' & <angle> "d" こんにちは 4695
    item <4696> & "co"'q' & <angle> "d" こんにちは 4696
    item <4697> & "co"'q' & <angle> "d" こんにちは 4697
    item <4698> & "co"'q' & <angle> "d" こんにちは 4698
    item <4699> & "co"'q' & <angle> "d" こんにちは 4699
    item <4700> & "co"'q' & <angle> "d" こんにちは 4700
    item <4701> & "co"'q' & <angle> "d" こんにちは 4701
    item <4702> & "co"'q' & <angle> "d" こんにちは 4702
    item <4703> & "co"'q' & <angle> "d" こんにちは 4703
    item <4704> & "co"'q' & <angle> "d" こんにちは 4704
    item <4705> & "co"'q' & <angle> "d" こんにちは 4705
    item <4706> & "co"'q' & <angle> "d" こんにちは 4706
    item <4707> & "co"'q' & <angle> "d" こんにちは 4707
    item <4708> & "co"'q' & <angle> "d" こんにちは 4708
    item <4709> & "co"'q' & <angle> "d" こんにちは 4709
    item <4710> & "co"'q' & <angle> "d" こんにちは 4710
    item <4711> & "co"'q' & <angle> "d" こんにちは 4711
    item <4712> & "co"'q' & <angle> "d" こんにちは 4712
    item <4713> & "co"'q' & <angle> "d" こんにちは 4713
    item <4714> & "co"'q' & <angle> "d" こんにちは 4714
    item <4715> & "co"'q' & <angle> "d" こんにちは 4715
    item <4716> & "co"'q' & <angle> "d" こんにちは 4716
    item <4717> & "co"'q' & <angle> "d" こんにちは 4717
    item <4718> & "co"'q' & <angle> "d" こんにちは 4718
    item <4719> & "co"'q' & <angle> "d" こんにちは 4719
    item <4720> & "co"'q' & <angle> "d" こんにちは 4720
    item <4721> & "co"'q' & <angle> "d" こんにちは 4721
    item <4722> & "co"'q' & <angle> "d" こんにちは 4722
    item <4723> & "co"'q' & <angle> "d" こんにちは 4723
    item <4724> & "co"'q' & <angle> "d" こんにちは 4724
    item <4725> & "co"'q' & <angle> "d" こんにちは 4725
    item <4726> & "co"'q' & <angle> "d" こんにちは 4726
    item <4727> & "co"'q' & <angle> "d" こんにちは 4727
    item <4728> & "co"'q' & <angle> "d" こんにちは 4728
    item <4729> & "co"'q' & <angle> "d" こんにちは 4729
    item <4730> & "co"'q' & <angle> "d" こんにちは 4730
    item <4731> & "co"'q' & <angle> "d" こんにちは 4731
    item <4732> & "co"'q' & <angle> "d" こんにちは 4732
    item <4733> & "co"'q' & <angle> "d" こんにちは 4733
    item <4734> & "co"'q' & <angle> "d" こんにちは 4734
    item <4735> & "co"'q' & <angle> "d" こんにちは 4735
    item <4736> & "co"'q' & <angle> "d" こんにちは 4736
    item <4737> & "co"'q' & <angle> "d" こんにちは 4737
    item <4738> & "co"'q' & <angle> "d" こんにちは 4738
    item <4739> & "co"'q' & <angle> "d" こんにちは 4739
    item <4740> & "co"'q' & <angle> "d" こんにちは 4740
    item <4741> & "co"'q' & <angle> "d" こんにちは 4741
    item <4742> & "co"'q' & <angle> "d" こんにちは 4742
    item <4743> & "co"'q' & <angle> "d" こんにちは 4743
    item <4744> & "co"'q' & <angle> "d" こんにちは 4744
    item <4745> & "co"'q' & <angle> "d" こんにちは 4745
    item <4746> & "co"'q' & <angle> "d" こんにちは 4746
    item <4747> & "co"'q' & <angle> "d" こんにちは 4747
    item <4748> & "co"'q' & <angle> "d" こんにちは 4748
    item <4749> & "co"'q' & <angle> "d" こんにちは 4749
    item <4750> & "co"'q' & <angle> "d" こんにちは 4750
    item <4751> & "co"'q' & <angle> "d" こんにちは 4751
    item <4752> & "co"'q' & <angle> "d" こんにちは 4752
    item <4753> & "co"'q' & <angle> "d" こんにちは 4753
    item <4754> & "co"'q' & <angle> "d" こんにちは 4754
    item <4755> & "co"'q' & <angle> "d" こんにちは 4755
    item <4756> & "co"'q' & <angle> "d" こんにちは 4756
    item <4757> & "co"'q' & <angle> "d" こんにちは 4757
    item <4758> & "co"'q' & <angle> "d" こんにちは 4758
    item <4759> & "co"'q' & <angle> "d" こんにちは 4759
    item <4760> & "co"'q' & <angle> "d" こんにちは 4760
    item <4761> & "co"'q' & <angle> "d" こんにちは 4761
    item <4762> & "co"'q' & <angle> "d" こんにちは 4762
    item <4763> & "co"'q' & <angle> "d" こんにちは 4763
    item <4764> & "co"'q' & <angle> "d" こんにちは 4764
    item <4765> & "co"'q' & <angle> "d" こんにちは 4765
    item <4766> & "co"'q' & <angle> "d" こんにちは 4766
    item <4767> & "co"'q' & <angle> "d" こんにちは 4767
    item <4768> & "co"'q' & <angle> "d" こんにちは 4768
    item <4769> & "co"'q' & <angle> "d" こんにちは 4769
    item <4770> & "co"'q' & <angle> "d" こんにちは 4770
    item <4771> & "co"'q' & <angle> "d" こんにちは 4771
    item <4772> & "co"'q' & <angle> "d" こんにちは 4772
    item <4773> & "co"'q' & <angle> "d" こんにちは 4773
    item <4774> & "co"'q' & <angle> "d" こんにちは 4774
    item <4775> & "co"'q' & <angle> "d" こんにちは 4775
    item <4776> & "co"'q' & <angle> "d" こんにちは 4776
    item <4777> & "co"'q' & <angle> "d" こんにちは 4777
    item <4778> & "co"'q' & <angle> "d" こんにちは 4778
    item <4779> & "co"'q' & <angle> "d" こんにちは 4779
    item <4780> & "co"'q' & <angle> "d" こんにちは 4780
    item <4781> & "co"'q' & <angle> "d" こんにちは 4781
    item <4782> & "co"'q' & <angle> "d" こんにちは 4782
    item <4783> & "co"'q' & <angle> "d" こんにちは 4783
    item <4784> & "co"'q' & <angle> "d" こんにちは 4784
    item <4785> & "co"'q' & <angle> "d" こんにちは 4785
    item <4786> & "co"'q' & <angle> "d" こんにちは 4786
    item <4787> & "co"'q' & <angle> "d" こんにちは 4787
    item <4788> & "co"'q' & <angle> "d" こんにちは 4788
    item <4789> & "co"'q' & <angle> "d" こんにちは 4789
    item <4790> & "co"'q' & <angle> "d" こんにちは 4790
    item <4791> & "co"'q' & <angle> "d" こんにちは 4791
    item <4792> & "co"'q' & <angle> "d" こんにちは 4792
    item <4793> & "co"'q' & <angle> "d" こんにちは 4793
    item <4794> & "co"'q' & <angle> "d" こんにちは 4794
    item <4795> & "co"'q' & <angle> "d" こんにちは 4795
    item <4796> & "co"'q' & <angle> "d" こんにちは 4796
    item <4797> & "co"'q' & <angle> "d" こんにちは 4797
    item <4798> & "co"'q' & <angle> "d" こんにちは 4798
    item <4799> & "co"'q' & <angle> "d" こんにちは 4799
    item <4800> & "co"'q' & <angle> "d" こんにちは 4800
    item <4801> & "co"'q' & <angle> "d" こんにちは 4801
    item <4802> & "co"'q' & <angle> "d" こんにちは 4802
    item <4803> & "co"'q' & <angle> "d" こんにちは 4803
    item <4804> & "co"'q' & <angle> "d" こんにちは 4804
    item <4805> & "co"'q' & <angle> "d" こんにちは 4805
    item <4806> & "co"'q' & <angle> "d" こんにちは 4806
    item <4807> & "co"'q' & <angle> "d" こんにちは 4807
    item <4808> & "co"'q' & <angle> "d" こんにちは 4808
    item <4809> & "co"'q' & <angle> "d" こんにちは 4809
    item <4810> & "co"'q' & <angle> "d" こんにちは 4810
    item <4811> & "co"'q' & <angle> "d" こんにちは 4811
    item <4812> & "co"'q' & <angle> "d" こんにちは 4812
    item <4813> & "co"'q' & <angle> "d" こんにちは 4813
    item <4814> & "co"'q' & <angle> "d" こんにちは 4814
    item <4815> & "co"'q' & <angle> "d" こんにちは 4815
    item <4816> & "co"'q' & <angle> "d" こんにちは 4816
    item <4817> & "co"'q' & <angle> "d" こんにちは 4817
    item <4818> & "co"'q' & <angle> "d" こんにちは 4818
    item <4819> & "co"'q' & <angle> "d" こんにちは 4819
    item <4820> & "co"'q' & <angle> "d" こんにちは 4820
    item <4821> & "co"'q' & <angle> "d" こんにちは 4821
    item <4822> & "co"'q' & <angle> "d" こんにちは 4822
    item <4823> & "co"'q' & <angle> "d" こんにちは 4823
    item <4824> & "co"'q' & <angle> "d" こんにちは 4824
    item <4825> & "co"'q' & <angle> "d" こんにちは 4825
    item <4826> & "co"'q' & <angle> "d" こんにちは 4826
    item <4827> & "co"'q' & <angle> "d" こんにちは 4827
    item <4828> & "co"'q' & <angle> "d" こんにちは 4828
    item <4829> & "co"'q' & <angle> "d" こんにちは 4829
    item <4830> & "co"'q' & <angle> "d" こんにちは 4830
    item <4831> & "co"'q' & <angle> "d" こんにちは 4831
    item <4832> & "co"'q' & <angle> "d" こんにちは 4832
    item <4833> & "co"'q' & <angle> "d" こんにちは 4833
    item <4834> & "co"'q' & <angle> "d" こんにちは 4834
    item <4835> & "co"'q' & <angle> "d" こんにちは 4835
    item <4836> & "co"'q' & <angle> "d" こんにちは 4836
    item <4837> & "co"'q' & <angle> "d" こんにちは 4837
    item <4838> & "co"'q' & <angle> "d" こんにちは 4838
    item <4839> & "co"'q' & <angle> "d" こんにちは 4839
    item <4840> & "co"'q' & <angle> "d" こんにちは 4840
    item <4841> & "co"'q' & <angle> "d" こんにちは 4841
    item <4842> & "co"'q' & <angle> "d" こんにちは 4842
    item <4843> & "co"'q' & <angle> "d" こんにちは 4843
    item <4844> & "co"'q' & <angle> "d" こんにちは 4844
    item <4845> & "co"'q' & <angle> "d" こんにちは 4845
    item <4846> & "co"'q' & <angle> "d" こんにちは 4846
    item <4847> & "co"'q' & <angle> "d" こんにちは 4847
    item <4848> & "co"'q' & <angle> "d" こんにちは 4848
    item <4849> & "co"'q' & <angle> "d" こんにちは 4849
    item <4850> & "co"'q' & <angle> "d" こんにちは 4850
    item <4851> & "co"'q' & <angle> "d" こんにちは 4851
    item <4852> & "co"'q' & <angle> "d" こんにちは 4852
    item <4853> & "co"'q' & <angle> "d" こんにちは 4853
    item <4854> & "co"'q' & <angle> "d" こんにちは 4854
    item <4855> & "co"'q' & <angle> "d" こんにちは 4855
    item <4856> & "co"'q' & <angle> "d" こんにちは 4856
    item <4857> & "co"'q' & <angle> "d" こんにちは 4857
    item <4858> & "co"'q' & <angle> "d" こんにちは 4858
    item <4859> & "co"'q' & <angle> "d" こんにちは 4859
    item <4860> & "co"'q' & <angle> "d" こんにちは 4860
    item <4861> & "co"'q' & <angle> "d" こんにちは 4861
    item <4862> & "co"'q' & <angle> "d" こんにちは 4862
    item <4863> & "co"'q' & <angle> "d" こんにちは 4863
    item <4864> & "co"'q' & <angle> "d" こんにちは 4864
    item <4865> & "co"'q' & <angle> "d" こんにちは 4865
    item <4866> & "co"'q' & <angle> "d" こんにちは 4866
    item <4867> & "co"'q' & <angle> "d" こんにちは 4867
    item <4868> & "co"'q' & <angle> "d" こんにちは 4868
    item <4869> & "co"'q' & <angle> "d" こんにちは 4869
    item <4870> & "co"'q' & <angle> "d" こんにちは 4870
    item <4871> & "co"'q' & <angle> "d" こんにちは 4871
    item <4872> & "co"'q' & <angle> "d" こんにちは 4872
    item <4873> & "co"'q' & <angle> "d" こんにちは 4873
    item <4874> & "co"'q' & <angle> "d" こんにちは 4874
    item <4875> & "co"'q' & <angle> "d" こんにちは 4875
    item <4876> & "co"'q' & <angle> "d" こんにちは 4876
    item <4877> & "co"'q' & <angle> "d" こんにちは 4877
    item <4878> & "co"'q' & <angle> "d" こんにちは 4878
    item <4879> & "co"'q' & <angle> "d" こんにちは 4879
    item <4880> & "co"'q' & <angle> "d" こんにちは 4880
    item <4881> & "co"'q' & <angle> "d" こんにちは 4881
    item <4882> & "co"'q' & <angle> "d" こんにちは 4882
    item <4883> & "co"'q' & <angle> "d" こんにちは 4883
    item <4884> & "co"'q' & <angle> "d" こんにちは 4884
    item <4885> & "co"'q' & <angle> "d" こんにちは 4885
    item <4886> & "co"'q' & <angle> "d" こんにちは 4886
    item <4887> & "co"'q' & <angle> "d" こんにちは 4887
    item <4888> & "co"'q' & <angle> "d" こんにちは 4888
    item <4889> & "co"'q' & <angle> "d" こんにちは 4889
    item <4890> & "co"'q' & <angle> "d" こんにちは 4890
    item <4891> & "co"'q' & <angle> "d" こんにちは 4891
    item <4892> & "co"'q' & <angle> "d" こんにちは 4892
    item <4893> & "co"'q' & <angle> "d" こんにちは 4893
    item <4894> & "co"'q' & <angle> "d" こんにちは 4894
    item <4895> & "co"'q' & <angle> "d" こんにちは 4895
    item <4896> & "co"'q' & <angle> "d" こんにちは 4896
    item <4897> & "co"'q' & <angle> "d" こんにちは 4897
    item <4898> & "co"'q' & <angle> "d" こんにちは 4898
    item <4899> & "co"'q' & <angle> "d" こんにちは 4899
    item <4900> & "co"'q' & <angle> "d" こんにちは 4900
    item <4901> & "co"'q' & <angle> "d" こんにちは 4901
    item <4902> & "co"'q' & <angle> "d" こんにちは 4902
    item <4903> & "co"'q' & <angle> "d" こんにちは 4903
    item <4904> & "co"'q' & <angle> "d" こんにちは 4904
    item <4905> & "co"'q' & <angle> "d" こんにちは 4905
    item <4906> & "co"'q' & <angle> "d" こんにちは 4906
    item <4907> & "co"'q' & <angle> "d" こんにちは 4907
    item <4908> & "co"'q' & <angle> "d" こんにちは 4908
    item <4909> & "co"'q' & <angle> "d" こんにちは 4909
    item <4910> & "co"'q' & <angle> "d" こんにちは 4910
    item <4911> & "co"'q' & <angle> "d" こんにちは 4911
    item <4912> & "co"'q' & <angle> "d" こんにちは 4912
    item <4913> & "co"'q' & <angle> "d" こんにちは 4913
    item <4914> & "co"'q' & <angle> "d" こんにちは 4914
    item <4915> & "co"'q' & <angle> "d" こんにちは 4915
    item <4916> & "co"'q' & <angle> "d" こんにちは 4916
    item <4917> & "co"'q' & <angle> "d" こんにちは 4917
    item <4918> & "co"'q' & <angle> "d" こんにちは 4918
    item <4919> & "co"'q' & <angle> "d" こんにちは 4919
    item <4920> & "co"'q' & <angle> "d" こんにちは 4920
    item <4921> & "co"'q' & <angle> "d" こんにちは 4921
    item <4922> & "co"'q' & <angle> "d" こんにちは 4922
    item <4923> & "co"'q' & <angle> "d" こんにちは 4923
    item <4924> & "co"'q' & <angle> "d" こんにちは 4924
    item <4925> & "co"'q' & <angle> "d" こんにちは 4925
    item <4926> & "co"'q' & <angle> "d" こんにちは 4926
    item <4927> & "co"'q' & <angle> "d" こんにちは 4927
    item <4928> & "co"'q' & <angle> "d" こんにちは 4928
    item <4929> & "co"'q' & <angle> "d" こんにちは 4929
    item <4930> & "co"'q' & <angle> "d" こんにちは 4930
    item <4931> & "co"'q' & <angle> "d" こんにちは 4931
    item <4932> & "co"'q' & <angle> "d" こんにちは 4932
    item <4933> & "co"'q' & <angle> "d" こんにちは 4933
    item <4934> & "co"'q' & <angle> "d" こんにちは 4934
    item <4935> & "co"'q' & <angle> "d" こんにちは 4935
    item <4936> & "co"'q' & <angle> "d" こんにちは 4936
    item <4937> & "co"'q' & <angle> "d" こんにちは 4937
    item <4938> & "co"'q' & <angle> "d" こんにちは 4938
    item <4939> & "co"'q' & <angle> "d" こんにちは 4939
    item <4940> & "co"'q' & <angle> "d" こんにちは 4940
    item <4941> & "co"'q' & <angle> "d" こんにちは 4941
    item <4942> & "co"'q' & <angle> "d" こんにちは 4942
    item <4943> & "co"'q' & <angle> "d" こんにちは 4943
    item <4944> & "co"'q' & <angle> "d" こんにちは 4944
    item <4945> & "co"'q' & <angle> "d" こんにちは 4945
    item <4946> & "co"'q' & <angle> "d" こんにちは 4946
    item <4947> & "co"'q' & <angle> "d" こんにちは 4947
    item <4948> & "co"'q' & <angle> "d" こんにちは 4948
    item <4949> & "co"'q' & <angle> "d" こんにちは 4949
    item <4950> & "co"'q' & <angle> "d" こんにちは 4950
    item <4951> & "co"'q' & <angle> "d" こんにちは 4951
    item <4952> & "co"'q' & <angle> "d" こんにちは 4952
    item <4953> & "co"'q' & <angle> "d" こんにちは 4953
    item <4954> & "co"'q' & <angle> "d" こんにちは 4954
    item <4955> & "co"'q' & <angle> "d" こんにちは 4955
    item <4956> & "co"'q' & <angle> "d" こんにちは 4956
    item <4957> & "co"'q' & <angle> "d" こんにちは 4957
    item <4958> & "co"'q' & <angle> "d" こんにちは 4958
    item <4959> & "co"'q' & <angle> "d" こんにちは 4959
    item <4960> & "co"'q' & <angle> "d" こんにちは 4960
    item <4961> & "co"'q' & <angle> "d" こんにちは 4961
    item <4962> & "co"'q' & <angle> "d" こんにちは 4962
    item <4963> & "co"'q' & <angle> "d" こんにちは 4963
    item <4964> & "co"'q' & <angle> "d" こんにちは 4964
    item <4965> & "co"'q' & <angle> "d" こんにちは 4965
    item <4966> & "co"'q' & <angle> "d" こんにちは 4966
    item <4967> & "co"'q' & <angle> "d" こんにちは 4967
    item <4968> & "co"'q' & <angle> "d" こんにちは 4968
    item <4969> & "co"'q' & <angle> "d" こんにちは 4969
    item <4970> & "co"'q' & <angle> "d" こんにちは 4970
    item <4971> & "co"'q' & <angle> "d" こんにちは 4971
    item <4972> & "co"'q' & <angle> "d" こんにちは 4972
    item <4973> & "co"'q' & <angle> "d" こんにちは 4973
    item <4974> & "co"'q' & <angle> "d" こんにちは 4974
    item <4975> & "co"'q' & <angle> "d" こんにちは 4975
    item <4976> & "co"'q' & <angle> "d" こんにちは 4976
    item <4977> & "co"'q' & <angle> "d" こんにちは 4977
    item <4978> & "co"'q' & <angle> "d" こんにちは 4978
    item <4979> & "co"'q' & <angle> "d" こんにちは 4979
    item <4980> & "co"'q' & <angle> "d" こんにちは 4980
    item <4981> & "co"'q' & <angle> "d" こんにちは 4981
    item <4982> & "co"'q' & <angle> "d" こんにちは 4982
    item <4983> & "co"'q' & <angle> "d" こんにちは 4983
    item <4984> & "co"'q' & <angle> "d" こんにちは 4984
    item <4985> & "co"'q' & <angle> "d" こんにちは 4985
    item <4986> & "co"'q' & <angle> "d" こんにちは 4986
    item <4987> & "co"'q' & <angle> "d" こんにちは 4987
    item <4988> & "co"'q' & <angle> "d" こんにちは 4988
    item <4989> & "co"'q' & <angle> "d" こんにちは 4989
    item <4990> & "co"'q' & <angle> "d" こんにちは 4990
    item <4991> & "co"'q' & <angle> "d" こんにちは 4991
    item <4992> & "co"'q' & <angle> "d" こんにちは 4992
    item <4993> & "co"'q' & <angle> "d" こんにちは 4993
    item <4994> & "co"'q' & <angle> "d" こんにちは 4994
    item <4995> & "co"'q' & <angle> "d" こんにちは 4995
    item <4996> & "co"'q' & <angle> "d" こんにちは 4996
    item <4997> & "co"'q' & <angle> "d" こんにちは 4997
    item <4998> & "co"'q' & <angle> "d" こんにちは 4998
    item <4999> & "co"'q' & <angle> "d" こんにちは 4999
    \ No newline at end of file diff --git a/benchmarks/dotnet/GoldenCorpus/encoded-loop.verify.json b/benchmarks/dotnet/GoldenCorpus/encoded-loop.verify.json new file mode 100644 index 00000000..d64a1ad8 --- /dev/null +++ b/benchmarks/dotnet/GoldenCorpus/encoded-loop.verify.json @@ -0,0 +1,17 @@ +{ + "workload": "encoded-loop", + "suite": "encoded", + "values": [ + { "text": "tag-0&'0'", "count": 1 }, + { "text": "item <4999> &", "count": 1 }, + { "text": "alert(", ""], + "required": [{ "text": "<angle>", "minCount": 5000 }] +} diff --git a/benchmarks/dotnet/GoldenCorpus/fixtures/composed-page/nav.json b/benchmarks/dotnet/GoldenCorpus/fixtures/composed-page/nav.json new file mode 100644 index 00000000..67af5c68 --- /dev/null +++ b/benchmarks/dotnet/GoldenCorpus/fixtures/composed-page/nav.json @@ -0,0 +1,955 @@ +{ + "menus": [ + { + "tabs": [ + { + "label": "Shop All Products", + "href": "#", + "css": "shop-all-products", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "FISH", + "href": "", + "title_linked": false, + "links": [ + { "label": "Salmon", "href": "/products/wild-salmon" }, + { "label": "Halibut", "href": "/products/wild-alaskan-halibut" }, + { "label": "Cod", "href": "/products/wild-alaskan-cod" }, + { "label": "Sablefish", "href": "/products/wild-alaskan-sablefish-aka-black-cod-butterfish" }, + { "label": "Tuna", "href": "/products/wild-tuna" }, + { "label": "Smoked Fish and Lox", "href": "/products/smoked-fish-and-lox" }, + { "label": "Sausage, Burgers and Bacon", "href": "/products/wild-salmon-sausage-bacon-and-burgers" }, + { "label": "Petrale Sole", "href": "/product/wild-petrale-sole-portions-4-6-oz-1-lb-bags" } + ] + }, + { + "title": "SHELLFISH", + "href": "/products/wild-and-eco-grown-shellfish", + "title_linked": true, + "links": [ + { "label": "Scallops", "href": "/products/wild-sea-scallops" }, + { "label": "Clams, Oysters and Mussels", "href": "/products/cultured-shellfish-mussels-clams-oysters" }, + { "label": "Wild Shrimp", "href": "/product/oregon-pink-shrimp-cooked" }, + { "label": "Spot Prawns", "href": "/products/wild-pacific-spot-prawns" }, + { "label": "Crab", "href": "/products/crab" }, + { "label": "Lobster", "href": "/products/wild-maine-lobster" }, + { "label": "Calamari", "href": "/product/wild-pacific-calamari-8-oz" }, + { "label": "See All", "href": "/products/wild-and-eco-grown-shellfish" } + ] + }, + { + "title": "MEAT", + "href": "", + "title_linked": false, + "links": [ + { "label": "Pork - coming soon", "href": "/product/coming-soon-paleo-pork" }, + { "label": "Grass-Fed Bison", "href": "/products/grass-fed-bison" }, + { "label": "Grass Fed Beef", "href": "/products/organic-grass-fed-beef-by-skagit-river-ranch" }, + { "label": "Heritage Chicken", "href": "/products/heritage-chicken" }, + { "label": "Bone Broth", "href": "/products/bone-broth-fish-chicken-and-beef" }, + { "label": "Burgers and Hotdogs: Fish and Meat", "href": "/products/burgers-and-hot-dogs" } + ] + } + ] + }, + { + "sections": [ + { + "title": "CANNED AND POUCHED", + "href": "/products/canned-and-pouched-wild-seafood", + "title_linked": true, + "links": [ + { "label": "Salmon", "href": "/products/wild-canned-sockeye-salmon" }, + { "label": "Sardines", "href": "/products/canned-wild-portuguese-sardines-bone-in-and-fillets" }, + { "label": "Tuna", "href": "/products/canned-and-pouched-tuna" }, + { "label": "Anchovies", "href": "/products/anchovies" }, + { "label": "Shrimp", "href": "/products/wild-oregon-tiny-pink-shrimp" }, + { "label": "Crab", "href": "/products/canned-wild-pacific-dungeness-crab" }, + { "label": "Mackerel", "href": "/products/canned-wild-portuguese-mackerel" }, + { "label": "Mussels", "href": "/products/smoked-mussels-cultured" }, + { "label": "Canned Samplers", "href": "/products/canned-wild-seafood-samplers" }, + { "label": "See All", "href": "/products/canned-and-pouched-wild-seafood" } + ] + }, + { + "title": "ORGANIC FOODS AND SEASONINGS", + "href": "/products/organic-food-meat-and-poultry", + "title_linked": true, + "links": [ + { "label": "Broth, Soups and Meals", "href": "/products/meals-broth-and-soups-organic-and-natural" }, + { "label": "Frozen Berries", "href": "/products/organic-berries-frozen" }, + { "label": "Oils and Vinegars", "href": "/products/organic-oils-and-vinegar" }, + { "label": "Garlic, Marinades and Seasonings", "href": "/products/organic-marinade-rub-mixes-and-seasonings" }, + { "label": "Natural Jerky - Salmon and Bison", "href": "/products/natural-jerky" }, + { "label": "Dried Fruit", "href": "/products/organic-dried-fruits" }, + { "label": "Chocolate", "href": "/products/organic-extra-dark-chocolate" }, + { "label": "Trail Mix", "href": "/products/organic-trail-mix" }, + { "label": "Seaweed and Kelp", "href": "/products/seaweed-salad-and-kelp-cubes" }, + { "label": "See All", "href": "/products/organic-food-meat-and-poultry" } + ] + } + ] + }, + { + "sections": [ + { + "title": "OMEGA-3s AND SUPPLEMENTS", + "href": "/products/omega-3s-herbs-tests-vitamin-d-and-astaxanthin", + "title_linked": true, + "links": [ + { "label": "Omega-3 Wild Salmon Oil", "href": "/products/omega-3-wild-salmon-oil-supplements" }, + { "label": "Vitamin D3 + Omega-3 Combos", "href": "/products/vitamin-d3-omega-3-combos" }, + { "label": "High DHA Brain Care Therapy", "href": "/product/high-dha-brain-care-vitamin-d3" }, + { "label": "Daily Dose Packs", "href": "/products/daily-supplement-packs" }, + { "label": "Omega-3 Krill Oil", "href": "/products/omega-3-krill-oil" }, + { "label": "Vital Omega-3/6 Test Kit", "href": "/products/vital-omega-3-6-hufa-test" }, + { "label": "Curcumin in Wild Salmon Oil", "href": "/product/curcumin-in-wild-alaskan-salmon-oil-250mg-120-ct" }, + { "label": "See All", "href": "/products/omega-3s-herbs-tests-vitamin-d-and-astaxanthin" } + ] + }, + { + "title": "SAMPLERS AND GIFT PACKS", + "href": "", + "title_linked": false, + "links": [ + { "label": "Samplers", "href": "/products/samplers" }, + { "label": "Health Advisor Packs", "href": "/products/health-advisors-packs" }, + { "label": "Pet Treats", "href": "/products/pet-products" }, + { "label": "Healthy Mom and Baby", "href": "/content/healthy-mom-baby" }, + { "label": "Doctors Favorites", "href": "/products/doctors-favorites" }, + { "label": "All Gifts and Packs", "href": "/products/gift-packs-and-certificates" }, + { "label": "Gift Certificates", "href": "/products/gift-certificates" } + ] + }, + { + "title": "COOKS TOOLS AND BOOKS", + "href": "", + "title_linked": false, + "links": [ + { "label": "Gift Certificates", "href": "/product/vital-choice-gift-certificate?cat=278" }, + { "label": "Cooks Tools and Books", "href": "/products/cookbooks-and-cooking-accessories" }, + { "label": "Grilling Accessories", "href": "/products/grilling-accessories" } + ] + } + ] + }, + { + "sections": [ + { + "title": "SPECIAL OFFERS / VALUE PICKS", + "href": "/products/special-offers", + "title_linked": true, + "links": [] + }, + { + "title": "NEW PRODUCTS", + "href": "/products/new-at-vital-choice", + "title_linked": true, + "links": [] + }, + { + "title": "TOP SELLERS", + "href": "/products/top-sellers", + "title_linked": true, + "links": [] + }, + { + "title": "RANDYS PICKS", + "href": "/products/randy-s-picks", + "title_linked": true, + "links": [] + }, + { + "title": "GIFT CERTIFICATES", + "href": "/products/gift-certificates", + "title_linked": true, + "links": [] + } + ] + } + ] + }, + { + "label": "Wild Salmon", + "href": "#", + "css": "wild-salmon", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "Wild Salmon", + "href": "/products/wild-salmon", + "title_linked": true, + "links": [ + { "label": "Wild Alaskan Sockeye Salmon", "href": "/products/wild-alaskan-sockeye-salmon" }, + { "label": "Arctic Keta", "href": "/products/artic-keta-salmon" }, + { "label": "Wild Pacific King Salmon", "href": "/products/wild-pacific-king-salmon" }, + { "label": "Wild Alaskan Silver Salmon", "href": "/products/wild-alaskan-silver-salmon" }, + { "label": "Wild Salmon Samplers", "href": "/products/wild-salmon-samplers" }, + { "label": "Seared Sockeye Salmon (Tataki)", "href": "/products/seared-sockeye-salmon-tataki" }, + { "label": "Ikura Wild Salmon Caviar", "href": "/products/ikura-wild-salmon-caviar" }, + { "label": "Wild Salmon Jerky Strips", "href": "/products/wild-salmon-jerky-strips" } + ] + } + ] + }, + { + "sections": [ + { + "title": "WILD CANNED SOCKEYE SALMON", + "href": "/products/wild-canned-sockeye-salmon", + "title_linked": true, + "links": [] + }, + { + "title": "SAUSAGE, BACON, AND BURGERS", + "href": "/products/wild-salmon-sausage-bacon-and-burgers", + "title_linked": true, + "links": [] + }, + { + "title": "SMOKED FISH AND LOX", + "href": "/products/smoked-fish-and-lox", + "title_linked": true, + "links": [] + }, + { + "title": "OMEGA-3 WILD SALMON OIL", + "href": "/products/omega-3-wild-salmon-oil-supplements", + "title_linked": true, + "links": [] + } + ] + } + ] + }, + { + "label": "Supplements", + "href": "#", + "css": "supplements", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "OMEGA-3S AND SUPPLEMENTS", + "href": "/products/omega-3s-herbs-tests-vitamin-d-and-astaxanthin", + "title_linked": true, + "links": [ + { "label": "Omega-3 Wild Salmon Oil", "href": "/products/omega-3-wild-salmon-oil-supplements" }, + { "label": "Vitamin D3 + Omega-3 Combos", "href": "/products/vitamin-d3-omega-3-combos" }, + { "label": "High DHA Brain Care Therapy", "href": "/product/high-dha-prenatal-therapy-vitamin-d3-180-softgels" }, + { "label": "Daily Dose Packs", "href": "/products/daily-supplement-packs" }, + { "label": "Omega-3 Krill Oil", "href": "/products/omega-3-krill-oil" }, + { "label": "Vital Omega-3/6 Test Kit", "href": "/products/vital-omega-3-6-hufa-test" }, + { "label": "Curcumin in Wild Salmon Oil", "href": "/product/curcumin-in-wild-alaskan-salmon-oil-250mg-120-ct" }, + { "label": "See All", "href": "/products/omega-3s-herbs-tests-vitamin-d-and-astaxanthin" } + ] + } + ] + } + ] + }, + { + "label": "About Vital Choice", + "href": "#", + "css": "about-vital-choice", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "WHO WE ARE: OUR STORY", + "href": "", + "title_linked": false, + "links": [ + { "label": "About Vital Choice", "href": "/content/about-vital-choice" }, + { "label": "Our Mission", "href": "/content/our-mission" }, + { "label": "Customer and Expert Reviews", "href": "/content/what-are-people-saying-about-vital-choice" } + ] + } + ] + }, + { + "sections": [ + { + "title": "WHY WE ARE DIFFERENT", + "href": "", + "title_linked": false, + "links": [ + { "label": "Purity Standards", "href": "/content/purity-story" }, + { "label": "Vital Green Eco Programs", "href": "/content/vital-green-environmental-stewardship-program" }, + { "label": "Sustainable Seafood", "href": "/content/sustainability" } + ] + } + ] + }, + { + "sections": [ + { + "title": "WHAT WE BELIEVE", + "href": "", + "title_linked": false, + "links": [ + { "label": "A Letter from Randy Hartnell", "href": "/content/a-letter-from-randy-hartnell" }, + { "label": "Randys Podcasts", "href": "/content/the-antidote-podcast-series" }, + { "label": "Giving Back", "href": "/content/giving-back-to-the-community" } + ] + } + ] + } + ] + }, + { + "label": "Learn", + "href": "#", + "css": "learn", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "RECOMMENDED READING", + "href": "", + "title_linked": false, + "links": [ + { "label": "Newsletter Sign-up", "href": "/content/newsletter-sign-up" }, + { "label": "Newsletter Articles Archive", "href": "/articles/" }, + { "label": "FAQs", "href": "/faqs" } + ] + } + ] + }, + { + "sections": [ + { + "title": "HEALTH AND NUTRITION", + "href": "", + "title_linked": false, + "links": [ + { "label": "Take the Vital Omega-3/6 Test", "href": "/product/the-vital-omega-3-6-hufa-test-trade" }, + { "label": "Omega-3 Facts", "href": "/content/omega-3-facts-sources" }, + { "label": "Seafood Benefits", "href": "/content/health-benefits-of-fish" }, + { "label": "Omega 3/6 Balance", "href": "/content/omega-3-6-balance-scores-how-to-use-them" }, + { "label": "Healthy Mom and Baby", "href": "/content/healthy-mom-baby" } + ] + } + ] + }, + { + "sections": [ + { + "title": "ABOUT VITAL CHOICE PRODUCTS", + "href": "", + "title_linked": false, + "links": [ + { "label": "How to Prepare Seafood", "href": "/content/cooking-tips" }, + { "label": "Kosher and Organic Certification", "href": "/content/about-vital-choice#Organic" }, + { "label": "The Flash-Frozen Advantage", "href": "/content/about-vital-choice#Flash-Frozen" }, + { "label": "Seafood Purity and Safety", "href": "/content/purity-story" }, + { "label": "Superior Salmon, Naturally", "href": "/content/about-vital-choice#Superior%20Salmon" } + ] + } + ] + } + ] + }, + { + "label": "Cook", + "href": "#", + "css": "cook", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "COOKING VIDEOS", + "href": "/recipe/vital-choice-seafood-cooking-videos", + "title_linked": true, + "links": [] + }, + { + "title": "CELEBRITY CHEF VIDEOS", + "href": "", + "title_linked": false, + "links": [ + { "label": "Becky Selengut", "href": "/recipes/becky-selengut" }, + { "label": "Myra Kornfeld", "href": "/recipes/myra-kornfeld" }, + { "label": "Rebecca Katz", "href": "/recipes/rebecca-katz" } + ] + } + ] + }, + { + "sections": [ + { + "title": "RECIPES BY CATEGORY", + "href": "", + "title_linked": false, + "links": [ + { "label": "Salmon", "href": "/recipes/wild-salmon" }, + { "label": "Shellfish", "href": "/recipes/shellfish" }, + { "label": "Grass Fed Beef", "href": "/recipes/grass-fed-beef" }, + { "label": "Chicken", "href": "/recipes/heritage-chicken" }, + { "label": "See All Recipes", "href": "/content/in-the-kitchen" } + ] + } + ] + }, + { + "sections": [ + { + "title": "SEAFOOD HOW-TO VIDEOS", + "href": "", + "title_linked": false, + "links": [ + { "label": "How-to Broil Salmon", "href": "/recipe/how-to-broil-salmon" }, + { "label": "How-to Saute Salmon", "href": "/recipe/how-to-saut-salmon" }, + { "label": "How-to Clean Spot Prawns", "href": "/recipe/how-to-clean-spot-prawns" }, + { "label": "See All Videos", "href": "/content/in-the-kitchen" } + ] + }, + { + "title": "GUIDE: HOW-TO PREPARE SEAFOOD", + "href": "/content/cooking-tips", + "title_linked": true, + "links": [] + }, + { + "title": "SEE ALL RECIPES AND VIDEOS", + "href": "/content/in-the-kitchen", + "title_linked": true, + "links": [] + } + ] + } + ] + } + ] + }, + { + "tabs": [ + { + "label": "Shop All Products", + "href": "#", + "css": "shop-all-products", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "FISH", + "href": "", + "title_linked": false, + "links": [ + { "label": "Salmon", "href": "/products/wild-salmon" }, + { "label": "Halibut", "href": "/products/wild-alaskan-halibut" }, + { "label": "Cod", "href": "/products/wild-alaskan-cod" }, + { "label": "Sablefish", "href": "/products/wild-alaskan-sablefish-aka-black-cod-butterfish" }, + { "label": "Tuna", "href": "/products/wild-tuna" }, + { "label": "Smoked Fish and Lox", "href": "/products/smoked-fish-and-lox" }, + { "label": "Sausages,Dogs, Burgers and Bacon", "href": "/products/wild-salmon-sausage-bacon-and-burgers" }, + { "label": "Petrale Sole", "href": "/product/wild-petrale-sole-portions-4-6-oz-1-lb-bags" } + ] + }, + { + "title": "SHELLFISH", + "href": "/products/wild-and-eco-grown-shellfish", + "title_linked": true, + "links": [ + { "label": "Scallops", "href": "/products/wild-sea-scallops" }, + { "label": "Clams, Oysters and Mussels", "href": "/products/cultured-shellfish-mussels-clams-oysters" }, + { "label": "Wild Shrimp", "href": "/product/oregon-pink-shrimp-cooked" }, + { "label": "Spot Prawns", "href": "/products/wild-pacific-spot-prawns" }, + { "label": "Crab", "href": "/products/crab" }, + { "label": "Lobster", "href": "/products/wild-maine-lobster" }, + { "label": "Calamari", "href": "/product/wild-pacific-calamari-8-oz" }, + { "label": "See All", "href": "/products/wild-and-eco-grown-shellfish" } + ] + }, + { + "title": "MEAT", + "href": "", + "title_linked": false, + "links": [ + { "label": "Paleo-Friendly Pork", "href": "/products/paleo-friendly-pork" }, + { "label": "Grass-Fed Bison", "href": "/products/grass-fed-bison" }, + { "label": "Grass Fed Beef", "href": "/products/organic-grass-fed-beef-by-skagit-river-ranch" }, + { "label": "Heritage Chicken", "href": "/products/heritage-chicken" }, + { "label": "Bone Broth", "href": "/products/bone-broth-fish-chicken-and-beef" }, + { "label": "Burgers and Hotdogs: Fish and Meat", "href": "/products/burgers-and-hot-dogs" } + ] + } + ] + }, + { + "sections": [ + { + "title": "CANNED AND POUCHED", + "href": "/products/canned-and-pouched-wild-seafood", + "title_linked": true, + "links": [ + { "label": "Salmon", "href": "/products/wild-canned-sockeye-salmon" }, + { "label": "Sardines", "href": "/products/canned-wild-portuguese-sardines-bone-in-and-fillets" }, + { "label": "Tuna", "href": "/products/canned-and-pouched-tuna" }, + { "label": "Anchovies", "href": "/products/anchovies" }, + { "label": "Shrimp", "href": "/products/wild-oregon-tiny-pink-shrimp" }, + { "label": "Crab", "href": "/products/canned-wild-pacific-dungeness-crab" }, + { "label": "Mackerel", "href": "/products/canned-wild-portuguese-mackerel" }, + { "label": "Mussels", "href": "/products/smoked-mussels-cultured" }, + { "label": "Canned Samplers", "href": "/products/canned-wild-seafood-samplers" }, + { "label": "See All", "href": "/products/canned-and-pouched-wild-seafood" } + ] + }, + { + "title": "ORGANIC FOODS AND SEASONINGS", + "href": "/products/organic-food-meat-and-poultry", + "title_linked": true, + "links": [ + { "label": "Broth, Soups and Meals", "href": "/products/meals-broth-and-soups-organic-and-natural" }, + { "label": "Frozen Berries", "href": "/products/organic-berries-frozen" }, + { "label": "Oils and Vinegars", "href": "/products/organic-oils-and-vinegar" }, + { "label": "Garlic, Marinades and Seasonings", "href": "/products/organic-marinade-rub-mixes-and-seasonings" }, + { "label": "Natural Jerky - Salmon and Bison", "href": "/products/natural-jerky" }, + { "label": "Dried Fruit", "href": "/products/organic-dried-fruits" }, + { "label": "Chocolate", "href": "/products/organic-extra-dark-chocolate" }, + { "label": "Trail Mix", "href": "/products/organic-trail-mix" }, + { "label": "Seaweed and Kelp", "href": "/products/seaweed-salad-and-kelp-cubes" }, + { "label": "See All", "href": "/products/organic-food-meat-and-poultry" } + ] + } + ] + }, + { + "sections": [ + { + "title": "OMEGA-3s AND SUPPLEMENTS", + "href": "/products/omega-3s-herbs-tests-vitamin-d-and-astaxanthin", + "title_linked": true, + "links": [ + { "label": "Omega-3 Wild Salmon Oil", "href": "/products/omega-3-wild-salmon-oil-supplements" }, + { "label": "Vitamin D3 + Omega-3 Combos", "href": "/products/vitamin-d3-omega-3-combos" }, + { "label": "High DHA Brain Care Therapy", "href": "/product/high-dha-brain-care-vitamin-d3" }, + { "label": "Daily Dose Packs", "href": "/products/daily-supplement-packs" }, + { "label": "Omega-3 Krill Oil", "href": "/products/omega-3-krill-oil" }, + { "label": "Vital Omega-3/6 Test Kit", "href": "/products/vital-omega-3-6-hufa-test" }, + { "label": "Curcumin in Wild Salmon Oil", "href": "/product/curcumin-in-wild-alaskan-salmon-oil-250mg-120-ct" }, + { "label": "See All", "href": "/products/omega-3s-herbs-tests-vitamin-d-and-astaxanthin" } + ] + }, + { + "title": "SAMPLERS AND GIFT PACKS", + "href": "", + "title_linked": false, + "links": [ + { "label": "Samplers", "href": "/products/samplers" }, + { "label": "Health Advisor Packs", "href": "/products/health-advisors-packs" }, + { "label": "Pet Treats", "href": "/products/pet-products" }, + { "label": "Healthy Mom and Baby", "href": "/content/healthy-mom-baby" }, + { "label": "Doctors Favorites", "href": "/products/doctors-favorites" }, + { "label": "All Gifts and Packs", "href": "/products/gift-packs-and-certificates" }, + { "label": "Gift Certificates", "href": "/products/gift-certificates" } + ] + }, + { + "title": "COOKS TOOLS AND BOOKS", + "href": "", + "title_linked": false, + "links": [ + { "label": "Gift Certificates", "href": "/product/vital-choice-gift-certificate?cat=278" }, + { "label": "Cooks Tools and Books", "href": "/products/cookbooks-and-cooking-accessories" }, + { "label": "Grilling Accessories", "href": "/products/grilling-accessories" } + ] + } + ] + }, + { + "sections": [ + { + "title": "SPECIAL OFFERS / VALUE PICKS", + "href": "/products/special-offers", + "title_linked": true, + "links": [] + }, + { + "title": "NEW PRODUCTS", + "href": "/products/new-at-vital-choice", + "title_linked": true, + "links": [] + }, + { + "title": "TOP SELLERS", + "href": "/products/top-sellers", + "title_linked": true, + "links": [] + }, + { + "title": "RANDYS PICKS", + "href": "/products/randy-s-picks", + "title_linked": true, + "links": [] + }, + { + "title": "GIFT CERTIFICATES", + "href": "/products/gift-certificates", + "title_linked": true, + "links": [] + } + ] + } + ] + }, + { + "label": "Wild Salmon", + "href": "#", + "css": "wild-salmon", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "Wild Salmon", + "href": "/products/wild-salmon", + "title_linked": true, + "links": [ + { "label": "Wild Alaskan Sockeye Salmon", "href": "/products/wild-alaskan-sockeye-salmon" }, + { "label": "Arctic Keta", "href": "/products/artic-keta-salmon" }, + { "label": "Wild Pacific King Salmon", "href": "/products/wild-pacific-king-salmon" }, + { "label": "Wild Alaskan Silver Salmon", "href": "/products/wild-alaskan-silver-salmon" }, + { "label": "Wild Salmon Samplers", "href": "/products/wild-salmon-samplers" }, + { "label": "Seared Sockeye Salmon (Tataki)", "href": "/products/seared-sockeye-salmon-tataki" }, + { "label": "Ikura Wild Salmon Caviar", "href": "/products/ikura-wild-salmon-caviar" }, + { "label": "Coming Soon: Wild Salmon Dogs", "href": "/products/wild-salmon-hot-dogs" } + ] + } + ] + }, + { + "sections": [ + { + "title": "WILD SALMON SAMPLERS", + "href": "/products/wild-salmon-samplers", + "title_linked": true, + "links": [] + }, + { + "title": "WILD CANNED SOCKEYE SALMON", + "href": "/products/wild-canned-sockeye-salmon", + "title_linked": true, + "links": [] + }, + { + "title": "SAUSAGE, BACON, AND BURGERS", + "href": "/products/wild-salmon-sausage-bacon-and-burgers", + "title_linked": true, + "links": [] + }, + { + "title": "SMOKED FISH AND LOX", + "href": "/products/smoked-fish-and-lox", + "title_linked": true, + "links": [] + }, + { + "title": "OMEGA-3 WILD SALMON OIL", + "href": "/products/omega-3-wild-salmon-oil-supplements", + "title_linked": true, + "links": [] + } + ] + } + ] + }, + { + "label": "Supplements", + "href": "#", + "css": "supplements", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "OMEGA-3S AND SUPPLEMENTS", + "href": "/products/omega-3s-herbs-tests-vitamin-d-and-astaxanthin", + "title_linked": true, + "links": [ + { "label": "Omega-3 Wild Salmon Oil", "href": "/products/omega-3-wild-salmon-oil-supplements" }, + { "label": "Vitamin D3 + Omega-3 Combos", "href": "/products/vitamin-d3-omega-3-combos" }, + { "label": "High DHA Brain Care Therapy", "href": "/product/high-dha-prenatal-therapy-vitamin-d3-180-softgels" }, + { "label": "Daily Dose Packs", "href": "/products/daily-supplement-packs" }, + { "label": "Omega-3 Krill Oil", "href": "/products/omega-3-krill-oil" }, + { "label": "Vital Omega-3/6 Test Kit", "href": "/products/vital-omega-3-6-hufa-test" }, + { "label": "Curcumin in Wild Salmon Oil", "href": "/product/curcumin-in-wild-alaskan-salmon-oil-250mg-120-ct" }, + { "label": "See All", "href": "/products/omega-3s-herbs-tests-vitamin-d-and-astaxanthin" } + ] + } + ] + } + ] + }, + { + "label": "About Vital Choice", + "href": "#", + "css": "about-vital-choice", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "WHO WE ARE: OUR STORY", + "href": "", + "title_linked": false, + "links": [ + { "label": "About Vital Choice", "href": "/content/about-vital-choice" }, + { "label": "Our Mission", "href": "/content/our-mission" }, + { "label": "Customer and Expert Reviews", "href": "/content/what-are-people-saying-about-vital-choice" } + ] + } + ] + }, + { + "sections": [ + { + "title": "WHY WE ARE DIFFERENT", + "href": "", + "title_linked": false, + "links": [ + { "label": "Purity Standards", "href": "/content/purity-story" }, + { "label": "Vital Green Eco Programs", "href": "/content/vital-green-environmental-stewardship-program" }, + { "label": "Sustainable Seafood", "href": "/content/sustainability" } + ] + } + ] + }, + { + "sections": [ + { + "title": "WHAT WE BELIEVE", + "href": "", + "title_linked": false, + "links": [ + { "label": "A Letter from Randy Hartnell", "href": "/content/a-letter-from-randy-hartnell" }, + { "label": "Randys Podcasts", "href": "/content/the-antidote-podcast-series" }, + { "label": "Giving Back", "href": "/content/giving-back-to-the-community" } + ] + } + ] + } + ] + }, + { + "label": "Learn", + "href": "#", + "css": "learn", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "RECOMMENDED READING", + "href": "", + "title_linked": false, + "links": [ + { "label": "Newsletter Sign-up", "href": "/content/newsletter-sign-up" }, + { "label": "Newsletter Articles Archive", "href": "/articles/" }, + { "label": "FAQs", "href": "/faqs" } + ] + } + ] + }, + { + "sections": [ + { + "title": "HEALTH AND NUTRITION", + "href": "", + "title_linked": false, + "links": [ + { "label": "Take the Vital Omega-3/6 Test", "href": "/product/the-vital-omega-3-6-hufa-test-trade" }, + { "label": "Omega-3 Facts", "href": "/content/omega-3-facts-sources" }, + { "label": "Seafood Benefits", "href": "/content/health-benefits-of-fish" }, + { "label": "Omega 3/6 Balance", "href": "/content/omega-3-6-balance-scores-how-to-use-them" }, + { "label": "Healthy Mom and Baby", "href": "/content/healthy-mom-baby" } + ] + } + ] + }, + { + "sections": [ + { + "title": "ABOUT VITAL CHOICE PRODUCTS", + "href": "", + "title_linked": false, + "links": [ + { "label": "How to Prepare Seafood", "href": "/content/cooking-tips" }, + { "label": "Kosher and Organic Certification", "href": "/content/about-vital-choice#Organic" }, + { "label": "The Flash-Frozen Advantage", "href": "/content/about-vital-choice#Flash-Frozen" }, + { "label": "Seafood Purity and Safety", "href": "/content/purity-story" }, + { "label": "Superior Salmon, Naturally", "href": "/content/about-vital-choice#Superior%20Salmon" } + ] + } + ] + } + ] + }, + { + "label": "Cook", + "href": "#", + "css": "cook", + "has_dropdown": true, + "dropdown_css": "dropdown_2columns", + "columns": [ + { + "sections": [ + { + "title": "COOKING VIDEOS", + "href": "/recipe/vital-choice-seafood-cooking-videos", + "title_linked": true, + "links": [] + }, + { + "title": "CELEBRITY CHEF VIDEOS", + "href": "", + "title_linked": false, + "links": [ + { "label": "Becky Selengut", "href": "/recipes/becky-selengut" }, + { "label": "Myra Kornfeld", "href": "/recipes/myra-kornfeld" }, + { "label": "Rebecca Katz", "href": "/recipes/rebecca-katz" } + ] + } + ] + }, + { + "sections": [ + { + "title": "RECIPES BY CATEGORY", + "href": "", + "title_linked": false, + "links": [ + { "label": "Salmon", "href": "/recipes/wild-salmon" }, + { "label": "Shellfish", "href": "/recipes/shellfish" }, + { "label": "Grass Fed Beef", "href": "/recipes/grass-fed-beef" }, + { "label": "Chicken", "href": "/recipes/heritage-chicken" }, + { "label": "See All Recipes", "href": "/content/in-the-kitchen" } + ] + } + ] + }, + { + "sections": [ + { + "title": "SEAFOOD HOW-TO VIDEOS", + "href": "", + "title_linked": false, + "links": [ + { "label": "How-to Broil Salmon", "href": "/recipe/how-to-broil-salmon" }, + { "label": "How-to Saute Salmon", "href": "/recipe/how-to-saut-salmon" }, + { "label": "How-to Clean Spot Prawns", "href": "/recipe/how-to-clean-spot-prawns" }, + { "label": "See All Videos", "href": "/content/in-the-kitchen" } + ] + }, + { + "title": "GUIDE: HOW-TO PREPARE SEAFOOD", + "href": "/content/cooking-tips", + "title_linked": true, + "links": [] + }, + { + "title": "SEE ALL RECIPES AND VIDEOS", + "href": "/content/in-the-kitchen", + "title_linked": true, + "links": [] + } + ] + } + ] + } + ] + } + ], + "footer_columns": [ + { + "sections": [ + { + "title": "Need Help?", + "href": "", + "title_linked": false, + "links": [ + { "label": "Customer Service", "href": "/content/contact-customer-service" }, + { "label": "Request a Catalog", "href": "/content/request-catalog" }, + { "label": "Customer Rewards", "href": "/content/HealthWise-Rewards-Program" }, + { "label": "Returns and Exchanges", "href": "/content/the-vital-choice-guarantee" }, + { "label": "Shipping Information", "href": "/content/shipping-information" } + ] + } + ] + }, + { + "sections": [ + { + "title": "Our Company", + "href": "", + "title_linked": false, + "links": [ + { "label": "About Us", "href": "/content/About-Vital-Choice" }, + { "label": "Guarantee", "href": "/content/the-vital-choice-guarantee" }, + { "label": "Testimonials", "href": "/content/what-are-people-saying-about-vital-choice" }, + { "label": "Purity Standards", "href": "/content/Purity-Story" }, + { "label": "Sustainability Policy", "href": "/content/Sustainability" }, + { "label": "Vital Green", "href": "/content/Vital-Green-Environmental-Stewardship-Program" }, + { "label": "News Room", "href": "/content/News-Room" }, + { "label": "Giving Back", "href": "/content/Giving-Back-to-the-Community" }, + { "label": "Privacy Policy", "href": "/content/privacy-policy" }, + { "label": "Careers", "href": "/content/Careers" } + ] + } + ] + }, + { + "sections": [ + { + "title": "Programs", + "href": "", + "title_linked": false, + "links": [ + { "label": "Affiliate Accounts", "href": "/content/Web-Affiliate-Program" }, + { "label": "Customer Rewards", "href": "/content/HealthWise-Rewards-Program" }, + { "label": "Wholesale Accounts", "href": "/content/wholesale-registration" } + ] + } + ] + }, + { + "sections": [ + { + "title": "Learn", + "href": "", + "title_linked": false, + "links": [ + { "label": "FAQs", "href": "/faqs" }, + { "label": "Recipes", "href": "/content/in-the-kitchen" }, + { "label": "Seafood Cooking Tips", "href": "/content/Seafood-Storage-Cooking-Tips" }, + { "label": "Newsletter Archive", "href": "/articles" }, + { "label": "Healthy Mom and Baby", "href": "/content/Healthy-Mom-Baby" }, + { "label": "Seafood Health Benefits", "href": "/content/Health-Benefits-of-Fish" }, + { "label": "Omega-3 Facts and Sources", "href": "/content/omega-3-facts-sources" } + ] + } + ] + } + ] +} diff --git a/benchmarks/dotnet/GoldenCorpus/fortunes-encoded.golden.html b/benchmarks/dotnet/GoldenCorpus/fortunes-encoded.golden.html new file mode 100644 index 00000000..771dd763 --- /dev/null +++ b/benchmarks/dotnet/GoldenCorpus/fortunes-encoded.golden.html @@ -0,0 +1 @@ +Fortunes
    idmessage
    1A bad random number generator: 1, 1, 1, 1, 1, 4.33e67, 1, 1, 1
    2A computer program does what you tell it to do, not what you want it to do.
    3A computer scientist is someone who fixes things that aren't broken.
    4A list is only as strong as its weakest link. — Donald Knuth
    5After enough decimal places, nobody gives a damn.
    6Any program that runs right is obsolete.
    7Computers make very fast, very accurate mistakes.
    8Emacs is a nice operating system, but I prefer UNIX. — Tom Christiansen
    9Feature: A bug with seniority.
    10fortune: No such file or directory
    11<script>alert("This should not be displayed in a browser alert box.");</script>
    12フレームワークのベンチマーク
    \ No newline at end of file diff --git a/benchmarks/dotnet/GoldenCorpus/fortunes-encoded.verify.json b/benchmarks/dotnet/GoldenCorpus/fortunes-encoded.verify.json new file mode 100644 index 00000000..29221fd5 --- /dev/null +++ b/benchmarks/dotnet/GoldenCorpus/fortunes-encoded.verify.json @@ -0,0 +1,29 @@ +{ + "workload": "fortunes-encoded", + "suite": "encoded", + "values": [ + { "text": "A bad random number generator: 1, 1, 1, 1, 1, 4.33e67, 1, 1, 1", "count": 1 }, + { "text": "A computer program does what you tell it to do, not what you want it to do.", "count": 1 }, + { "text": "A computer scientist is someone who fixes things that aren", "count": 1 }, + { "text": "A list is only as strong as its weakest link. — Donald Knuth", "count": 1 }, + { "text": "After enough decimal places, nobody gives a damn.", "count": 1 }, + { "text": "Any program that runs right is obsolete.", "count": 1 }, + { "text": "Computers make very fast, very accurate mistakes.", "count": 1 }, + { "text": "Emacs is a nice operating system, but I prefer UNIX. — Tom Christiansen", "count": 1 }, + { "text": "Feature: A bug with seniority.", "count": 1 }, + { "text": "fortune: No such file or directory", "count": 1 }, + { "text": "<script>alert(", "count": 1 }, + { "text": ");</script>", "count": 1 }, + { "text": "フレームワークのベンチマーク", "count": 1 }, + { "text": "", "count": 12 } + ], + "markers": [ + "", + "", + "", + "フレームワークのベンチマーク", + "
    idmessage
    " + ], + "forbidden": ["", // the body_end_scripts fragment + "", + }; + + return new Authored + { + Definition = Def("composed-page", "raw", + values: new[] + { + V(sectionMeta, 1), + // Every nav link renders exactly one of these (mega menus + footer). + V("
  • ", totalColumns), + // The first footer column's title — proves the footer rendered. + V("Need Help?", 1), + V(privacyNeedle, 1), + }, + markers: markers), + // Delete the spliced slider body (an empty idiomatic body must FAIL); swap the + // wholesale-only and retail-only mega anchors. Both trip the ordered-markers check. + RemovedSegment = sliderSegment, + RemovedKind = "marker", + SwapA = wholesaleAnchor, + SwapB = retailAnchor, + }; + } + + private static Authored TrivialSubstitution() => new Authored + { + Definition = Def("trivial-substitution", "raw", + values: new[] + { + V("Heddle Handbook", 1), + V("HB-2001", 1), + V("A concise field guide to the engine.", 1), + V("4.8", 1), + }, + markers: new[] { "
    ", "

    ", "class=\"sku\"", "class=\"rating\"", "

    " }), + RemovedSegment = "HB-2001", + RemovedKind = "value", + SwapA = "class=\"sku\"", + SwapB = "class=\"rating\"", + }; + + private static Authored LargeLoop() => new Authored + { + Definition = Def("large-loop", "raw", + values: new[] + { + V("row-00", 1), + V("row-49994999", 1), + V("row-", 5000), + }, + markers: new[] { "row-0", "row-2500", "row-4999" }), + RemovedSegment = "row-00", + RemovedKind = "value", + SwapA = "row-00", + SwapB = "row-25002500", + }; + + private static Authored MixedPage() => new Authored + { + Definition = Def("mixed-page", "raw", + values: new[] + { + V("Mercantile - Catalog", 1), + V("Autumn hardware sale", 1), + V("Product 01", 1), + V("Product 36", 1), + V("MX-1036", 1), + V("
    ", 36), + V("

    On sale

    ", 12), + V("Free shipping on orders over 60.", 1), + }, + markers: new[] + { + "", "
    ", "class=\"hero\"", "class=\"grid\"", "
  • - @area_component(@"Alert Top Section Above Nav") + @alert_top()
    @@ -102,18 +107,17 @@
    - @area_component(@"Wholesale Top Mega Menu") - @area_component(@"Retail Top Mega Menu") + @list(Nav.Menus){{@mega_menu()}}
  • - @area_component(@"Alert Top Section Below Nav") + @alert_below()
    - @body() + @out()
    @@ -121,7 +125,7 @@
    - @assets_component(@"scripts") + @assets_scripts() @page_scripts() @endpage_scripts() @body_end_scripts() - \ No newline at end of file +}} :: ComposedModel +%@ diff --git a/src/Heddle.Performance/TestTemplates/trivial-substitution.heddle b/benchmarks/dotnet/templates/controlled/heddle/trivial-substitution.heddle similarity index 100% rename from src/Heddle.Performance/TestTemplates/trivial-substitution.heddle rename to benchmarks/dotnet/templates/controlled/heddle/trivial-substitution.heddle diff --git a/benchmarks/dotnet/templates/controlled/liquid/composed-page.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/composed-page.dotliquid.liquid new file mode 100644 index 00000000..7df6e084 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/composed-page.dotliquid.liquid @@ -0,0 +1,13 @@ +{% capture body_content %} +
    +
    +
    +
    +
    + + + +
    +
    +
    +{% endcapture %}{% include 'layout' %} diff --git a/benchmarks/dotnet/templates/controlled/liquid/composed-page.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/composed-page.fluid.liquid new file mode 100644 index 00000000..7df6e084 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/composed-page.fluid.liquid @@ -0,0 +1,13 @@ +{% capture body_content %} +
    +
    +
    +
    +
    + + + +
    +
    +
    +{% endcapture %}{% include 'layout' %} diff --git a/benchmarks/dotnet/templates/controlled/liquid/conditional-heavy.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/conditional-heavy.dotliquid.liquid new file mode 100644 index 00000000..70263a3d --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/conditional-heavy.dotliquid.liquid @@ -0,0 +1 @@ +
      {% for r in rows %}
    • {% if r.is_bronze %}bronze{% elsif r.is_silver %}silver{% elsif r.is_gold %}gold{% else %}platinum{% endif %}{{ r.name }}{% if r.has_note %}note {{ r.seq }}{% endif %}{% if r.is_active %}active{% endif %}
    • {% endfor %}
    diff --git a/benchmarks/dotnet/templates/controlled/liquid/conditional-heavy.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/conditional-heavy.fluid.liquid new file mode 100644 index 00000000..70263a3d --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/conditional-heavy.fluid.liquid @@ -0,0 +1 @@ +
      {% for r in rows %}
    • {% if r.is_bronze %}bronze{% elsif r.is_silver %}silver{% elsif r.is_gold %}gold{% else %}platinum{% endif %}{{ r.name }}{% if r.has_note %}note {{ r.seq }}{% endif %}{% if r.is_active %}active{% endif %}
    • {% endfor %}
    diff --git a/benchmarks/dotnet/templates/controlled/liquid/encoded-loop.liquid b/benchmarks/dotnet/templates/controlled/liquid/encoded-loop.liquid new file mode 100644 index 00000000..0f24ee55 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/encoded-loop.liquid @@ -0,0 +1 @@ +{% for item in items %}{% endfor %}
    {{ item.name | escape }}{{ item.comment | escape }}
    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/fortunes-encoded.liquid b/benchmarks/dotnet/templates/controlled/liquid/fortunes-encoded.liquid new file mode 100644 index 00000000..00a4af8c --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/fortunes-encoded.liquid @@ -0,0 +1 @@ +Fortunes{% for r in rows %}{% endfor %}
    idmessage
    {{ r.id }}{{ r.message | escape }}
    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/fragment-heavy.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/fragment-heavy.dotliquid.liquid new file mode 100644 index 00000000..788425a8 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/fragment-heavy.dotliquid.liquid @@ -0,0 +1 @@ +
    {% for item in items %}{% if item.is_tile %}{% include 'tile' %}{% elsif item.is_card %}{% include 'card' %}{% elsif item.is_media %}{% include 'media-row' %}{% else %}{% include 'stat' %}{% endif %}{% endfor %}
    diff --git a/benchmarks/dotnet/templates/controlled/liquid/fragment-heavy.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/fragment-heavy.fluid.liquid new file mode 100644 index 00000000..ca96a613 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/fragment-heavy.fluid.liquid @@ -0,0 +1 @@ +
    {% for item in items %}{% if item.is_tile %}{% include 'tile' with item %}{% elsif item.is_card %}{% include 'card' with item %}{% elsif item.is_media %}{% include 'media-row' with item %}{% else %}{% include 'stat' with item %}{% endif %}{% endfor %}
    diff --git a/benchmarks/dotnet/templates/controlled/liquid/large-loop.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/large-loop.dotliquid.liquid new file mode 100644 index 00000000..5e6b9a65 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/large-loop.dotliquid.liquid @@ -0,0 +1 @@ +{% for item in items %}row-{{ item.value }}{{ item.value }}{% endfor %} diff --git a/benchmarks/dotnet/templates/controlled/liquid/large-loop.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/large-loop.fluid.liquid new file mode 100644 index 00000000..5e6b9a65 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/large-loop.fluid.liquid @@ -0,0 +1 @@ +{% for item in items %}row-{{ item.value }}{{ item.value }}{% endfor %} diff --git a/benchmarks/dotnet/templates/controlled/liquid/mixed-page.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/mixed-page.dotliquid.liquid new file mode 100644 index 00000000..d145e169 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/mixed-page.dotliquid.liquid @@ -0,0 +1 @@ +{{ page_title }}

    {{ store_name }}

    {% if show_banner %}{% endif %}

    {{ hero_heading }}

    {{ hero_tagline }}

    {% for p in products %}

    {{ p.name }}

    MX-{{ p.sku_number }}

    {{ p.price }}

    {% if p.on_sale %}

    On sale

    {% endif %}

    A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

    {% endfor %}
    {% if show_debug_panel %}
    debug
    {% endif %}

    {{ footer_note }}

    {{ store_name }} {{ year }} {{ support_email }}

    diff --git a/benchmarks/dotnet/templates/controlled/liquid/mixed-page.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/mixed-page.fluid.liquid new file mode 100644 index 00000000..d145e169 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/mixed-page.fluid.liquid @@ -0,0 +1 @@ +{{ page_title }}

    {{ store_name }}

    {% if show_banner %}{% endif %}

    {{ hero_heading }}

    {{ hero_tagline }}

    {% for p in products %}

    {{ p.name }}

    MX-{{ p.sku_number }}

    {{ p.price }}

    {% if p.on_sale %}

    On sale

    {% endif %}

    A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

    {% endfor %}
    {% if show_debug_panel %}
    debug
    {% endif %}

    {{ footer_note }}

    {{ store_name }} {{ year }} {{ support_email }}

    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/alert-below.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/alert-below.dotliquid.liquid new file mode 100644 index 00000000..b0dac656 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/alert-below.dotliquid.liquid @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/alert-below.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/alert-below.fluid.liquid new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/alert-top.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/alert-top.dotliquid.liquid new file mode 100644 index 00000000..2abc9bf1 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/alert-top.dotliquid.liquid @@ -0,0 +1 @@ +
    holiday shipping
    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/alert-top.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/alert-top.fluid.liquid new file mode 100644 index 00000000..d889f879 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/alert-top.fluid.liquid @@ -0,0 +1 @@ +
    holiday shipping
    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/assets-scripts.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/assets-scripts.dotliquid.liquid new file mode 100644 index 00000000..e47cda12 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/assets-scripts.dotliquid.liquid @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/assets-scripts.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/assets-scripts.fluid.liquid new file mode 100644 index 00000000..bf801bb9 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/assets-scripts.fluid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/assets-styles.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/assets-styles.dotliquid.liquid new file mode 100644 index 00000000..cb6751d3 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/assets-styles.dotliquid.liquid @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/assets-styles.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/assets-styles.fluid.liquid new file mode 100644 index 00000000..28df0356 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/assets-styles.fluid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/badge.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/badge.dotliquid.liquid new file mode 100644 index 00000000..9dd928bf --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/badge.dotliquid.liquid @@ -0,0 +1 @@ +{{ item.promo.label }} diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/badge.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/badge.fluid.liquid new file mode 100644 index 00000000..7a10b2c6 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/badge.fluid.liquid @@ -0,0 +1 @@ +{{ badge.label }} diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/body-end-scripts.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/body-end-scripts.dotliquid.liquid new file mode 100644 index 00000000..4a28491d --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/body-end-scripts.dotliquid.liquid @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/body-end-scripts.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/body-end-scripts.fluid.liquid new file mode 100644 index 00000000..51c5f27e --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/body-end-scripts.fluid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/body-scripts.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/body-scripts.dotliquid.liquid new file mode 100644 index 00000000..cb28a558 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/body-scripts.dotliquid.liquid @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/body-scripts.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/body-scripts.fluid.liquid new file mode 100644 index 00000000..7bcf90f9 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/body-scripts.fluid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/card.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/card.dotliquid.liquid new file mode 100644 index 00000000..ef4ec4d6 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/card.dotliquid.liquid @@ -0,0 +1 @@ +

    {{ item.name }}

    {% include 'badge' %}{% include 'price' %}

    {{ item.value }}

    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/card.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/card.fluid.liquid new file mode 100644 index 00000000..7f8b37f6 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/card.fluid.liquid @@ -0,0 +1 @@ +

    {{ card.name }}

    {% include 'badge' with card.promo %}{% include 'price' with card.promo %}

    {{ card.value }}

    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/custom-styles.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/custom-styles.dotliquid.liquid new file mode 100644 index 00000000..f635c77f --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/custom-styles.dotliquid.liquid @@ -0,0 +1 @@ +/* CSS Comment Test */ \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/custom-styles.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/custom-styles.fluid.liquid new file mode 100644 index 00000000..c03f73c5 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/custom-styles.fluid.liquid @@ -0,0 +1 @@ +/* CSS Comment Test */ diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/head-scripts.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/head-scripts.dotliquid.liquid new file mode 100644 index 00000000..879142ca --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/head-scripts.dotliquid.liquid @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/head-scripts.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/head-scripts.fluid.liquid new file mode 100644 index 00000000..35f0ac9a --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/head-scripts.fluid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/layout.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/layout.dotliquid.liquid new file mode 100644 index 00000000..53066132 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/layout.dotliquid.liquid @@ -0,0 +1,126 @@ + + + + + + + + + + Title + + + + + + + + + {% include 'assets-styles' %} + + {% include 'head-scripts' %} + + + {% include 'body-scripts' %} +
    +
    + +
    +
    +
    +
    + {% include 'alert-top' %} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + {% for menu in nav.menus %}{% include 'mega-menu' %}{% endfor %} +
    +
    +
    + {% include 'alert-below' %} +
    +
    + {{ body_content }} +
    +
    +
    +
    +
    + +
    +
    + {% include 'assets-scripts' %} + + {% include 'body-end-scripts' %} + + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/layout.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/layout.fluid.liquid new file mode 100644 index 00000000..d0f2c7f1 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/layout.fluid.liquid @@ -0,0 +1,126 @@ + + + + + + + + + + Title + + + + + + + + + {% include 'assets-styles' %} + + {% include 'head-scripts' %} + + + {% include 'body-scripts' %} +
    +
    + +
    +
    +
    +
    + {% include 'alert-top' %} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + {% for menu in nav.menus %}{% include 'mega-menu' with menu %}{% endfor %} +
    +
    +
    + {% include 'alert-below' %} +
    +
    + {{ body_content }} +
    +
    +
    +
    +
    + +
    +
    + {% include 'assets-scripts' %} + + {% include 'body-end-scripts' %} + + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/media-row.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/media-row.dotliquid.liquid new file mode 100644 index 00000000..caab49f1 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/media-row.dotliquid.liquid @@ -0,0 +1 @@ +
    {{ item.name }}

    {{ item.name }}

    Caption for {{ item.name }}

    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/media-row.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/media-row.fluid.liquid new file mode 100644 index 00000000..9da25049 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/media-row.fluid.liquid @@ -0,0 +1 @@ +
    {{ media-row.name }}

    {{ media-row.name }}

    Caption for {{ media-row.name }}

    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/mega-menu.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/mega-menu.dotliquid.liquid new file mode 100644 index 00000000..53eaf45d --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/mega-menu.dotliquid.liquid @@ -0,0 +1 @@ +
      {% for tab in menu.tabs %}
    • {{ tab.label }}{% if tab.has_dropdown %}
      {% for column in tab.columns %}{% include 'nav-column' %}{% endfor %}
      {% endif %}
    • {% endfor %}
    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/mega-menu.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/mega-menu.fluid.liquid new file mode 100644 index 00000000..c68871a2 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/mega-menu.fluid.liquid @@ -0,0 +1 @@ +
      {% for tab in mega-menu.tabs %}
    • {{ tab.label }}{% if tab.has_dropdown %}
      {% for column in tab.columns %}{% include 'nav-column' with column %}{% endfor %}
      {% endif %}
    • {% endfor %}
    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/nav-column.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-column.dotliquid.liquid new file mode 100644 index 00000000..944526b2 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-column.dotliquid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/nav-column.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-column.fluid.liquid new file mode 100644 index 00000000..2927aa6a --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-column.fluid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/nav-link.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-link.dotliquid.liquid new file mode 100644 index 00000000..b07a3c05 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-link.dotliquid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/nav-link.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-link.fluid.liquid new file mode 100644 index 00000000..39ccd8e2 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-link.fluid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/nav-section.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-section.dotliquid.liquid new file mode 100644 index 00000000..38ef4f3e --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-section.dotliquid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/nav-section.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-section.fluid.liquid new file mode 100644 index 00000000..9ac81bca --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/nav-section.fluid.liquid @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/price.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/price.dotliquid.liquid new file mode 100644 index 00000000..bba5bedf --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/price.dotliquid.liquid @@ -0,0 +1 @@ +

    {{ item.promo.price }}.99

    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/price.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/price.fluid.liquid new file mode 100644 index 00000000..1c795bf1 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/price.fluid.liquid @@ -0,0 +1 @@ +

    {{ price.price }}.99

    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-retail-menu.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-retail-menu.dotliquid.liquid new file mode 100644 index 00000000..cc0390b5 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-retail-menu.dotliquid.liquid @@ -0,0 +1,116 @@ + \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-retail-menu.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-retail-menu.fluid.liquid new file mode 100644 index 00000000..cbdfa51a --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-retail-menu.fluid.liquid @@ -0,0 +1,116 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-wholesale-menu.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-wholesale-menu.dotliquid.liquid new file mode 100644 index 00000000..471ab31c --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-wholesale-menu.dotliquid.liquid @@ -0,0 +1,138 @@ + \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-wholesale-menu.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-wholesale-menu.fluid.liquid new file mode 100644 index 00000000..12bab348 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/secondary-wholesale-menu.fluid.liquid @@ -0,0 +1,138 @@ + diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/stat.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/stat.dotliquid.liquid new file mode 100644 index 00000000..c7e0e140 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/stat.dotliquid.liquid @@ -0,0 +1 @@ +
    {{ item.name }}{{ item.value }}{{ item.delta }}
    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/stat.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/stat.fluid.liquid new file mode 100644 index 00000000..16eb04ba --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/stat.fluid.liquid @@ -0,0 +1 @@ +
    {{ stat.name }}{{ stat.value }}{{ stat.delta }}
    diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/tile.dotliquid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/tile.dotliquid.liquid new file mode 100644 index 00000000..5fcf1396 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/tile.dotliquid.liquid @@ -0,0 +1 @@ +

    {{ item.name }}

    {{ item.value }}

    {{ item.badge }}
    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/shared/tile.fluid.liquid b/benchmarks/dotnet/templates/controlled/liquid/shared/tile.fluid.liquid new file mode 100644 index 00000000..397b741a --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/shared/tile.fluid.liquid @@ -0,0 +1 @@ +

    {{ tile.name }}

    {{ tile.value }}

    {{ tile.badge }}
    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/liquid/trivial-substitution.liquid b/benchmarks/dotnet/templates/controlled/liquid/trivial-substitution.liquid new file mode 100644 index 00000000..372f7f69 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/liquid/trivial-substitution.liquid @@ -0,0 +1 @@ +

    {{ title }}

    {{ sku }}

    {{ price }}

    {{ brand }}

    {{ category }}

    {{ availability }}

    {{ summary }}

    {{ rating }}

    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/badge.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/badge.cshtml new file mode 100644 index 00000000..f01697aa --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/badge.cshtml @@ -0,0 +1,8 @@ +@* + Razor parity twin -- fragment-heavy badge sub-partial. + + Nested by the card partial against the row's Promo. Html.Raw: raw-suite non-encoding path. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentPromo +@Html.Raw(Model.Label) diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/card.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/card.cshtml new file mode 100644 index 00000000..d0337cb7 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/card.cshtml @@ -0,0 +1,10 @@ +@* + Razor parity twin -- fragment-heavy card partial. + + One of the four dispatched fragment kinds, and the one that NESTS: it renders the badge + and price partials against the row's Promo, mirroring Heddle's `@badge(Promo)@price(Promo)`. + Html.Raw: raw-suite non-encoding path. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentRow +

    @Html.Raw(Model.Name)

    @await Html.PartialAsync("/Views/Shared/badge.cshtml", Model.Promo)@await Html.PartialAsync("/Views/Shared/price.cshtml", Model.Promo)

    @Model.Value

    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/composed-page-layout.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/composed-page-layout.cshtml new file mode 100644 index 00000000..10717dfa --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/composed-page-layout.cshtml @@ -0,0 +1,399 @@ +@* + Razor parity twin -- composed-page layout. + + A genuine full-page layout with a LIVE body slot: Razor's native Layout/@RenderBody + mechanism, mirroring Heddle's layout-as-definition idiom (layout.heddle's @out() slot). + The inert chrome fragments -- the alert banner, the two secondary menus, the fixed + asset/script snippets -- are literal template text transcribed from + templates/controlled/heddle/{layout,chrome-fragments}.heddle (all display text + lives in templates; the C# tier carries only model DATA). The structured navigation + renders from ComposedModel.Nav through nested loops and partials + (menu -> column -> section -> link), the composition shape pinned for every + engine. The transcribed chrome contains no literal '@', so no @@ escapes were + needed. Whitespace is free -- N3b strips every whitespace run from both sides before + the byte comparison. + + Html.Raw for the nav string values: the raw suite renders every engine's non-encoding + path, same discipline as the other twins' triple-mustache / no-escape-filter forms. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model ComposedModel + + + + + + + + + + Title + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    holiday shipping
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + @foreach (var menu in Model.Nav.Menus) + {@await Html.PartialAsync("/Views/Shared/mega-menu.cshtml", menu)} +
    +
    +
    +
    +
    + @RenderBody() +
    +
    +
    +
    +
    + +
    +
    + + + + + diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/media-row.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/media-row.cshtml new file mode 100644 index 00000000..f9d48991 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/media-row.cshtml @@ -0,0 +1,11 @@ +@* + Razor parity twin -- fragment-heavy media-row partial. + + One of the four dispatched fragment kinds. The image source (`/img/@(Model.Name).jpg`) and + the caption (`Caption for @Model.Name`) are composed by the TEMPLATE as + literal-plus-substitution -- the model carries data, never display strings. + Html.Raw: raw-suite non-encoding path. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentRow +
    @Html.Raw(Model.Name)

    @Html.Raw(Model.Name)

    Caption for @Html.Raw(Model.Name)

    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/mega-menu.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/mega-menu.cshtml new file mode 100644 index 00000000..2a8730e7 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/mega-menu.cshtml @@ -0,0 +1,13 @@ +@* + Razor parity twin -- composed-page mega-menu partial. + + One mega menu: the tab loop with the per-tab dropdown, each dropdown column rendered + through the nested nav-column partial (menu -> column -> section -> link), mirroring + Heddle's mega_menu definition. Html.Raw: raw-suite non-encoding path. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model MegaMenu +
      @foreach (var tab in Model.Tabs) +{
    • @Html.Raw(tab.Label)@if (tab.HasDropdown) + {
      @foreach (var column in tab.Columns) + {@await Html.PartialAsync("/Views/Shared/nav-column.cshtml", column)}
      }
    • }
    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/nav-column.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/nav-column.cshtml new file mode 100644 index 00000000..31763fd5 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/nav-column.cshtml @@ -0,0 +1,11 @@ +@* + Razor parity twin -- composed-page nav-column partial. + + One navigation column: the section loop rendered through the nested nav-section partial, + mirroring Heddle's nav_column definition. Shared by the mega-menu dropdowns and the + footer nav. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model NavColumn + diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/nav-link.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/nav-link.cshtml new file mode 100644 index 00000000..0d7c6732 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/nav-link.cshtml @@ -0,0 +1,9 @@ +@* + Razor parity twin -- composed-page nav-link partial. + + One navigation link, mirroring Heddle's nav_link definition. Html.Raw: raw-suite + non-encoding path. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model NavLink + diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/nav-section.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/nav-section.cshtml new file mode 100644 index 00000000..8775a0b1 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/nav-section.cshtml @@ -0,0 +1,14 @@ +@* + Razor parity twin -- composed-page nav-section partial. + + One navigation section: the (pre-computed) TitleLinked branch and the link loop rendered + through the nested nav-link partial, mirroring Heddle's nav_section definition. + Html.Raw: raw-suite non-encoding path. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model NavSection + diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/price.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/price.cshtml new file mode 100644 index 00000000..88ce6117 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/price.cshtml @@ -0,0 +1,10 @@ +@* + Razor parity twin -- fragment-heavy price sub-partial. + + Nested by the card partial against the row's Promo. The display price is composed by the + TEMPLATE as literal-plus-substitution (`@(Model.Price).99`): formatting is rendering + work, not model work. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentPromo +

    @(Model.Price).99

    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/stat.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/stat.cshtml new file mode 100644 index 00000000..3e016c29 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/stat.cshtml @@ -0,0 +1,8 @@ +@* + Razor parity twin -- fragment-heavy stat partial. + + One of the four dispatched fragment kinds. Html.Raw: raw-suite non-encoding path. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentRow +
    @Html.Raw(Model.Name)@Model.Value@Model.Delta
    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/Shared/tile.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/tile.cshtml new file mode 100644 index 00000000..b55bb3a3 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/Shared/tile.cshtml @@ -0,0 +1,8 @@ +@* + Razor parity twin -- fragment-heavy tile partial. + + One of the four dispatched fragment kinds. Html.Raw: raw-suite non-encoding path. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentRow +

    @Html.Raw(Model.Name)

    @Model.Value

    @Html.Raw(Model.Badge)
    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/composed-page.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/composed-page.cshtml new file mode 100644 index 00000000..62656950 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/composed-page.cshtml @@ -0,0 +1,24 @@ +@* + Razor parity twin -- composed-page. + + The page is Razor's native composition: it names the layout and its markup body splices + at the layout's single mid-page @RenderBody() -- a LIVE body slot, mirroring Heddle's + home.heddle (`@<<{{layout.heddle}}` + `@layout(){{ ...slider... }}` splicing at @out()). + The slider body is the verifier's removed-segment calibration pin, so an empty body fails. + Whitespace is free -- N3b strips every whitespace run from both sides before the byte + comparison. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model ComposedModel +@{ Layout = "/Views/Shared/composed-page-layout.cshtml"; } +
    +
    +
    +
    +
    + + + +
    +
    +
    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/conditional-heavy.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/conditional-heavy.cshtml new file mode 100644 index 00000000..c8bf3655 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/conditional-heavy.cshtml @@ -0,0 +1,27 @@ +@* + Razor parity twin -- conditional-heavy (the template composes `note @(r.Seq)` -- + the model carries the int only). + + Razor is now measured on ALL EIGHT workloads. It previously existed for composed-page only, + which meant the repository's "faster than Razor" claim rested on the single least favourable + workload in the set. An engine with one workload does not belong in a cross-stack table. + + Every value comes from the shared PUBLIC fixtures under src/Models/, the same objects every + other engine reads, so this twin cannot drift from the engine it is compared against. Its + predecessor did drift -- it carried a hand-duplicated 56 KB copy of the area dictionary that had + diverged unnoticed -- precisely because nothing compared the two. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model ConditionalContent.ConditionalModel +@{ Layout = null; } +
      @foreach (var r in Model.Rows) +{
    • @if (r.IsBronze) + {bronze} + else if (r.IsSilver) + {silver} + else if (r.IsGold) + {gold} + else + {platinum}@Html.Raw(r.Name)@if (r.HasNote) + {note @r.Seq}@if (r.IsActive) + {active}
    • }
    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/encoded-loop.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/encoded-loop.cshtml new file mode 100644 index 00000000..e5185bcb --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/encoded-loop.cshtml @@ -0,0 +1,20 @@ +@* + Razor parity twin -- encoded-loop. + + Razor is now measured on ALL EIGHT workloads. It previously existed for composed-page only, + which meant the repository's "faster than Razor" claim rested on the single least favourable + workload in the set. An engine with one workload does not belong in a cross-stack table. + + Every value comes from the shared PUBLIC fixtures under src/Models/, the same objects every + other engine reads, so this twin cannot drift from the engine it is compared against. Its + predecessor did drift -- it carried a hand-duplicated 56 KB copy of the area dictionary that had + diverged unnoticed -- precisely because nothing compared the two. + + ENCODED SUITE. Every field goes through Razor's own HtmlEncoder, including the attribute-value + context on data-tag. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model EncodedLoopContent.EncodedLoopModel +@{ Layout = null; } +@foreach (var item in Model.Items) +{}
    @item.Name@item.Comment
    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/fortunes-encoded.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/fortunes-encoded.cshtml new file mode 100644 index 00000000..edd33b35 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/fortunes-encoded.cshtml @@ -0,0 +1,21 @@ +@* + Razor parity twin -- fortunes-encoded. + + Razor is now measured on ALL EIGHT workloads. It previously existed for composed-page only, + which meant the repository's "faster than Razor" claim rested on the single least favourable + workload in the set. An engine with one workload does not belong in a cross-stack table. + + Every value comes from the shared PUBLIC fixtures under src/Models/, the same objects every + other engine reads, so this twin cannot drift from the engine it is compared against. Its + predecessor did drift -- it carried a hand-duplicated 56 KB copy of the area dictionary that had + diverged unnoticed -- precisely because nothing compared the two. + + ENCODED SUITE. The message uses a bare @expression so Razor's own HtmlEncoder escapes it -- + the engine's documented mechanism, measured rather than bypassed. The id is numeric and needs + no escaping either way. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FortunesContent.FortuneModel +@{ Layout = null; } +Fortunes@foreach (var r in Model.Rows) +{}
    idmessage
    @r.Id@r.Message
    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/fragment-heavy.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/fragment-heavy.cshtml new file mode 100644 index 00000000..ecb610f1 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/fragment-heavy.cshtml @@ -0,0 +1,21 @@ +@* + Razor parity twin -- fragment-heavy. + + Per-row fragment DISPATCH plus nested per-call composition: 48 rows, a four-way boolean + if-chain per row (the precomputed IsTile/IsCard/IsMedia/IsStat -- guaranteed + common-denominator dispatch pinned for Razor) selecting which of the four + partial views to invoke; the card partial nests the badge and price partials against the + row's Promo -- the one nesting level. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentModel +@{ Layout = null; } +
    @foreach (var item in Model.Items) +{if (item.IsTile) + {@await Html.PartialAsync("/Views/Shared/tile.cshtml", item)} + else if (item.IsCard) + {@await Html.PartialAsync("/Views/Shared/card.cshtml", item)} + else if (item.IsMedia) + {@await Html.PartialAsync("/Views/Shared/media-row.cshtml", item)} + else + {@await Html.PartialAsync("/Views/Shared/stat.cshtml", item)}}
    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/large-loop.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/large-loop.cshtml new file mode 100644 index 00000000..c6cc893d --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/large-loop.cshtml @@ -0,0 +1,11 @@ +@* + Razor parity twin -- large-loop. + + The display name is composed by the TEMPLATE as literal-plus-substitution + (`row-@(item.Value)`): the model carries the int only. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model LoopContent.LoopModel +@{ Layout = null; } +@foreach (var item in Model.Items) +{row-@item.Value@item.Value} diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/mixed-page.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/mixed-page.cshtml new file mode 100644 index 00000000..1b499ab4 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/mixed-page.cshtml @@ -0,0 +1,22 @@ +@* + Razor parity twin -- mixed-page (the template composes the display SKU + (`MX-@(p.SkuNumber)`) and the blurb sentence around `@p.Batch` -- + the model carries the ints only). + + Razor is now measured on ALL EIGHT workloads. It previously existed for composed-page only, + which meant the repository's "faster than Razor" claim rested on the single least favourable + workload in the set. An engine with one workload does not belong in a cross-stack table. + + Every value comes from the shared PUBLIC fixtures under src/Models/, the same objects every + other engine reads, so this twin cannot drift from the engine it is compared against. Its + predecessor did drift -- it carried a hand-duplicated 56 KB copy of the area dictionary that had + diverged unnoticed -- precisely because nothing compared the two. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model MixedContent.MixedModel +@{ Layout = null; } +@Html.Raw(Model.PageTitle)

    @Html.Raw(Model.StoreName)

    @if (Model.ShowBanner) +{}

    @Html.Raw(Model.HeroHeading)

    @Html.Raw(Model.HeroTagline)

    @foreach (var p in Model.Products) +{

    @Html.Raw(p.Name)

    MX-@p.SkuNumber

    @p.Price

    @if (p.OnSale) +{

    On sale

    }

    A dependable workshop staple from batch @p.Batch, checked for daily use and backed by our lifetime guarantee.

    }
    @if (Model.ShowDebugPanel) +{
    debug
    }

    @Html.Raw(Model.FooterNote)

    @Html.Raw(Model.StoreName) @Model.Year @Html.Raw(Model.SupportEmail)

    diff --git a/benchmarks/dotnet/templates/controlled/razor/Views/trivial-substitution.cshtml b/benchmarks/dotnet/templates/controlled/razor/Views/trivial-substitution.cshtml new file mode 100644 index 00000000..90008fb4 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/razor/Views/trivial-substitution.cshtml @@ -0,0 +1,16 @@ +@* + Razor parity twin -- trivial-substitution. + + Razor is now measured on ALL EIGHT workloads. It previously existed for composed-page only, + which meant the repository's "faster than Razor" claim rested on the single least favourable + workload in the set. An engine with one workload does not belong in a cross-stack table. + + Every value comes from the shared PUBLIC fixtures under src/Models/, the same objects every + other engine reads, so this twin cannot drift from the engine it is compared against. Its + predecessor did drift -- it carried a hand-duplicated 56 KB copy of the area dictionary that had + diverged unnoticed -- precisely because nothing compared the two. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model SubstitutionContent.SubstitutionModel +@{ Layout = null; } +

    @Html.Raw(Model.Title)

    @Html.Raw(Model.Sku)

    @Model.Price

    @Html.Raw(Model.Brand)

    @Html.Raw(Model.Category)

    @Html.Raw(Model.Availability)

    @Html.Raw(Model.Summary)

    @Html.Raw(Model.Rating)

    diff --git a/benchmarks/dotnet/templates/controlled/scriban/composed-page.scriban b/benchmarks/dotnet/templates/controlled/scriban/composed-page.scriban new file mode 100644 index 00000000..9c04b653 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/composed-page.scriban @@ -0,0 +1,13 @@ +{{ capture body_content }} +
    +
    +
    +
    +
    + + + +
    +
    +
    +{{ end }}{{ include 'layout' }} diff --git a/benchmarks/dotnet/templates/controlled/scriban/conditional-heavy.scriban b/benchmarks/dotnet/templates/controlled/scriban/conditional-heavy.scriban new file mode 100644 index 00000000..443562aa --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/conditional-heavy.scriban @@ -0,0 +1 @@ +
      {{ for r in rows }}
    • {{ if r.is_bronze }}bronze{{ else if r.is_silver }}silver{{ else if r.is_gold }}gold{{ else }}platinum{{ end }}{{ r.name }}{{ if r.has_note }}note {{ r.seq }}{{ end }}{{ if r.is_active }}active{{ end }}
    • {{ end }}
    diff --git a/benchmarks/dotnet/templates/controlled/scriban/encoded-loop.scriban b/benchmarks/dotnet/templates/controlled/scriban/encoded-loop.scriban new file mode 100644 index 00000000..73978033 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/encoded-loop.scriban @@ -0,0 +1 @@ +{{ for item in items }}{{ end }}
    {{ item.name | html.escape }}{{ item.comment | html.escape }}
    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/scriban/fortunes-encoded.scriban b/benchmarks/dotnet/templates/controlled/scriban/fortunes-encoded.scriban new file mode 100644 index 00000000..66b58fc6 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/fortunes-encoded.scriban @@ -0,0 +1 @@ +Fortunes{{ for r in rows }}{{ end }}
    idmessage
    {{ r.id }}{{ r.message | html.escape }}
    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/controlled/scriban/fragment-heavy.scriban b/benchmarks/dotnet/templates/controlled/scriban/fragment-heavy.scriban new file mode 100644 index 00000000..4f49d04b --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/fragment-heavy.scriban @@ -0,0 +1 @@ +
    {{ for item in items }}{{ if item.is_tile }}{{ include 'tile' }}{{ else if item.is_card }}{{ include 'card' }}{{ else if item.is_media }}{{ include 'media-row' }}{{ else }}{{ include 'stat' }}{{ end }}{{ end }}
    diff --git a/benchmarks/dotnet/templates/controlled/scriban/large-loop.scriban b/benchmarks/dotnet/templates/controlled/scriban/large-loop.scriban new file mode 100644 index 00000000..53d84822 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/large-loop.scriban @@ -0,0 +1 @@ +{{ for item in items }}row-{{ item.value }}{{ item.value }}{{ end }} diff --git a/benchmarks/dotnet/templates/controlled/scriban/mixed-page.scriban b/benchmarks/dotnet/templates/controlled/scriban/mixed-page.scriban new file mode 100644 index 00000000..b538605e --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/mixed-page.scriban @@ -0,0 +1 @@ +{{ page_title }}

    {{ store_name }}

    {{ if show_banner }}{{ end }}

    {{ hero_heading }}

    {{ hero_tagline }}

    {{ for p in products }}

    {{ p.name }}

    MX-{{ p.sku_number }}

    {{ p.price }}

    {{ if p.on_sale }}

    On sale

    {{ end }}

    A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

    {{ end }}
    {{ if show_debug_panel }}
    debug
    {{ end }}

    {{ footer_note }}

    {{ store_name }} {{ year }} {{ support_email }}

    diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/alert-below.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/alert-below.scriban new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/alert-top.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/alert-top.scriban new file mode 100644 index 00000000..d889f879 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/alert-top.scriban @@ -0,0 +1 @@ +
    holiday shipping
    diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/assets-scripts.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/assets-scripts.scriban new file mode 100644 index 00000000..bf801bb9 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/assets-scripts.scriban @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/assets-styles.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/assets-styles.scriban new file mode 100644 index 00000000..28df0356 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/assets-styles.scriban @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/badge.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/badge.scriban new file mode 100644 index 00000000..9dd928bf --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/badge.scriban @@ -0,0 +1 @@ +{{ item.promo.label }} diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/body-end-scripts.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/body-end-scripts.scriban new file mode 100644 index 00000000..51c5f27e --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/body-end-scripts.scriban @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/body-scripts.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/body-scripts.scriban new file mode 100644 index 00000000..7bcf90f9 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/body-scripts.scriban @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/card.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/card.scriban new file mode 100644 index 00000000..edf4f562 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/card.scriban @@ -0,0 +1 @@ +

    {{ item.name }}

    {{ include 'badge' }}{{ include 'price' }}

    {{ item.value }}

    diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/custom-styles.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/custom-styles.scriban new file mode 100644 index 00000000..c03f73c5 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/custom-styles.scriban @@ -0,0 +1 @@ +/* CSS Comment Test */ diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/head-scripts.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/head-scripts.scriban new file mode 100644 index 00000000..35f0ac9a --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/head-scripts.scriban @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/layout.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/layout.scriban new file mode 100644 index 00000000..210e45fd --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/layout.scriban @@ -0,0 +1,126 @@ + + + + + + + + + + Title + + + + + + + + + {{ include 'assets-styles' }} + + {{ include 'head-scripts' }} + + + {{ include 'body-scripts' }} +
    +
    + +
    +
    +
    +
    + {{ include 'alert-top' }} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + {{ for menu in nav.menus }}{{ include 'mega-menu' }}{{ end }} +
    +
    +
    + {{ include 'alert-below' }} +
    +
    + {{ body_content }} +
    +
    +
    +
    +
    + +
    +
    + {{ include 'assets-scripts' }} + + {{ include 'body-end-scripts' }} + + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/media-row.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/media-row.scriban new file mode 100644 index 00000000..caab49f1 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/media-row.scriban @@ -0,0 +1 @@ +
    {{ item.name }}

    {{ item.name }}

    Caption for {{ item.name }}

    diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/mega-menu.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/mega-menu.scriban new file mode 100644 index 00000000..6f223a6d --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/mega-menu.scriban @@ -0,0 +1 @@ +
      {{ for tab in menu.tabs }}
    • {{ tab.label }}{{ if tab.has_dropdown }}
      {{ for column in tab.columns }}{{ include 'nav-column' }}{{ end }}
      {{ end }}
    • {{ end }}
    diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/nav-column.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/nav-column.scriban new file mode 100644 index 00000000..bef94d83 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/nav-column.scriban @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/nav-link.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/nav-link.scriban new file mode 100644 index 00000000..b07a3c05 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/nav-link.scriban @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/nav-section.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/nav-section.scriban new file mode 100644 index 00000000..116ae313 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/nav-section.scriban @@ -0,0 +1 @@ + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/price.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/price.scriban new file mode 100644 index 00000000..bba5bedf --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/price.scriban @@ -0,0 +1 @@ +

    {{ item.promo.price }}.99

    diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/secondary-retail-menu.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/secondary-retail-menu.scriban new file mode 100644 index 00000000..6c6147b8 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/secondary-retail-menu.scriban @@ -0,0 +1,116 @@ + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/secondary-wholesale-menu.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/secondary-wholesale-menu.scriban new file mode 100644 index 00000000..b80f8830 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/secondary-wholesale-menu.scriban @@ -0,0 +1,138 @@ + diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/stat.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/stat.scriban new file mode 100644 index 00000000..c7e0e140 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/stat.scriban @@ -0,0 +1 @@ +
    {{ item.name }}{{ item.value }}{{ item.delta }}
    diff --git a/benchmarks/dotnet/templates/controlled/scriban/shared/tile.scriban b/benchmarks/dotnet/templates/controlled/scriban/shared/tile.scriban new file mode 100644 index 00000000..35a89004 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/shared/tile.scriban @@ -0,0 +1 @@ +

    {{ item.name }}

    {{ item.value }}

    {{ item.badge }}
    diff --git a/benchmarks/dotnet/templates/controlled/scriban/trivial-substitution.scriban b/benchmarks/dotnet/templates/controlled/scriban/trivial-substitution.scriban new file mode 100644 index 00000000..372f7f69 --- /dev/null +++ b/benchmarks/dotnet/templates/controlled/scriban/trivial-substitution.scriban @@ -0,0 +1 @@ +

    {{ title }}

    {{ sku }}

    {{ price }}

    {{ brand }}

    {{ category }}

    {{ availability }}

    {{ summary }}

    {{ rating }}

    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/composed-page.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/composed-page.hbs new file mode 100644 index 00000000..57dae27b --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/composed-page.hbs @@ -0,0 +1,26 @@ +{{!-- + Idiomatic Handlebars -- composed-page. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +{{#> layout}} +
    +
    +
    +
    +
    + + + +
    +
    +
    +{{/layout}} diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/conditional-heavy.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/conditional-heavy.hbs new file mode 100644 index 00000000..21799edb --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/conditional-heavy.hbs @@ -0,0 +1,25 @@ +{{!-- + Idiomatic Handlebars -- conditional-heavy. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, and registered partials. + Raw triple-mustaches appear only where the value genuinely IS an HTML fragment; plain text goes + through the default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +
      + {{#each rows}} +
    • + {{#if is_bronze}}bronze + {{else if is_silver}}silver + {{else if is_gold}}gold + {{else}}platinum{{/if}} + {{name}} + {{#if has_note}}note {{seq}}{{/if}} + {{#if is_active}}active{{/if}} +
    • + {{/each}} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/encoded-loop.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/encoded-loop.hbs new file mode 100644 index 00000000..0fd56eaa --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/encoded-loop.hbs @@ -0,0 +1,20 @@ +{{!-- + Idiomatic Handlebars -- encoded-loop. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else}}` chains, and registered partials. Raw + triple-mustaches appear only where the value genuinely IS an HTML fragment; plain text goes + through the default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + + {{#each items}} + + + + + {{/each}} +
    {{name}}{{comment}}
    diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/fortunes-encoded.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/fortunes-encoded.hbs new file mode 100644 index 00000000..9880a34a --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/fortunes-encoded.hbs @@ -0,0 +1,24 @@ +{{!-- + Idiomatic Handlebars -- fortunes-encoded. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else}}` chains, and registered partials. Raw + triple-mustaches appear only where the value genuinely IS an HTML fragment; plain text goes + through the default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + + +Fortunes + + + + {{#each rows}} + + {{/each}} +
    idmessage
    {{id}}{{message}}
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/fragment-heavy.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/fragment-heavy.hbs new file mode 100644 index 00000000..bb1fb655 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/fragment-heavy.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- fragment-heavy. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +
    {{#each items}}{{#if is_tile}}{{> tile this}}{{else if is_card}}{{> card this}}{{else if is_media}}{{> media_row this}}{{else}}{{> stat this}}{{/if}}{{/each}}
    diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/large-loop.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/large-loop.hbs new file mode 100644 index 00000000..4174b39f --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/large-loop.hbs @@ -0,0 +1,15 @@ +{{!-- + Idiomatic Handlebars -- large-loop. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else}}` chains, and registered partials. Raw + triple-mustaches appear only where the value genuinely IS an HTML fragment; plain text goes + through the default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +{{#each items}} + row-{{value}}{{value}} +{{/each}} diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/mixed-page.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/mixed-page.hbs new file mode 100644 index 00000000..6d86afb1 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/mixed-page.hbs @@ -0,0 +1,49 @@ +{{!-- + Idiomatic Handlebars -- mixed-page. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else}}` chains, and registered partials. Raw + triple-mustaches appear only where the value genuinely IS an HTML fragment; plain text goes + through the default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + + + + + {{page_title}} + + + +
    +

    {{store_name}}

    + +
    +
    + {{#if show_banner}}{{/if}} +
    +

    {{hero_heading}}

    +

    {{hero_tagline}}

    +
    +
    + {{#each products}} +
    +

    {{name}}

    +

    MX-{{sku_number}}

    +

    {{price}}

    + {{#if on_sale}}

    On sale

    {{/if}} +

    A dependable workshop staple from batch {{batch}}, checked for daily use and backed by our lifetime guarantee.

    +
    + {{/each}} +
    + {{#if show_debug_panel}}
    debug
    {{/if}} +
    +
    +

    {{footer_note}}

    +

    {{store_name}} {{year}} {{support_email}}

    +
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/alert-below.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/alert-below.hbs new file mode 100644 index 00000000..778c1ed3 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/alert-below.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page alert-below chrome fragment (pinned empty). + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/alert-top.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/alert-top.hbs new file mode 100644 index 00000000..6ba30e57 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/alert-top.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page alert-banner chrome fragment. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +
    holiday shipping
    diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/assets-scripts.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/assets-scripts.hbs new file mode 100644 index 00000000..66a4a24c --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/assets-scripts.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page assets_scripts chrome fragment. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/assets-styles.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/assets-styles.hbs new file mode 100644 index 00000000..989602b3 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/assets-styles.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page assets_styles chrome fragment. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/badge.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/badge.hbs new file mode 100644 index 00000000..3138541f --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/badge.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- fragment-heavy badge partial. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +{{label}} diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/body-end-scripts.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/body-end-scripts.hbs new file mode 100644 index 00000000..c3b808a4 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/body-end-scripts.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page body_end_scripts chrome fragment. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/body-scripts.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/body-scripts.hbs new file mode 100644 index 00000000..63b06b16 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/body-scripts.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page body_scripts chrome fragment. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/card.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/card.hbs new file mode 100644 index 00000000..0aa6b8a7 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/card.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- fragment-heavy card partial (nests badge + price). + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +

    {{name}}

    {{> badge promo}}{{> price promo}}

    {{value}}

    diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/custom-styles.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/custom-styles.hbs new file mode 100644 index 00000000..286ea290 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/custom-styles.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page custom_styles chrome fragment. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +/* CSS Comment Test */ diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/endpage-scripts.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/endpage-scripts.hbs new file mode 100644 index 00000000..10fefc38 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/endpage-scripts.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page endpage_scripts section default (empty). + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/head-scripts.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/head-scripts.hbs new file mode 100644 index 00000000..f5341536 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/head-scripts.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page head_scripts chrome fragment. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/layout.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/layout.hbs new file mode 100644 index 00000000..cd74dc05 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/layout.hbs @@ -0,0 +1,139 @@ +{{!-- + Idiomatic Handlebars -- composed-page layout partial. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + + + + + + + + + + {{> meta}} + {{> socialmeta}} + + + + + + {{> assets_styles}} + + {{> head_scripts}} + + + {{> body_scripts}} +
    +
    + +
    +
    +
    +
    + {{> alert_top}} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + {{#each nav.menus}}{{> mega_menu this}}{{/each}} +
    +
    +
    + {{> alert_below}} +
    +
    + {{> @partial-block}} +
    +
    +
    +
    +
    + +
    +
    + {{> assets_scripts}} + + {{> page_scripts}} + {{> endpage_scripts}} + {{> body_end_scripts}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/media-row.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/media-row.hbs new file mode 100644 index 00000000..eb57c49d --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/media-row.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- fragment-heavy media-row partial. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +
    {{name}}

    {{name}}

    Caption for {{name}}

    diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/mega-menu.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/mega-menu.hbs new file mode 100644 index 00000000..a74d77ee --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/mega-menu.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page mega-menu partial. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +
      {{#each tabs}}
    • {{label}}{{#if has_dropdown}}
      {{#each columns}}{{> nav_column this}}{{/each}}
      {{/if}}
    • {{/each}}
    diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/meta.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/meta.hbs new file mode 100644 index 00000000..1c88a504 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/meta.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page meta section default. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +Title diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/nav-column.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/nav-column.hbs new file mode 100644 index 00000000..187e13d6 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/nav-column.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page nav-column partial. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/nav-link.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/nav-link.hbs new file mode 100644 index 00000000..9572652a --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/nav-link.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page nav-link partial. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/nav-section.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/nav-section.hbs new file mode 100644 index 00000000..d0a3145d --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/nav-section.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page nav-section partial. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/page-scripts.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/page-scripts.hbs new file mode 100644 index 00000000..91428134 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/page-scripts.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- composed-page page_scripts section default (empty). + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/price.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/price.hbs new file mode 100644 index 00000000..8a47e977 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/price.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- fragment-heavy price partial. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +

    {{price}}.99

    diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/secondary-retail-menu.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/secondary-retail-menu.hbs new file mode 100644 index 00000000..f811f5c6 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/secondary-retail-menu.hbs @@ -0,0 +1,129 @@ +{{!-- + Idiomatic Handlebars -- composed-page secondary retail menu chrome fragment. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/secondary-wholesale-menu.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/secondary-wholesale-menu.hbs new file mode 100644 index 00000000..3e22fefd --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/secondary-wholesale-menu.hbs @@ -0,0 +1,151 @@ +{{!-- + Idiomatic Handlebars -- composed-page secondary wholesale menu chrome fragment. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/socialmeta.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/socialmeta.hbs new file mode 100644 index 00000000..d3513118 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/socialmeta.hbs @@ -0,0 +1,16 @@ +{{!-- + Idiomatic Handlebars -- composed-page socialmeta section default. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + + + + diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/stat.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/stat.hbs new file mode 100644 index 00000000..851a5ced --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/stat.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- fragment-heavy stat partial. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +
    {{name}}{{value}}{{delta}}
    diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/shared/tile.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/tile.hbs new file mode 100644 index 00000000..36e8b87a --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/shared/tile.hbs @@ -0,0 +1,14 @@ +{{!-- + Idiomatic Handlebars -- fragment-heavy tile partial. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else if}}` chains, partial blocks + (`{{#> layout}}` with `{{> @partial-block}}`), and registered partials. Raw triple-mustaches + appear only where the value genuinely IS an HTML fragment; plain text goes through the + default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +

    {{name}}

    {{value}}

    {{badge}}
    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/idiomatic/handlebars/trivial-substitution.hbs b/benchmarks/dotnet/templates/idiomatic/handlebars/trivial-substitution.hbs new file mode 100644 index 00000000..73da7f10 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/handlebars/trivial-substitution.hbs @@ -0,0 +1,23 @@ +{{!-- + Idiomatic Handlebars -- trivial-substitution. + + Patterns followed, from the engines' own documentation: + Handlebars language https://handlebarsjs.com/guide/ + Handlebars.Net https://github.com/Handlebars-Net/Handlebars.Net#readme + + Uses `{{#each}}` blocks with `this`, `{{#if}}`/`{{else}}` chains, and registered partials. Raw + triple-mustaches appear only where the value genuinely IS an HTML fragment; plain text goes + through the default encoder, which is what the guide teaches. Checked by the functional verifier. +--}} + +
    +

    {{title}}

    +

    {{sku}}

    +

    {{price}}

    +

    {{brand}}

    +

    {{category}}

    +

    {{availability}}

    + +

    {{summary}}

    +

    {{rating}}

    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/composed-page.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/composed-page.heddle new file mode 100644 index 00000000..f3f770c9 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/composed-page.heddle @@ -0,0 +1,29 @@ +@* + Idiomatic Heddle -- composed-page. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md ("Composition without coupling" -- + the layout-as-definition idiom) + Architecture docs/architecture.md + + The page imports the definition-only layout and calls @layout() with the slider body; the + body splices at the layout's @out() slot. The slider content is the SAME as the controlled + track's -- the verifier's calibration pin (RemovedSegment = the slider fragment) fails an + empty body, deliberately. Checked by the functional verifier, not the byte gate. +*@ + +@<<{{shared/layout.heddle}} +@layout() +{{ +
    +
    +
    +
    +
    + + + +
    +
    +
    +}} diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/conditional-heavy.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/conditional-heavy.heddle new file mode 100644 index 00000000..c8a3e3c6 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/conditional-heavy.heddle @@ -0,0 +1,27 @@ +@* + Idiomatic Heddle -- conditional-heavy. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md + Architecture docs/architecture.md + + Authored the way the reference teaches -- readable block layout, definitions declared in the + @%...%@ header, and `@list`/`@if`/`@elif`/`@else` for control flow -- rather than collapsed onto + one line to match the oracle byte-for-byte. Checked by the functional verifier, not the byte + gate. The encoded workloads rely on OutputProfile.Html, where `@(...)` encodes by default and + `@attr(...)` applies attribute-context encoding; nothing here opts out. +*@ + +
      +@list(Rows){{ +
    • + @if(IsBronze){{bronze}} + @elif(IsSilver){{silver}} + @elif(IsGold){{gold}} + @else(){{platinum}} + @(Name) + @if(HasNote){{note @(Seq)}} + @if(IsActive){{active}} +
    • +}} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/encoded-loop.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/encoded-loop.heddle new file mode 100644 index 00000000..e7449cca --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/encoded-loop.heddle @@ -0,0 +1,22 @@ +@* + Idiomatic Heddle -- encoded-loop. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md + Architecture docs/architecture.md + + Authored the way the reference teaches -- readable block layout, definitions declared in the + @%...%@ header, and `@list`/`@if`/`@elif`/`@else` for control flow -- rather than collapsed onto + one line to match the oracle byte-for-byte. Checked by the functional verifier, not the byte + gate. The encoded workloads rely on OutputProfile.Html, where `@(...)` encodes by default and + `@attr(...)` applies attribute-context encoding; nothing here opts out. +*@ + + +@list(Items){{ + + + + +}} +
    @(Name)@(Comment)
    diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/fortunes-encoded.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/fortunes-encoded.heddle new file mode 100644 index 00000000..11bdab1b --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/fortunes-encoded.heddle @@ -0,0 +1,26 @@ +@* + Idiomatic Heddle -- fortunes-encoded. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md + Architecture docs/architecture.md + + Authored the way the reference teaches -- readable block layout, definitions declared in the + @%...%@ header, and `@list`/`@if`/`@elif`/`@else` for control flow -- rather than collapsed onto + one line to match the oracle byte-for-byte. Checked by the functional verifier, not the byte + gate. The encoded workloads rely on OutputProfile.Html, where `@(...)` encodes by default and + `@attr(...)` applies attribute-context encoding; nothing here opts out. +*@ + + + +Fortunes + + + + @list(Rows){{ + + }} +
    idmessage
    @(Id)@(Message)
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/fragment-heavy.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/fragment-heavy.heddle new file mode 100644 index 00000000..2e0c0e04 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/fragment-heavy.heddle @@ -0,0 +1,19 @@ +@* + Idiomatic Heddle -- fragment-heavy. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md ("Composition without coupling" -- + definition libraries imported via @<<) + Architecture docs/architecture.md + + Authored the way the reference teaches -- readable block layout, definitions imported + from the shared/fragments.heddle library via `@<<`, and `@list`/`@if`/`@elif`/`@else` + for control flow -- rather than collapsed onto one line to match the oracle + byte-for-byte. Four fragment kinds dispatch per row on the precomputed booleans. + Checked by the functional verifier, not the byte gate. +*@ + +@<<{{shared/fragments.heddle}} +
    +@list(Items){{@if(IsTile){{@tile()}}@elif(IsCard){{@card()}}@elif(IsMedia){{@media_row()}}@else(){{@stat()}}}} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/large-loop.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/large-loop.heddle new file mode 100644 index 00000000..d378912c --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/large-loop.heddle @@ -0,0 +1,17 @@ +@* + Idiomatic Heddle -- large-loop. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md + Architecture docs/architecture.md + + Authored the way the reference teaches -- readable block layout, definitions declared in the + @%...%@ header, and `@list`/`@if`/`@elif`/`@else` for control flow -- rather than collapsed onto + one line to match the oracle byte-for-byte. Checked by the functional verifier, not the byte + gate. The encoded workloads rely on OutputProfile.Html, where `@(...)` encodes by default and + `@attr(...)` applies attribute-context encoding; nothing here opts out. +*@ + +@list(Items){{ + row-@(Value)@(Value) +}} diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/mixed-page.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/mixed-page.heddle new file mode 100644 index 00000000..4f7b6cca --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/mixed-page.heddle @@ -0,0 +1,51 @@ +@* + Idiomatic Heddle -- mixed-page. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md + Architecture docs/architecture.md + + Authored the way the reference teaches -- readable block layout, definitions declared in the + @%...%@ header, and `@list`/`@if`/`@elif`/`@else` for control flow -- rather than collapsed onto + one line to match the oracle byte-for-byte. Checked by the functional verifier, not the byte + gate. The encoded workloads rely on OutputProfile.Html, where `@(...)` encodes by default and + `@attr(...)` applies attribute-context encoding; nothing here opts out. +*@ + + + + + + @(PageTitle) + + + +
    +

    @(StoreName)

    + +
    +
    + @if(ShowBanner){{}} +
    +

    @(HeroHeading)

    +

    @(HeroTagline)

    +
    +
    + @list(Products){{ +
    +

    @(Name)

    +

    MX-@(SkuNumber)

    +

    @(Price)

    + @if(OnSale){{

    On sale

    }} +

    A dependable workshop staple from batch @(Batch), checked for daily use and backed by our lifetime guarantee.

    +
    + }} +
    + @if(ShowDebugPanel){{
    debug
    }} +
    +
    +

    @(FooterNote)

    +

    @(StoreName) @(Year) @(SupportEmail)

    +
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/shared/chrome-fragments.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/shared/chrome-fragments.heddle new file mode 100644 index 00000000..871c27ec --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/shared/chrome-fragments.heddle @@ -0,0 +1,288 @@ +@* + Idiomatic Heddle -- composed-page chrome fragments. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md ("Composition without coupling" -- + definition libraries imported via @<<) + Architecture docs/architecture.md + + Definition-only library: the page's inert literal text (alert banner, secondary menus, + fixed asset/script fragments) as named definitions the layout calls at its composition + points. Importing it renders nothing; any piece is overridable with . All + display text lives in templates -- the C# tier carries only model data. +*@ +@% + + {{
    holiday shipping
    }} + + {{ }} + + {{ }} + + {{ + }} + + {{}} + + {{}} + + {{/* CSS Comment Test */}} + + {{}} + + {{}} + + {{}} +%@ diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/shared/fragments.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/shared/fragments.heddle new file mode 100644 index 00000000..500d48ee --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/shared/fragments.heddle @@ -0,0 +1,59 @@ +@* + Idiomatic Heddle -- fragment-heavy fragment library. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md ("Composition without coupling" -- + definition libraries imported via @<<) + Architecture docs/architecture.md + + Definition-only library: the six fragment kinds (tile, badge, price, card, media_row, + stat) as named definitions the fragment-heavy entry dispatches over per row; the card + fragment nests @badge/@price against the row's Promo, passing the member down exactly + as the reference's "passing the current value into a call" teaches. Importing it + renders nothing. Checked by the functional verifier, not the byte gate. +*@ +@% + +{{ +
    +

    @(Name)

    +

    @(Value)

    + @(Badge) +
    +}} + +{{ + @(Label) +}} + +{{ +

    @(Price).99

    +}} + +{{ +
    +

    @(Name)

    + @badge(Promo) + @price(Promo) +

    @(Value)

    +
    +}} + +{{ +
    + @(Name) +
    +

    @(Name)

    +

    Caption for @(Name)

    +
    +
    +}} + +{{ +
    + @(Name) + @(Value) + @(Delta) +
    +}} +%@ diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/shared/layout.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/shared/layout.heddle new file mode 100644 index 00000000..15feb6bd --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/shared/layout.heddle @@ -0,0 +1,199 @@ +@* + Idiomatic Heddle -- composed-page layout. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md ("Composition without coupling" -- + the layout-as-definition idiom) + Architecture docs/architecture.md + + This file is DEFINITION-ONLY: importing it renders nothing. The full page chrome lives + inside the definition, a bare @out() marks the body slot, and a page composes by + `@<<{{shared/layout.heddle}}` + `@layout(){{ ...body... }}` -- the documented equivalent of + Razor's Layout/@RenderBody, at zero render-time cost. Sections keep defaults a page may + override with the ordinary mechanism. The two mega menus and the footer render + from the structured nav model through nested definitions; the inert chrome fragments + (alert banner, secondary menus, asset/script snippets) are definitions imported from + shared/chrome-fragments.heddle -- all display text lives in templates. Checked by + the functional verifier, not the byte gate. +*@ + +@using() {{Heddle.Benchmarks.Dotnet.Models}} +@<<{{shared/chrome-fragments.heddle}} +@% + + {{ + Title + }} + + {{ + + + + }} + + {{ + }} + + {{ + }} + + {{ + + }} + + {{ + + }} + + {{ + + }} + + {{ +
    +
      + @list(Tabs) + {{ +
    • + @(Label) + @if(HasDropdown) + {{
      @list(Columns){{@nav_column()}}
      }} +
    • + }} +
    +
    + }} + + {{ + + + + + + + + + @meta() + @socialmeta() + + + + + + @assets_styles() + + @head_scripts() + + + @body_scripts() +
    +
    + +
    +
    +
    +
    + @alert_top() +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + @list(Nav.Menus){{@mega_menu()}} +
    +
    +
    + @alert_below() +
    +
    + @out() +
    +
    +
    +
    +
    + +
    +
    + @assets_scripts() + + @page_scripts() + @endpage_scripts() + @body_end_scripts() + +}} :: ComposedModel +%@ diff --git a/benchmarks/dotnet/templates/idiomatic/heddle/trivial-substitution.heddle b/benchmarks/dotnet/templates/idiomatic/heddle/trivial-substitution.heddle new file mode 100644 index 00000000..f27971f8 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/heddle/trivial-substitution.heddle @@ -0,0 +1,25 @@ +@* + Idiomatic Heddle -- trivial-substitution. + + Patterns followed, from Heddle's own documentation: + Language reference docs/language-reference.md + Architecture docs/architecture.md + + Authored the way the reference teaches -- readable block layout, definitions declared in the + @%...%@ header, and `@list`/`@if`/`@elif`/`@else` for control flow -- rather than collapsed onto + one line to match the oracle byte-for-byte. Checked by the functional verifier, not the byte + gate. The encoded workloads rely on OutputProfile.Html, where `@(...)` encodes by default and + `@attr(...)` applies attribute-context encoding; nothing here opts out. +*@ + +
    +

    @(Title)

    +

    @(Sku)

    +

    @(Price)

    +

    @(Brand)

    +

    @(Category)

    +

    @(Availability)

    + +

    @(Summary)

    +

    @(Rating)

    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/composed-page.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/composed-page.dotliquid.liquid new file mode 100644 index 00000000..e375b552 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/composed-page.dotliquid.liquid @@ -0,0 +1,29 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Capture-then-include layout composition: the slider body is captured into + body_content, then the layout partial is included and splices it at its live slot. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +{% capture body_content %} +
    +
    +
    +
    +
    + + + +
    +
    +
    +{% endcapture %} +{% include 'layout' %} diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/composed-page.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/composed-page.fluid.liquid new file mode 100644 index 00000000..3cdfb72a --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/composed-page.fluid.liquid @@ -0,0 +1,28 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + The Liquid layout idiom pinned for this workload: the page captures its + body into `body_content` and includes the layout, which emits `{{ body_content }}` at its + body-slot position. The slider content is the SAME as the controlled track's -- the verifier's + calibration pin (RemovedSegment = the slider fragment) fails an empty body, deliberately. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +{% capture body_content %} +
    +
    +
    +
    +
    + + + +
    +
    +
    +{% endcapture %} +{% include 'layout' %} diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/conditional-heavy.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/conditional-heavy.dotliquid.liquid new file mode 100644 index 00000000..9ac9785a --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/conditional-heavy.dotliquid.liquid @@ -0,0 +1,29 @@ +{%- comment -%} + Idiomatic Liquid -- conditional-heavy (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + The note text is composed in the template as the literal note plus the seq substitution + (the model carries data, never display strings). + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +
      + {% for r in rows %} +
    • + {% if r.is_bronze %}bronze + {% elsif r.is_silver %}silver + {% elsif r.is_gold %}gold + {% else %}platinum + {% endif %} + {{ r.name }} + {% if r.has_note %}note {{ r.seq }}{% endif %} + {% if r.is_active %}active{% endif %} +
    • + {% endfor %} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/conditional-heavy.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/conditional-heavy.fluid.liquid new file mode 100644 index 00000000..77a878c8 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/conditional-heavy.fluid.liquid @@ -0,0 +1,26 @@ +{%- comment -%} + Idiomatic Liquid -- conditional-heavy (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + The note text is composed by the template as `note ` + the seq substitution (the + model carries data only). Authored the way the docs teach rather than to match the oracle + byte-for-byte. Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +
      + {% for r in rows %} +
    • + {% if r.is_bronze %}bronze + {% elsif r.is_silver %}silver + {% elsif r.is_gold %}gold + {% else %}platinum + {% endif %} + {{ r.name }} + {% if r.has_note %}note {{ r.seq }}{% endif %} + {% if r.is_active %}active{% endif %} +
    • + {% endfor %} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/encoded-loop.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/encoded-loop.liquid new file mode 100644 index 00000000..cd8040f7 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/encoded-loop.liquid @@ -0,0 +1,21 @@ +{%- comment -%} + Idiomatic Liquid -- encoded-loop. + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + DotLiquid http://dotliquidmarkup.org/ + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented `escape` filter on untrusted + values. Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + + {% for item in items %} + + + + + {% endfor %} +
    {{ item.name | escape }}{{ item.comment | escape }}
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/fortunes-encoded.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/fortunes-encoded.liquid new file mode 100644 index 00000000..8955022f --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/fortunes-encoded.liquid @@ -0,0 +1,25 @@ +{%- comment -%} + Idiomatic Liquid -- fortunes-encoded. + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + DotLiquid http://dotliquidmarkup.org/ + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented `escape` filter on untrusted + values. Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + + +Fortunes + + + + {% for r in rows %} + + {% endfor %} +
    idmessage
    {{ r.id }}{{ r.message | escape }}
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/fragment-heavy.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/fragment-heavy.dotliquid.liquid new file mode 100644 index 00000000..3eccd1da --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/fragment-heavy.dotliquid.liquid @@ -0,0 +1,30 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Per-row fragment dispatch: Liquid's native {% case %} switch selects the + fragment partial; the card partial nests the badge and price partials against the row's + promo (the one nesting level). + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +
    + {% for item in items %} + {% case item.kind %} + {% when 'tile' %} + {% include 'tile' %} + {% when 'card' %} + {% include 'card' %} + {% when 'media' %} + {% include 'media-row' %} + {% else %} + {% include 'stat' %} + {% endcase %} + {% endfor %} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/fragment-heavy.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/fragment-heavy.fluid.liquid new file mode 100644 index 00000000..84e7782b --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/fragment-heavy.fluid.liquid @@ -0,0 +1,27 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Four fragment kinds dispatch per row on the precomputed booleans (the pinned dispatch shape + for this engine: the boolean `{% if %}/{% elsif %}` chain with the per-kind include inside each + arm); the card partial nests badge + price against the row's promo. Authored the way the docs + teach -- readable whitespace and Liquid's own control-flow tags -- rather than to match the + oracle byte-for-byte. Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +
    + {% for item in items %} + {% if item.is_tile %} + {% include 'tile' with item %} + {% elsif item.is_card %} + {% include 'card' with item %} + {% elsif item.is_media %} + {% include 'media-row' with item %} + {% else %} + {% include 'stat' with item %} + {% endif %} + {% endfor %} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/large-loop.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/large-loop.dotliquid.liquid new file mode 100644 index 00000000..50a9cb32 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/large-loop.dotliquid.liquid @@ -0,0 +1,18 @@ +{%- comment -%} + Idiomatic Liquid -- large-loop (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + The display name row-N is composed in the template as the literal row- plus the value + substitution (the model carries data, never display strings). + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +{% for item in items %} + row-{{ item.value }}{{ item.value }} +{% endfor %} diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/large-loop.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/large-loop.fluid.liquid new file mode 100644 index 00000000..5906af30 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/large-loop.fluid.liquid @@ -0,0 +1,15 @@ +{%- comment -%} + Idiomatic Liquid -- large-loop (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + The display name is composed by the template as `row-` + the value substitution (the + model carries data only). Authored the way the docs teach rather than to match the oracle + byte-for-byte. Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +{% for item in items %} + row-{{ item.value }}{{ item.value }} +{% endfor %} diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/mixed-page.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/mixed-page.dotliquid.liquid new file mode 100644 index 00000000..edd7c8a6 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/mixed-page.dotliquid.liquid @@ -0,0 +1,57 @@ +{%- comment -%} + Idiomatic Liquid -- mixed-page (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Single-file by rule (layout composition is composed-page's dimension). The + display SKU MX-N and the blurb sentence are composed in the template around the sku_number + and batch substitutions. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + + + + + + {{ page_title }} + + + +
    +

    {{ store_name }}

    + +
    +
    + {% if show_banner %} + + {% endif %} +
    +

    {{ hero_heading }}

    +

    {{ hero_tagline }}

    +
    +
    + {% for p in products %} +
    +

    {{ p.name }}

    +

    MX-{{ p.sku_number }}

    +

    {{ p.price }}

    + {% if p.on_sale %}

    On sale

    {% endif %} +

    A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

    +
    + {% endfor %} +
    + {% if show_debug_panel %}
    debug
    {% endif %} +
    +
    +

    {{ footer_note }}

    +

    {{ store_name }} {{ year }} {{ support_email }}

    +
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/mixed-page.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/mixed-page.fluid.liquid new file mode 100644 index 00000000..07e165c7 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/mixed-page.fluid.liquid @@ -0,0 +1,55 @@ +{%- comment -%} + Idiomatic Liquid -- mixed-page (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Single-file by rule (layout composition is composed-page's dimension, not this one's). + The display SKU is composed by the template as `MX-` + the sku_number substitution, and the + blurb sentence lives in the template around the batch substitution (the model + carries data only). Authored the way the docs teach rather than to match the oracle + byte-for-byte. Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + + + + + {{ page_title }} + + + +
    +

    {{ store_name }}

    + +
    +
    + {% if show_banner %} + + {% endif %} +
    +

    {{ hero_heading }}

    +

    {{ hero_tagline }}

    +
    +
    + {% for p in products %} +
    +

    {{ p.name }}

    +

    MX-{{ p.sku_number }}

    +

    {{ p.price }}

    + {% if p.on_sale %}

    On sale

    {% endif %} +

    A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

    +
    + {% endfor %} +
    + {% if show_debug_panel %}
    debug
    {% endif %} +
    +
    +

    {{ footer_note }}

    +

    {{ store_name }} {{ year }} {{ support_email }}

    +
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-below.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-below.dotliquid.liquid new file mode 100644 index 00000000..4506204c --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-below.dotliquid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page chrome fragment: alert-below (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Literal chrome text transcribed from the Heddle chrome-fragments library + (all display text lives in templates; the C# tier carries only model data). Served to + the layout through DotLiquid's scope-shared {% include %}. Checked by the functional + verifier, not the byte gate. +{%- endcomment -%} + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-below.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-below.fluid.liquid new file mode 100644 index 00000000..c4947dd4 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-below.fluid.liquid @@ -0,0 +1,12 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page alert-below chrome fragment (pinned empty) (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-top.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-top.dotliquid.liquid new file mode 100644 index 00000000..da7109b3 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-top.dotliquid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page chrome fragment: alert-top (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Literal chrome text transcribed from the Heddle chrome-fragments library + (all display text lives in templates; the C# tier carries only model data). Served to + the layout through DotLiquid's scope-shared {% include %}. Checked by the functional + verifier, not the byte gate. +{%- endcomment -%} +
    holiday shipping
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-top.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-top.fluid.liquid new file mode 100644 index 00000000..0e89bd22 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/alert-top.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page alert-top chrome fragment (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +
    holiday shipping
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-scripts.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-scripts.dotliquid.liquid new file mode 100644 index 00000000..923ccf43 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-scripts.dotliquid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page chrome fragment: assets-scripts (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Literal chrome text transcribed from the Heddle chrome-fragments library + (all display text lives in templates; the C# tier carries only model data). Served to + the layout through DotLiquid's scope-shared {% include %}. Checked by the functional + verifier, not the byte gate. +{%- endcomment -%} + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-scripts.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-scripts.fluid.liquid new file mode 100644 index 00000000..26519309 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-scripts.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page assets-scripts chrome fragment (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-styles.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-styles.dotliquid.liquid new file mode 100644 index 00000000..3afb0ea3 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-styles.dotliquid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page chrome fragment: assets-styles (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Literal chrome text transcribed from the Heddle chrome-fragments library + (all display text lives in templates; the C# tier carries only model data). Served to + the layout through DotLiquid's scope-shared {% include %}. Checked by the functional + verifier, not the byte gate. +{%- endcomment -%} + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-styles.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-styles.fluid.liquid new file mode 100644 index 00000000..1c81557c --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/assets-styles.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page assets-styles chrome fragment (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/badge.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/badge.dotliquid.liquid new file mode 100644 index 00000000..2969f195 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/badge.dotliquid.liquid @@ -0,0 +1,16 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy badge partial (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Fragment partial: invoked from the fragment-heavy dispatch loop; DotLiquid's + scope-shared {% include %} makes the loop variable visible here. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +{{ item.promo.label }} diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/badge.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/badge.fluid.liquid new file mode 100644 index 00000000..8ec4e781 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/badge.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy badge partial (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +{{ badge.label }} diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-end-scripts.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-end-scripts.dotliquid.liquid new file mode 100644 index 00000000..66b2b535 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-end-scripts.dotliquid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page chrome fragment: body-end-scripts (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Literal chrome text transcribed from the Heddle chrome-fragments library + (all display text lives in templates; the C# tier carries only model data). Served to + the layout through DotLiquid's scope-shared {% include %}. Checked by the functional + verifier, not the byte gate. +{%- endcomment -%} + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-end-scripts.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-end-scripts.fluid.liquid new file mode 100644 index 00000000..54b0c360 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-end-scripts.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page body-end-scripts chrome fragment (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-scripts.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-scripts.dotliquid.liquid new file mode 100644 index 00000000..eebef768 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-scripts.dotliquid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page chrome fragment: body-scripts (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Literal chrome text transcribed from the Heddle chrome-fragments library + (all display text lives in templates; the C# tier carries only model data). Served to + the layout through DotLiquid's scope-shared {% include %}. Checked by the functional + verifier, not the byte gate. +{%- endcomment -%} + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-scripts.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-scripts.fluid.liquid new file mode 100644 index 00000000..5d2478bd --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/body-scripts.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page body-scripts chrome fragment (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/card.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/card.dotliquid.liquid new file mode 100644 index 00000000..23c08d85 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/card.dotliquid.liquid @@ -0,0 +1,21 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy card partial (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Fragment partial: invoked from the fragment-heavy dispatch loop; DotLiquid's + scope-shared {% include %} makes the loop variable visible here. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +
    +

    {{ item.name }}

    + {% include 'badge' %} + {% include 'price' %} +

    {{ item.value }}

    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/card.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/card.fluid.liquid new file mode 100644 index 00000000..ce3850c2 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/card.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy card partial (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +

    {{ card.name }}

    {% include 'badge' with card.promo %}{% include 'price' with card.promo %}

    {{ card.value }}

    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/custom-styles.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/custom-styles.dotliquid.liquid new file mode 100644 index 00000000..6176ce1d --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/custom-styles.dotliquid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page chrome fragment: custom-styles (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Literal chrome text transcribed from the Heddle chrome-fragments library + (all display text lives in templates; the C# tier carries only model data). Served to + the layout through DotLiquid's scope-shared {% include %}. Checked by the functional + verifier, not the byte gate. +{%- endcomment -%} +/* CSS Comment Test */ diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/custom-styles.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/custom-styles.fluid.liquid new file mode 100644 index 00000000..6f031c7d --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/custom-styles.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page custom-styles chrome fragment (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +/* CSS Comment Test */ diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/head-scripts.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/head-scripts.dotliquid.liquid new file mode 100644 index 00000000..bf61dfab --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/head-scripts.dotliquid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page chrome fragment: head-scripts (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Literal chrome text transcribed from the Heddle chrome-fragments library + (all display text lives in templates; the C# tier carries only model data). Served to + the layout through DotLiquid's scope-shared {% include %}. Checked by the functional + verifier, not the byte gate. +{%- endcomment -%} + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/head-scripts.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/head-scripts.fluid.liquid new file mode 100644 index 00000000..8131ce72 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/head-scripts.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page head-scripts chrome fragment (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/layout.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/layout.dotliquid.liquid new file mode 100644 index 00000000..b3d9aaa1 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/layout.dotliquid.liquid @@ -0,0 +1,148 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page layout (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Capture-then-include layout composition: the page captures its body into + body_content and includes this layout, which emits {{ body_content }} at the live slot. + DotLiquid's {% include %} shares the enclosing scope, so the captured body and the nav + model are visible here without arguments. All inert chrome is literal template text, + served by the chrome-fragment partials. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + + + + + + + + + + + Title + + + + + + + + + {% include 'assets-styles' %} + + {% include 'head-scripts' %} + + + {% include 'body-scripts' %} +
    +
    + +
    +
    +
    +
    + {% include 'alert-top' %} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + {% for menu in nav.menus %} + {% include 'mega-menu' %} + {% endfor %} +
    +
    +
    + {% include 'alert-below' %} +
    +
    + {{ body_content }} +
    +
    +
    +
    +
    + +
    +
    + {% include 'assets-scripts' %} + + {% include 'body-end-scripts' %} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/layout.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/layout.fluid.liquid new file mode 100644 index 00000000..19519d2e --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/layout.fluid.liquid @@ -0,0 +1,138 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page layout (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + + + + + + + + + + Title + + + + + + + + + {% include 'assets-styles' %} + + {% include 'head-scripts' %} + + + {% include 'body-scripts' %} +
    +
    + +
    +
    +
    +
    + {% include 'alert-top' %} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + {% for menu in nav.menus %}{% include 'mega-menu' with menu %}{% endfor %} +
    +
    +
    + {% include 'alert-below' %} +
    +
    + {{ body_content }} +
    +
    +
    +
    +
    + +
    +
    + {% include 'assets-scripts' %} + + {% include 'body-end-scripts' %} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/media-row.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/media-row.dotliquid.liquid new file mode 100644 index 00000000..10bed960 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/media-row.dotliquid.liquid @@ -0,0 +1,22 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy media-row partial (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Fragment partial: invoked from the fragment-heavy dispatch loop; DotLiquid's + scope-shared {% include %} makes the loop variable visible here. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +
    + {{ item.name }} +
    +

    {{ item.name }}

    +

    Caption for {{ item.name }}

    +
    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/media-row.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/media-row.fluid.liquid new file mode 100644 index 00000000..f21459d2 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/media-row.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy media-row partial (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +
    {{ media-row.name }}

    {{ media-row.name }}

    Caption for {{ media-row.name }}

    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/mega-menu.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/mega-menu.dotliquid.liquid new file mode 100644 index 00000000..3b9a5578 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/mega-menu.dotliquid.liquid @@ -0,0 +1,30 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page mega-menu partial (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Nested nav partial: invoked from a {% for %} loop; DotLiquid's scope-shared + {% include %} makes the loop variable visible inside the partial. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +
    +
      + {% for tab in menu.tabs %} +
    • {{ tab.label }} + {% if tab.has_dropdown %} +
      + {% for column in tab.columns %} + {% include 'nav-column' %} + {% endfor %} +
      + {% endif %} +
    • + {% endfor %} +
    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/mega-menu.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/mega-menu.fluid.liquid new file mode 100644 index 00000000..efc78f68 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/mega-menu.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page mega-menu partial (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +
      {% for tab in mega-menu.tabs %}
    • {{ tab.label }}{% if tab.has_dropdown %}
      {% for column in tab.columns %}{% include 'nav-column' with column %}{% endfor %}
      {% endif %}
    • {% endfor %}
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-column.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-column.dotliquid.liquid new file mode 100644 index 00000000..2fba54b3 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-column.dotliquid.liquid @@ -0,0 +1,20 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page nav-column partial (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Nested nav partial: invoked from a {% for %} loop; DotLiquid's scope-shared + {% include %} makes the loop variable visible inside the partial. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-column.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-column.fluid.liquid new file mode 100644 index 00000000..5d47719d --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-column.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page nav-column partial (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-link.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-link.dotliquid.liquid new file mode 100644 index 00000000..c6c2a8be --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-link.dotliquid.liquid @@ -0,0 +1,16 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page nav-link partial (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Nested nav partial: invoked from a {% for %} loop; DotLiquid's scope-shared + {% include %} makes the loop variable visible inside the partial. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-link.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-link.fluid.liquid new file mode 100644 index 00000000..62ea9d6d --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-link.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page nav-link partial (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-section.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-section.dotliquid.liquid new file mode 100644 index 00000000..cf775c7c --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-section.dotliquid.liquid @@ -0,0 +1,27 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page nav-section partial (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Nested nav partial: invoked from a {% for %} loop; DotLiquid's scope-shared + {% include %} makes the loop variable visible inside the partial. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-section.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-section.fluid.liquid new file mode 100644 index 00000000..73903304 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/nav-section.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page nav-section partial (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/price.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/price.dotliquid.liquid new file mode 100644 index 00000000..019e00e5 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/price.dotliquid.liquid @@ -0,0 +1,16 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy price partial (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Fragment partial: invoked from the fragment-heavy dispatch loop; DotLiquid's + scope-shared {% include %} makes the loop variable visible here. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +

    {{ item.promo.price }}.99

    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/price.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/price.fluid.liquid new file mode 100644 index 00000000..707858f9 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/price.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy price partial (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +

    {{ price.price }}.99

    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-retail-menu.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-retail-menu.dotliquid.liquid new file mode 100644 index 00000000..380f7e70 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-retail-menu.dotliquid.liquid @@ -0,0 +1,128 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page chrome fragment: secondary-retail-menu (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Literal chrome text transcribed from the Heddle chrome-fragments library + (all display text lives in templates; the C# tier carries only model data). Served to + the layout through DotLiquid's scope-shared {% include %}. Checked by the functional + verifier, not the byte gate. +{%- endcomment -%} + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-retail-menu.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-retail-menu.fluid.liquid new file mode 100644 index 00000000..d49f4ebe --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-retail-menu.fluid.liquid @@ -0,0 +1,128 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page secondary retail menu chrome fragment (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-wholesale-menu.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-wholesale-menu.dotliquid.liquid new file mode 100644 index 00000000..956213a1 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-wholesale-menu.dotliquid.liquid @@ -0,0 +1,150 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page chrome fragment: secondary-wholesale-menu (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Literal chrome text transcribed from the Heddle chrome-fragments library + (all display text lives in templates; the C# tier carries only model data). Served to + the layout through DotLiquid's scope-shared {% include %}. Checked by the functional + verifier, not the byte gate. +{%- endcomment -%} + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-wholesale-menu.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-wholesale-menu.fluid.liquid new file mode 100644 index 00000000..a741d491 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/secondary-wholesale-menu.fluid.liquid @@ -0,0 +1,150 @@ +{%- comment -%} + Idiomatic Liquid -- composed-page secondary wholesale menu chrome fragment (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + + diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/stat.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/stat.dotliquid.liquid new file mode 100644 index 00000000..dd27c8b3 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/stat.dotliquid.liquid @@ -0,0 +1,20 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy stat partial (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Fragment partial: invoked from the fragment-heavy dispatch loop; DotLiquid's + scope-shared {% include %} makes the loop variable visible here. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +
    + {{ item.name }} + {{ item.value }} + {{ item.delta }} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/stat.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/stat.fluid.liquid new file mode 100644 index 00000000..fcf13e67 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/stat.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy stat partial (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +
    {{ stat.name }}{{ stat.value }}{{ stat.delta }}
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/tile.dotliquid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/tile.dotliquid.liquid new file mode 100644 index 00000000..399102a6 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/tile.dotliquid.liquid @@ -0,0 +1,20 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy tile partial (DotLiquid dialect). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + DotLiquid http://dotliquidmarkup.org/ + + Fragment partial: invoked from the fragment-heavy dispatch loop; DotLiquid's + scope-shared {% include %} makes the loop variable visible here. + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace and Liquid's own control-flow tags. Checked by the functional verifier, not + the byte gate. +{%- endcomment -%} + +
    +

    {{ item.name }}

    +

    {{ item.value }}

    + {{ item.badge }} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/shared/tile.fluid.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/shared/tile.fluid.liquid new file mode 100644 index 00000000..23f5857e --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/shared/tile.fluid.liquid @@ -0,0 +1,13 @@ +{%- comment -%} + Idiomatic Liquid -- fragment-heavy tile partial (Fluid). + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented capture/include composition. + Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +

    {{ tile.name }}

    {{ tile.value }}

    {{ tile.badge }}
    \ No newline at end of file diff --git a/benchmarks/dotnet/templates/idiomatic/liquid/trivial-substitution.liquid b/benchmarks/dotnet/templates/idiomatic/liquid/trivial-substitution.liquid new file mode 100644 index 00000000..547bb1b1 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/liquid/trivial-substitution.liquid @@ -0,0 +1,24 @@ +{%- comment -%} + Idiomatic Liquid -- trivial-substitution. + + Patterns followed, from the engines' own documentation: + Liquid language reference https://shopify.github.io/liquid/ + Fluid https://github.com/sebastienros/fluid#readme + DotLiquid http://dotliquidmarkup.org/ + + Authored the way the docs teach rather than to match the oracle byte-for-byte: readable + whitespace, Liquid's own control-flow tags, and the documented `escape` filter on untrusted + values. Checked by the functional verifier, not the byte gate. +{%- endcomment -%} + +
    +

    {{ title }}

    +

    {{ sku }}

    +

    {{ price }}

    +

    {{ brand }}

    +

    {{ category }}

    +

    {{ availability }}

    + +

    {{ summary }}

    +

    {{ rating }}

    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/badge.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/badge.cshtml new file mode 100644 index 00000000..1f4a639d --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/badge.cshtml @@ -0,0 +1,13 @@ +@* + Idiomatic Razor -- fragment-heavy badge sub-partial. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + Nested by the card partial against the row's Promo. Checked by the functional verifier, + not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentPromo +@Model.Label diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/card.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/card.cshtml new file mode 100644 index 00000000..6db8d449 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/card.cshtml @@ -0,0 +1,18 @@ +@* + Idiomatic Razor -- fragment-heavy card partial. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + The nesting fragment: renders the badge and price partials against the row's Promo. + Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentRow +
    +

    @Model.Name

    + @await Html.PartialAsync("/Views/Shared/badge.cshtml", Model.Promo) + @await Html.PartialAsync("/Views/Shared/price.cshtml", Model.Promo) +

    @Model.Value

    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/composed-page-layout.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/composed-page-layout.cshtml new file mode 100644 index 00000000..e07501e0 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/composed-page-layout.cshtml @@ -0,0 +1,403 @@ +@* + Idiomatic Razor -- composed-page layout. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Layouts https://learn.microsoft.com/aspnet/core/mvc/views/layout + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + A genuine full-page layout with a LIVE body slot: Razor's native Layout/@RenderBody + mechanism. The inert chrome fragments (alert banner, secondary menus, asset/script + snippets) are literal markup in this view -- Razor-native, no workaround needed (all + display text lives in templates; the C# tier carries only model DATA). The structured + navigation renders from ComposedModel.Nav through nested loops and partial views + (menu -> column -> section -> link). Strongly-typed @model, C# control flow, and the + DEFAULT @expression output -- which HTML-encodes; the nav values are markup-clean ASCII + by fixture rule, so encoding is the idiomatic no-op it should be. Checked by the + functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model ComposedModel + + + + + + + + + + Title + + + + + + + + + + + + + + +
    +
    + +
    +
    +
    +
    +
    holiday shipping
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + @foreach (var menu in Model.Nav.Menus) + { + @await Html.PartialAsync("/Views/Shared/mega-menu.cshtml", menu) + } +
    +
    +
    +
    +
    + @RenderBody() +
    +
    +
    +
    +
    + +
    +
    + + + + + diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/media-row.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/media-row.cshtml new file mode 100644 index 00000000..64be2917 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/media-row.cshtml @@ -0,0 +1,21 @@ +@* + Idiomatic Razor -- fragment-heavy media-row partial. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + One of the four dispatched fragment kinds. The image source (`/img/@(Model.Name).jpg`) + and the caption (`Caption for @Model.Name`) are composed by the TEMPLATE as + literal-plus-substitution -- the model carries data, never display strings. Checked by + the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentRow +
    + @Model.Name +
    +

    @Model.Name

    +

    Caption for @Model.Name

    +
    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/mega-menu.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/mega-menu.cshtml new file mode 100644 index 00000000..1d6ba544 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/mega-menu.cshtml @@ -0,0 +1,32 @@ +@* + Idiomatic Razor -- composed-page mega-menu partial. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + One mega menu: the tab loop with the per-tab dropdown, each dropdown column rendered + through the nested nav-column partial. Strongly-typed @model and the DEFAULT @expression + output. Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model MegaMenu +
    +
      + @foreach (var tab in Model.Tabs) + { +
    • + @tab.Label + @if (tab.HasDropdown) + { +
      + @foreach (var column in tab.Columns) + { + @await Html.PartialAsync("/Views/Shared/nav-column.cshtml", column) + } +
      + } +
    • + } +
    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/nav-column.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/nav-column.cshtml new file mode 100644 index 00000000..86efef41 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/nav-column.cshtml @@ -0,0 +1,19 @@ +@* + Idiomatic Razor -- composed-page nav-column partial. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + One navigation column, shared by the mega-menu dropdowns and the footer nav; each section + renders through the nested nav-section partial. Checked by the functional verifier, not + the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model NavColumn + diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/nav-link.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/nav-link.cshtml new file mode 100644 index 00000000..dd0589c0 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/nav-link.cshtml @@ -0,0 +1,12 @@ +@* + Idiomatic Razor -- composed-page nav-link partial. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + One navigation link. Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model NavLink + diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/nav-section.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/nav-section.cshtml new file mode 100644 index 00000000..4b1d87ec --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/nav-section.cshtml @@ -0,0 +1,28 @@ +@* + Idiomatic Razor -- composed-page nav-section partial. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + One navigation section: the precomputed TitleLinked branch and the link loop through the + nested nav-link partial. Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model NavSection + diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/price.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/price.cshtml new file mode 100644 index 00000000..ca027a9a --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/price.cshtml @@ -0,0 +1,14 @@ +@* + Idiomatic Razor -- fragment-heavy price sub-partial. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + Nested by the card partial against the row's Promo. The display price is composed by the + TEMPLATE as literal-plus-substitution (`@(Model.Price).99`). Checked by the + functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentPromo +

    @(Model.Price).99

    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/stat.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/stat.cshtml new file mode 100644 index 00000000..a989c6fc --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/stat.cshtml @@ -0,0 +1,17 @@ +@* + Idiomatic Razor -- fragment-heavy stat partial. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + One of the four dispatched fragment kinds. Checked by the functional verifier, not the + byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentRow +
    + @Model.Name + @Model.Value + @Model.Delta +
    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/tile.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/tile.cshtml new file mode 100644 index 00000000..4c63dc5f --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/Shared/tile.cshtml @@ -0,0 +1,17 @@ +@* + Idiomatic Razor -- fragment-heavy tile partial. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + One of the four dispatched fragment kinds. Strongly-typed @model and the DEFAULT + @expression output. Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentRow +
    +

    @Model.Name

    +

    @Model.Value

    + @Model.Badge +
    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/composed-page.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/composed-page.cshtml new file mode 100644 index 00000000..c8292095 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/composed-page.cshtml @@ -0,0 +1,30 @@ +@* + Idiomatic Razor -- composed-page. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Layouts https://learn.microsoft.com/aspnet/core/mvc/views/layout + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + The page names its layout and the markup body splices at the layout's single mid-page + @RenderBody() -- exactly how a Razor developer composes a page. The slider body is the + SAME as the controlled track's: the verifier's removed-segment calibration pin is the + slider, so an empty body fails, deliberately. Checked by the functional verifier, not + the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model ComposedModel +@{ + Layout = "/Views/Shared/composed-page-layout.cshtml"; +} +
    +
    +
    +
    +
    + + + +
    +
    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/conditional-heavy.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/conditional-heavy.cshtml new file mode 100644 index 00000000..b65e4825 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/conditional-heavy.cshtml @@ -0,0 +1,49 @@ +@* + Idiomatic Razor -- conditional-heavy (the template composes `note @(r.Seq)` -- + the model carries the int only). + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Layouts https://learn.microsoft.com/aspnet/core/mvc/views/layout + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + Strongly-typed @model, C# control flow, and the DEFAULT @expression output -- which HTML-encodes + -- rather than Html.Raw. That is the substantive idiomatic difference from the controlled twin: + a Razor developer reaches for Html.Raw only when the value genuinely is markup, which here is + only the composed-page fragments. Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model ConditionalContent.ConditionalModel +@{ Layout = null; } +
      + @foreach (var r in Model.Rows) + { +
    • + @if (r.IsBronze) + { + bronze + } + else if (r.IsSilver) + { + silver + } + else if (r.IsGold) + { + gold + } + else + { + platinum + } + @r.Name + @if (r.HasNote) + { + note @r.Seq + } + @if (r.IsActive) + { + active + } +
    • + } +
    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/encoded-loop.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/encoded-loop.cshtml new file mode 100644 index 00000000..e6efc54a --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/encoded-loop.cshtml @@ -0,0 +1,25 @@ +@* + Idiomatic Razor -- encoded-loop. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Layouts https://learn.microsoft.com/aspnet/core/mvc/views/layout + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + Strongly-typed @model, C# control flow, and the DEFAULT @expression output -- which HTML-encodes + -- rather than Html.Raw. That is the substantive idiomatic difference from the controlled twin: + a Razor developer reaches for Html.Raw only when the value genuinely is markup, which here is + only the composed-page fragments. Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model EncodedLoopContent.EncodedLoopModel +@{ Layout = null; } + + @foreach (var item in Model.Items) + { + + + + + } +
    @item.Name@item.Comment
    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/fortunes-encoded.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/fortunes-encoded.cshtml new file mode 100644 index 00000000..462ab9b2 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/fortunes-encoded.cshtml @@ -0,0 +1,29 @@ +@* + Idiomatic Razor -- fortunes-encoded. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Layouts https://learn.microsoft.com/aspnet/core/mvc/views/layout + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + Strongly-typed @model, C# control flow, and the DEFAULT @expression output -- which HTML-encodes + -- rather than Html.Raw. That is the substantive idiomatic difference from the controlled twin: + a Razor developer reaches for Html.Raw only when the value genuinely is markup, which here is + only the composed-page fragments. Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FortunesContent.FortuneModel +@{ Layout = null; } + + +Fortunes + + + + @foreach (var r in Model.Rows) + { + + } +
    idmessage
    @r.Id@r.Message
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/fragment-heavy.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/fragment-heavy.cshtml new file mode 100644 index 00000000..1c031702 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/fragment-heavy.cshtml @@ -0,0 +1,36 @@ +@* + Idiomatic Razor -- fragment-heavy. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + Per-row fragment dispatch plus nested composition: a C# switch on Kind -- Razor's + documented native switch form, permitted on the idiomatic track -- + selects which of the four partial views to invoke; the card partial nests the badge and + price partials against the row's Promo. Checked by the functional verifier, not the + byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model FragmentContent.FragmentModel +@{ Layout = null; } +
    + @foreach (var item in Model.Items) + { + switch (item.Kind) + { + case "tile": + @await Html.PartialAsync("/Views/Shared/tile.cshtml", item) + break; + case "card": + @await Html.PartialAsync("/Views/Shared/card.cshtml", item) + break; + case "media": + @await Html.PartialAsync("/Views/Shared/media-row.cshtml", item) + break; + default: + @await Html.PartialAsync("/Views/Shared/stat.cshtml", item) + break; + } + } +
    diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/large-loop.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/large-loop.cshtml new file mode 100644 index 00000000..72c1e2fd --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/large-loop.cshtml @@ -0,0 +1,21 @@ +@* + Idiomatic Razor -- large-loop (the template composes `row-@(item.Value)` -- + the model carries the int only). + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Layouts https://learn.microsoft.com/aspnet/core/mvc/views/layout + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + Strongly-typed @model, C# control flow, and the DEFAULT @expression output -- which HTML-encodes + -- rather than Html.Raw. That is the substantive idiomatic difference from the controlled twin: + a Razor developer reaches for Html.Raw only when the value genuinely is markup, which here is + only the composed-page fragments. Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model LoopContent.LoopModel +@{ Layout = null; } +@foreach (var item in Model.Items) +{ + row-@item.Value@item.Value +} diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/mixed-page.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/mixed-page.cshtml new file mode 100644 index 00000000..cfec2801 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/mixed-page.cshtml @@ -0,0 +1,65 @@ +@* + Idiomatic Razor -- mixed-page (the template composes the display SKU + (`MX-@(p.SkuNumber)`) and the blurb sentence around `@p.Batch` -- the model + carries the ints only). + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Layouts https://learn.microsoft.com/aspnet/core/mvc/views/layout + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + Strongly-typed @model, C# control flow, and the DEFAULT @expression output -- which HTML-encodes + -- rather than Html.Raw. That is the substantive idiomatic difference from the controlled twin: + a Razor developer reaches for Html.Raw only when the value genuinely is markup, which here is + only the composed-page fragments. Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model MixedContent.MixedModel +@{ Layout = null; } + + + + + @Model.PageTitle + + + +
    +

    @Model.StoreName

    + +
    +
    + @if (Model.ShowBanner) + { + + } +
    +

    @Model.HeroHeading

    +

    @Model.HeroTagline

    +
    +
    + @foreach (var p in Model.Products) + { +
    +

    @p.Name

    +

    MX-@p.SkuNumber

    +

    @p.Price

    + @if (p.OnSale) + { +

    On sale

    + } +

    A dependable workshop staple from batch @p.Batch, checked for daily use and backed by our lifetime guarantee.

    +
    + } +
    + @if (Model.ShowDebugPanel) + { +
    debug
    + } +
    +
    +

    @Model.FooterNote

    +

    @Model.StoreName @Model.Year @Model.SupportEmail

    +
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/razor/Views/trivial-substitution.cshtml b/benchmarks/dotnet/templates/idiomatic/razor/Views/trivial-substitution.cshtml new file mode 100644 index 00000000..bb0ec219 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/razor/Views/trivial-substitution.cshtml @@ -0,0 +1,27 @@ +@* + Idiomatic Razor -- trivial-substitution. + + Patterns followed, from Microsoft's own documentation: + Razor syntax https://learn.microsoft.com/aspnet/core/mvc/views/razor + Layouts https://learn.microsoft.com/aspnet/core/mvc/views/layout + Partial views https://learn.microsoft.com/aspnet/core/mvc/views/partial + + Strongly-typed @model, C# control flow, and the DEFAULT @expression output -- which HTML-encodes + -- rather than Html.Raw. That is the substantive idiomatic difference from the controlled twin: + a Razor developer reaches for Html.Raw only when the value genuinely is markup, which here is + only the composed-page fragments. Checked by the functional verifier, not the byte gate. +*@ +@using Heddle.Benchmarks.Dotnet.Models +@model SubstitutionContent.SubstitutionModel +@{ Layout = null; } +
    +

    @Model.Title

    +

    @Model.Sku

    +

    @Model.Price

    +

    @Model.Brand

    +

    @Model.Category

    +

    @Model.Availability

    + +

    @Model.Summary

    +

    @Model.Rating

    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/composed-page.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/composed-page.scriban new file mode 100644 index 00000000..cbeda2c6 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/composed-page.scriban @@ -0,0 +1,29 @@ +{{## Idiomatic Scriban -- composed-page. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + The capture-then-include layout idiom: the page captures its body into + body_content, then includes the layout, which emits the captured slot at its body + position -- Scriban's documented equivalent of a live body slot. The slider body is the + SAME as the controlled track's: the verifier's calibration pin (RemovedSegment = the + slider fragment) fails an empty body, deliberately. Checked by the functional verifier, + not the byte gate. Note the multi-line comment delimiters: the single-line form ends at + the first newline, which would leave the doc URLs to parse as expressions. ##}} + +{{ capture body_content }} +
    +
    +
    +
    +
    + + + +
    +
    +
    +{{ end }} +{{ include 'layout' }} diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/conditional-heavy.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/conditional-heavy.scriban new file mode 100644 index 00000000..3e3da016 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/conditional-heavy.scriban @@ -0,0 +1,27 @@ +{{## Idiomatic Scriban -- conditional-heavy. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + The note text is composed template-side as `note ` plus the seq substitution -- + the model carries data, never display strings. Checked by the functional + verifier, not the byte gate. Note the multi-line comment delimiters: the single-line + form ends at the first newline, which would leave the doc URLs to parse as + expressions. ##}} + +
      + {{~ for r in rows ~}} +
    • + {{~ if r.is_bronze ~}}bronze + {{~ else if r.is_silver ~}}silver + {{~ else if r.is_gold ~}}gold + {{~ else ~}}platinum + {{~ end ~}} + {{ r.name }} + {{~ if r.has_note ~}}note {{ r.seq }}{{~ end ~}} + {{~ if r.is_active ~}}active{{~ end ~}} +
    • + {{~ end ~}} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/encoded-loop.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/encoded-loop.scriban new file mode 100644 index 00000000..f915e436 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/encoded-loop.scriban @@ -0,0 +1,20 @@ +{{## Idiomatic Scriban -- encoded-loop. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + + + {{~ for item in items ~}} + + + + + {{~ end ~}} +
    {{ item.name | html.escape }}{{ item.comment | html.escape }}
    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/fortunes-encoded.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/fortunes-encoded.scriban new file mode 100644 index 00000000..118a690d --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/fortunes-encoded.scriban @@ -0,0 +1,24 @@ +{{## Idiomatic Scriban -- fortunes-encoded. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + + + +Fortunes + + + + {{~ for r in rows ~}} + + {{~ end ~}} +
    idmessage
    {{ r.id }}{{ r.message | html.escape }}
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/fragment-heavy.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/fragment-heavy.scriban new file mode 100644 index 00000000..c24f7721 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/fragment-heavy.scriban @@ -0,0 +1,28 @@ +{{## Idiomatic Scriban -- fragment-heavy. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Per-row dispatch through Scriban's native switch form, `case`/`when` (the idiomatic-track + allowance for this workload), selecting one of the four fragment partials; the + card partial nests badge + price against the row's promo -- the one nesting level. + Checked by the functional verifier, not the byte gate. Note the multi-line comment + delimiters: the single-line form ends at the first newline, which would leave the doc + URLs to parse as expressions. ##}} + +
    + {{~ for item in items ~}} + {{~ case item.kind ~}} + {{~ when 'tile' ~}} + {{ include 'tile' }} + {{~ when 'card' ~}} + {{ include 'card' }} + {{~ when 'media' ~}} + {{ include 'media-row' }} + {{~ else ~}} + {{ include 'stat' }} + {{~ end ~}} + {{~ end ~}} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/large-loop.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/large-loop.scriban new file mode 100644 index 00000000..2f1619a7 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/large-loop.scriban @@ -0,0 +1,16 @@ +{{## Idiomatic Scriban -- large-loop. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + The display name is composed template-side as `row-` plus the value substitution -- + the model carries data, never display strings. Checked by the functional + verifier, not the byte gate. Note the multi-line comment delimiters: the single-line + form ends at the first newline, which would leave the doc URLs to parse as + expressions. ##}} + +{{~ for item in items ~}} + row-{{ item.value }}{{ item.value }} +{{~ end ~}} diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/mixed-page.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/mixed-page.scriban new file mode 100644 index 00000000..b48e1191 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/mixed-page.scriban @@ -0,0 +1,53 @@ +{{## Idiomatic Scriban -- mixed-page. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Single-file by rule (layout composition is composed-page's dimension). The + display SKU (`MX-` plus sku_number) and the blurb sentence around batch are composed + template-side -- the model carries data, never display strings. Checked by + the functional verifier, not the byte gate. Note the multi-line comment delimiters: the + single-line form ends at the first newline, which would leave the doc URLs to parse as + expressions. ##}} + + + + + + {{ page_title }} + + + +
    +

    {{ store_name }}

    + +
    +
    + {{~ if show_banner ~}} + + {{~ end ~}} +
    +

    {{ hero_heading }}

    +

    {{ hero_tagline }}

    +
    +
    + {{~ for p in products ~}} +
    +

    {{ p.name }}

    +

    MX-{{ p.sku_number }}

    +

    {{ p.price }}

    + {{~ if p.on_sale ~}}

    On sale

    {{~ end ~}} +

    A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

    +
    + {{~ end ~}} +
    + {{~ if show_debug_panel ~}}
    debug
    {{~ end ~}} +
    +
    +

    {{ footer_note }}

    +

    {{ store_name }} {{ year }} {{ support_email }}

    +
    + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/alert-below.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/alert-below.scriban new file mode 100644 index 00000000..5a47e449 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/alert-below.scriban @@ -0,0 +1,12 @@ +{{## Idiomatic Scriban -- composed-page alert-below chrome fragment (pinned empty). + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/alert-top.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/alert-top.scriban new file mode 100644 index 00000000..678d52f0 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/alert-top.scriban @@ -0,0 +1,13 @@ +{{## Idiomatic Scriban -- composed-page alert-banner chrome fragment. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + +
    holiday shipping
    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/assets-scripts.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/assets-scripts.scriban new file mode 100644 index 00000000..79ccd130 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/assets-scripts.scriban @@ -0,0 +1,13 @@ +{{## Idiomatic Scriban -- composed-page asset scripts chrome fragment. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/assets-styles.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/assets-styles.scriban new file mode 100644 index 00000000..2581e5f9 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/assets-styles.scriban @@ -0,0 +1,13 @@ +{{## Idiomatic Scriban -- composed-page asset styles chrome fragment. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/badge.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/badge.scriban new file mode 100644 index 00000000..a42780d7 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/badge.scriban @@ -0,0 +1,13 @@ +{{## Idiomatic Scriban -- fragment-heavy badge partial. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Renders the promo badge from the scope-shared row's promo. Checked by the functional + verifier, not the byte gate. Note the multi-line comment delimiters: the single-line + form ends at the first newline, which would leave the doc URLs to parse as + expressions. ##}} + +{{ item.promo.label }} diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/body-end-scripts.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/body-end-scripts.scriban new file mode 100644 index 00000000..e73345de --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/body-end-scripts.scriban @@ -0,0 +1,13 @@ +{{## Idiomatic Scriban -- composed-page body-end scripts chrome fragment. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/body-scripts.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/body-scripts.scriban new file mode 100644 index 00000000..aff9762b --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/body-scripts.scriban @@ -0,0 +1,13 @@ +{{## Idiomatic Scriban -- composed-page body scripts chrome fragment. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/card.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/card.scriban new file mode 100644 index 00000000..46986cbf --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/card.scriban @@ -0,0 +1,19 @@ +{{## Idiomatic Scriban -- fragment-heavy card partial. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Renders one card row from the scope-shared loop variable `item`, nesting the badge and + price partials against the row's promo -- the workload's one nesting level. Checked by + the functional verifier, not the byte gate. Note the multi-line comment delimiters: the + single-line form ends at the first newline, which would leave the doc URLs to parse as + expressions. ##}} + +
    +

    {{ item.name }}

    + {{ include 'badge' }} + {{ include 'price' }} +

    {{ item.value }}

    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/custom-styles.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/custom-styles.scriban new file mode 100644 index 00000000..ec216e4f --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/custom-styles.scriban @@ -0,0 +1,13 @@ +{{## Idiomatic Scriban -- composed-page custom styles chrome fragment. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + +/* CSS Comment Test */ diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/head-scripts.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/head-scripts.scriban new file mode 100644 index 00000000..46c58bb9 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/head-scripts.scriban @@ -0,0 +1,13 @@ +{{## Idiomatic Scriban -- composed-page head scripts chrome fragment. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/layout.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/layout.scriban new file mode 100644 index 00000000..2811c7d2 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/layout.scriban @@ -0,0 +1,142 @@ +{{## Idiomatic Scriban -- composed-page layout. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + The layout half of the capture-then-include idiom: the full page chrome as + literal template text (no text lives in the C# tier), the captured + body_content emitted at the body slot, the inert chrome fragments included from the + per-fragment partial library, and the structured nav rendered by nested for loops over + nested partials (mega-menu -> nav-column -> nav-section -> nav-link, scope-shared loop + variables per Scriban's include semantics). Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + + + + + + + + + + + Title + + + + + + + + + {{ include 'assets-styles' }} + + {{ include 'head-scripts' }} + + + {{ include 'body-scripts' }} +
    +
    + +
    +
    +
    +
    + {{ include 'alert-top' }} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + {{ for menu in nav.menus }}{{ include 'mega-menu' }}{{ end }} +
    +
    +
    + {{ include 'alert-below' }} +
    +
    + {{ body_content }} +
    +
    +
    +
    +
    + +
    +
    + {{ include 'assets-scripts' }} + + {{ include 'body-end-scripts' }} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/media-row.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/media-row.scriban new file mode 100644 index 00000000..4fe6b081 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/media-row.scriban @@ -0,0 +1,20 @@ +{{## Idiomatic Scriban -- fragment-heavy media-row partial. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Renders one media row from the scope-shared loop variable `item`; the image source and + the caption are composed template-side as literal-plus-substitution -- the + model carries data, never display strings. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + +
    + {{ item.name }} +
    +

    {{ item.name }}

    +

    Caption for {{ item.name }}

    +
    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/mega-menu.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/mega-menu.scriban new file mode 100644 index 00000000..2528c397 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/mega-menu.scriban @@ -0,0 +1,26 @@ +{{## Idiomatic Scriban -- composed-page mega-menu nav partial. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Renders one mega menu from the scope-shared loop variable `menu`; each tab with a + dropdown nests the nav-column partial. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + +
    +
      + {{~ for tab in menu.tabs ~}} +
    • + {{ tab.label }} + {{~ if tab.has_dropdown ~}} +
      + {{~ for column in tab.columns }}{{ include 'nav-column' }}{{ end ~}} +
      + {{~ end ~}} +
    • + {{~ end ~}} +
    +
    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/nav-column.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/nav-column.scriban new file mode 100644 index 00000000..956111f1 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/nav-column.scriban @@ -0,0 +1,16 @@ +{{## Idiomatic Scriban -- composed-page nav-column partial. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Renders one nav column from the scope-shared loop variable `column`, nesting the + nav-section partial. Serves both the mega-menu dropdowns and the footer columns. + Checked by the functional verifier, not the byte gate. Note the multi-line comment + delimiters: the single-line form ends at the first newline, which would leave the doc + URLs to parse as expressions. ##}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/nav-link.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/nav-link.scriban new file mode 100644 index 00000000..b77388dc --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/nav-link.scriban @@ -0,0 +1,13 @@ +{{## Idiomatic Scriban -- composed-page nav-link partial. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Renders one nav link from the scope-shared loop variable `link`. Checked by the + functional verifier, not the byte gate. Note the multi-line comment delimiters: the + single-line form ends at the first newline, which would leave the doc URLs to parse as + expressions. ##}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/nav-section.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/nav-section.scriban new file mode 100644 index 00000000..c3eb0813 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/nav-section.scriban @@ -0,0 +1,21 @@ +{{## Idiomatic Scriban -- composed-page nav-section partial. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Renders one nav section from the scope-shared loop variable `section`: the title (linked + or plain on the precomputed title_linked boolean) and the link list through the nav-link + partial. Checked by the functional verifier, not the byte gate. Note the multi-line + comment delimiters: the single-line form ends at the first newline, which would leave + the doc URLs to parse as expressions. ##}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/price.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/price.scriban new file mode 100644 index 00000000..15171c09 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/price.scriban @@ -0,0 +1,14 @@ +{{## Idiomatic Scriban -- fragment-heavy price partial. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Renders the display price from the scope-shared row's promo: the whole-currency int plus + the literal `.99` -- the template composes display text, the model carries data. + Checked by the functional verifier, not the byte gate. Note the multi-line comment + delimiters: the single-line form ends at the first newline, which would leave the doc + URLs to parse as expressions. ##}} + +

    {{ item.promo.price }}.99

    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/secondary-retail-menu.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/secondary-retail-menu.scriban new file mode 100644 index 00000000..0196df17 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/secondary-retail-menu.scriban @@ -0,0 +1,128 @@ +{{## Idiomatic Scriban -- composed-page secondary retail menu chrome fragment. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/secondary-wholesale-menu.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/secondary-wholesale-menu.scriban new file mode 100644 index 00000000..ed877c40 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/secondary-wholesale-menu.scriban @@ -0,0 +1,150 @@ +{{## Idiomatic Scriban -- composed-page secondary wholesale menu chrome fragment. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + + diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/stat.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/stat.scriban new file mode 100644 index 00000000..1dd14ef8 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/stat.scriban @@ -0,0 +1,17 @@ +{{## Idiomatic Scriban -- fragment-heavy stat partial. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Renders one stat row from the scope-shared loop variable `item`. Checked by the + functional verifier, not the byte gate. Note the multi-line comment delimiters: the + single-line form ends at the first newline, which would leave the doc URLs to parse as + expressions. ##}} + +
    + {{ item.name }} + {{ item.value }} + {{ item.delta }} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/shared/tile.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/shared/tile.scriban new file mode 100644 index 00000000..299d1b47 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/shared/tile.scriban @@ -0,0 +1,17 @@ +{{## Idiomatic Scriban -- fragment-heavy tile partial. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Renders one tile row from the scope-shared loop variable `item`. Checked by the + functional verifier, not the byte gate. Note the multi-line comment delimiters: the + single-line form ends at the first newline, which would leave the doc URLs to parse as + expressions. ##}} + +
    +

    {{ item.name }}

    +

    {{ item.value }}

    + {{ item.badge }} +
    diff --git a/benchmarks/dotnet/templates/idiomatic/scriban/trivial-substitution.scriban b/benchmarks/dotnet/templates/idiomatic/scriban/trivial-substitution.scriban new file mode 100644 index 00000000..297073a3 --- /dev/null +++ b/benchmarks/dotnet/templates/idiomatic/scriban/trivial-substitution.scriban @@ -0,0 +1,23 @@ +{{## Idiomatic Scriban -- trivial-substitution. + + Patterns followed, from Scriban's own documentation: + language https://github.com/scriban/scriban/blob/master/doc/language.md + builtins/html https://github.com/scriban/scriban/blob/master/doc/builtins.md#html-functions + runtime/includes https://github.com/scriban/scriban/blob/master/doc/runtime.md + + Uses Scriban's whitespace-control markers, its for/if statements, and the documented + html.escape builtin on untrusted values. Checked by the functional verifier, not the + byte gate. Note the multi-line comment delimiters: the single-line form ends at the + first newline, which would leave the doc URLs to parse as expressions. ##}} + +
    +

    {{ title }}

    +

    {{ sku }}

    +

    {{ price }}

    +

    {{ brand }}

    +

    {{ category }}

    +

    {{ availability }}

    + +

    {{ summary }}

    +

    {{ rating }}

    +
    diff --git a/benchmarks/go/.gitattributes b/benchmarks/go/.gitattributes new file mode 100644 index 00000000..30d7a570 --- /dev/null +++ b/benchmarks/go/.gitattributes @@ -0,0 +1,4 @@ +# Everything in the Go harness is ordinary text — no attribute pins needed. (The former +# internal/model/data -text pin died with the embedded composed-page blobs: all literal +# chrome moved into the template tier, and the nav model loads from the corpus fixture at +# runtime.) diff --git a/benchmarks/go/README.md b/benchmarks/go/README.md new file mode 100644 index 00000000..45e5637b --- /dev/null +++ b/benchmarks/go/README.md @@ -0,0 +1,113 @@ +# Go benchmark harness (Phase 6 — go) + +The Go module for the cross-stack benchmarks: the stdlib engine +(text/template on the raw suites, html/template on the encoded suite) and templ, both +fairness tracks, gated against the Phase 1 golden corpus at +`benchmarks/dotnet/GoldenCorpus/` (read repo-relative; the corpus does not move). + +Module: `heddle.dev/benchmarks/go` (repo-local, never published). Pins: `go 1.26` / +`toolchain go1.26.5`; `github.com/a-h/templ v0.3.1020` (runtime require + CLI `tool` +directive); benchstat via `tool golang.org/x/perf/cmd/benchstat` at +`golang.org/x/perf v0.0.0-20260709024250-82a0b07e230d`. Generated `*_templ.go` files are +committed; regenerate with the pinned CLI only: + +``` +go tool templ generate +``` + +## How to run + +From `benchmarks/go/`: + +``` +go vet ./... # static checks +go test ./internal/... # unit tests: N1–N5 pipeline, verifier calibration, alphabet assert, model pins, S1 probes +go test ./suites # the phase's parity command: TestMain runs every registered gate before anything times +``` + +Layout ([go-harness-and-measurement.md](../docs/go-harness-and-measurement.md) §Module layout): + +- `internal/corpus/` — corpus loader + manifest SHA-256 check, N1–N5 pipeline (N3b comparison + strip included), controlled byte gate + encoded security floor, idiomatic verifier, + untrusted-data alphabet assert. +- `internal/model/` — the eight pinned models (C# field spellings, `strconv`/`%d` numerics); + the composed-page model is pure structured data (`ComposedModel{Nav}` — the model carries data only; templates hold all text), + loaded once from the corpus fixture `fixtures/composed-page/nav.json`; every fragment of + literal page text lives in the templates as `{{define}}`d chrome fragments, never in Go + data files. +- `internal/spike/` — the S1 templ feasibility probes (evidence, excluded from timing). +- `suites/` — `gate_test.go` (TestMain + gate registry; engine cells register here as they + land), later `bench_test.go` / `coldparse_test.go`. + +Benchmarks, the runner script (`run-benchmarks.ps1`), and the engine ports are all landed. + +## Templ feasibility spike results + +Executed 2026-07-21 at the pinned toolchain (`go1.26.5`, templ `v0.3.1020`, Windows 11). +Command: `go test ./internal/spike/ -v` (probes are the committed tests in +`internal/spike/spike_test.go`; templ sources in `internal/spike/spike.templ`, generated code +committed alongside). **Verdict: clean pass on all four probes — the expected outcome of +[go-templ-feasibility.md](../docs/go-templ-feasibility.md). +No non-whitespace divergence surfaced, so no `EXCLUSIONS.md` and no `internal/spike/attempts/` +exist; the harness proceeded on this result.** + +### P1 — smallest-workload byte gate: PASS (byte-identical, pre-N3b) + +`trivial-substitution.templ` authored densely renders, after N1–N4, **byte-identical to the +committed oracle even before the N3b comparison strip** — templ's collapser found nothing to +change in the dense form, and templ emitted the void element as `` +(no self-closing slash), matching the oracle. Observed normalized output (338 bytes = the +oracle's byte length): + +``` +

    Heddle Handbook

    HB-2001

    +``` + +Fixed-point check: `

    { a } { b } { c }

    ` with single literal spaces renders +`

    Mercantile 2026 support at mercantile.example

    ` — **the single spaces survive +verbatim** (F3 fixed point confirmed; the mixed-page footer construct is safe). + +### P2 — escaper bytes: PASS (every spelling inside the N5 table) + +Text path (fortunes-shaped row over `& < > " '` + Japanese) — observed bytes: + +``` +1& < > " ' こんにちは +``` + +Attribute path (encoded-loop-shaped row, `data-tag={ tag }`, pinned row-0 data) — observed +bytes (templ auto-quotes the attribute with `"` and uses the same escaper on both paths): + +``` +item <0> & "co"'q' & <angle> "d" こんにちは 0 +``` + +Emitted spellings: `& < > " '` on **both** paths (templ.EscapeString → +stdlib html.EscapeString; the attribute path did *not* emit `"`) — **every spelling is +inside the N5 table**; the only non-canonical spelling is `"`, which N5 maps to `"`, +after which both outputs equal the canonical oracle bytes exactly. The Japanese strings pass +through byte-intact, and escape-free data round-trips unescaped (raw-suite no-op premise +confirmed). The non-whitespace contingency (a spelling outside N5) did **not** occur. + +### P3 — style passthrough: PASS (byte-identical) + +The exact mixed-page ``) — F4 executed and confirmed; the `@templ.Raw` fallback of [go-port-mapping.md](../docs/go-port-mapping.md) rule 6 is +**not** needed; mixed-page will be authored with a literal ` +} + +// P4 — inter-statement whitespace (evidence only): two consecutive @templ.Raw calls on +// separate lines whose payloads reproduce the composed-page CSS-comment neighborhood +// (comp-assets-styles → comp-custom-styles → comp-head-scripts, the one non-tag-flanked +// fragment boundary of the oracle). +templ boundary(link string, css string, script string) { + @templ.Raw(link) + @templ.Raw(css) + @templ.Raw(script) +} diff --git a/benchmarks/go/internal/spike/spike_templ.go b/benchmarks/go/internal/spike/spike_templ.go new file mode 100644 index 00000000..65f210f1 --- /dev/null +++ b/benchmarks/go/internal/spike/spike_templ.go @@ -0,0 +1,453 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Feasibility spike for the templ controlled track: four probes (P1–P4) pin the + +// byte-level behaviors the controlled ports rely on, executed at the pinned toolchain + +// (Go 1.26.5, templ v0.3.1020). Throwaway-quality but committed in-tree as evidence; + +// excluded from benchmark runs. Generated via `go tool templ generate` (the pinned CLI + +// through the go.mod tool directive). + +package spike + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +// P1 — smallest-workload byte gate: trivial-substitution authored densely as the pinned +// one-line
    card, ten substitutions in pinned order including the two attribute +// positions. +func trivialSubstitution(m model.SubstitutionModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(m.Title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 14, Col: 23} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(m.Sku) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 14, Col: 52} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(m.Price) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 14, Col: 84} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(m.Brand) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 14, Col: 116} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(m.Category) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 14, Col: 149} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(m.Availability) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 14, Col: 188} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(m.Summary) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 14, Col: 279} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(m.Rating) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 14, Col: 313} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// P1 (second half) — the mixed-page footer construct: string expressions separated by +// single literal spaces; whitespace collapsing maps a lone space to itself (fixed point). +func spacedExpressions(a string, b string, c string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var12 := templ.GetChildren(ctx) + if templ_7745c5c3_Var12 == nil { + templ_7745c5c3_Var12 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(a) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 20, Col: 7} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(b) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 20, Col: 13} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(c) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 20, Col: 19} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// P2 — escaper bytes, text path: a one-row fortunes-shaped fragment. +func fortunesRow(id string, message string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var16 := templ.GetChildren(ctx) + if templ_7745c5c3_Var16 == nil { + templ_7745c5c3_Var16 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var17 string + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(id) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 25, Col: 13} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var18 string + templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(message) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 25, Col: 33} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// P2 — escaper bytes, attribute path: an encoded-loop-shaped row (data-tag={ tag } plus +// two text expressions). +func encodedRow(tag string, name string, comment string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var19 := templ.GetChildren(ctx) + if templ_7745c5c3_Var19 == nil { + templ_7745c5c3_Var19 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 31, Col: 32} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var22 string + templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(comment) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/spike/spike.templ`, Line: 31, Col: 52} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// P3 — style passthrough: the exact mixed-page ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// P4 — inter-statement whitespace (evidence only): two consecutive @templ.Raw calls on +// separate lines whose payloads reproduce the composed-page CSS-comment neighborhood +// (comp-assets-styles → comp-custom-styles → comp-head-scripts, the one non-tag-flanked +// fragment boundary of the oracle). +func boundary(link string, css string, script string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var24 := templ.GetChildren(ctx) + if templ_7745c5c3_Var24 == nil { + templ_7745c5c3_Var24 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templ.Raw(link).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.Raw(css).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.Raw(script).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/spike/spike_test.go b/benchmarks/go/internal/spike/spike_test.go new file mode 100644 index 00000000..5896547b --- /dev/null +++ b/benchmarks/go/internal/spike/spike_test.go @@ -0,0 +1,222 @@ +// Feasibility-spike probe execution: each test executes one probe and pins its observed +// bytes; the results are additionally written up in the harness README. +package spike + +import ( + "context" + "strings" + "testing" + + "github.com/a-h/templ" + + "heddle.dev/benchmarks/go/internal/corpus" + "heddle.dev/benchmarks/go/internal/model" +) + +func render(t *testing.T, c templ.Component) string { + t.Helper() + var b strings.Builder + if err := c.Render(context.Background(), &b); err != nil { + t.Fatalf("render failed: %v", err) + } + return b.String() +} + +// ---- P1 — smallest-workload byte gate -------------------------------------------------------- + +func TestP1TrivialSubstitutionPassesTheByteGate(t *testing.T) { + output := render(t, trivialSubstitution(model.Substitution)) + + // The full controlled gate: N1–N4 pipeline, N3b strip on both sides, byte compare + // against the committed corpus entry. + if err := corpus.CheckControlled("trivial-substitution", "raw", "templ-spike", + func() string { return output }); err != nil { + t.Fatal(err) + } + + // Evidence: is the normalized candidate byte-identical to the stored oracle even + // BEFORE the N3b comparison strip? + golden, err := corpus.LoadGolden("trivial-substitution") + if err != nil { + t.Fatal(err) + } + normalized := corpus.NormalizeRaw(output) + if normalized == golden { + t.Log("P1: normalized output is byte-identical to the oracle pre-N3b (no whitespace divergence at all)") + } else { + t.Logf("P1: whitespace-only divergence reconciled by N3/N3b (normalized %d bytes vs oracle %d)", + len(normalized), len(golden)) + } +} + +func TestP1SingleSpacesBetweenExpressionsSurviveVerbatim(t *testing.T) { + // The mixed-page footer construct: `{ a } { b } { c }` separated by single literal + // spaces. Whitespace collapsing maps a lone space to itself (fixed point) — the spaces must + // survive verbatim in the rendered output. + output := render(t, spacedExpressions("Mercantile", "2026", "support at mercantile.example")) + const want = "

    Mercantile 2026 support at mercantile.example

    " + if output != want { + t.Fatalf("single spaces did not survive verbatim:\n want %q\n got %q", want, output) + } +} + +// ---- P2 — escaper bytes ---------------------------------------------------------------------- + +// n5Table lists every spelling the contract's N5 table recognizes for the five +// markup-significant characters; any escaper output must be composed of literal safe text +// plus spellings from this set. +var n5Table = []string{ + "&", "&", "&", + "<", "<", "<", + ">", ">", ">", + """, """, """, + "'", "'", "'", +} + +// assertSpellingsInsideN5 walks every entity-shaped span ("&…;") of the escaped output and +// asserts it is one of the N5 table's recognized spellings. +func assertSpellingsInsideN5(t *testing.T, label, escaped string) { + t.Helper() + for i := 0; i < len(escaped); i++ { + if escaped[i] != '&' { + continue + } + end := strings.IndexByte(escaped[i:], ';') + if end < 0 { + t.Fatalf("%s: unterminated entity at %d in %q", label, i, escaped) + } + entity := escaped[i : i+end+1] + found := false + for _, spelling := range n5Table { + if entity == spelling { + found = true + break + } + } + if !found { + t.Fatalf("%s: escaper spelling %q is OUTSIDE the N5 table — a non-whitespace divergence the normalization pipeline cannot reconcile", label, entity) + } + i += end + } +} + +func TestP2TextPathEscaperBytes(t *testing.T) { + // A fortunes-shaped row whose message covers all five specials plus Japanese. + const message = `& < > " ' こんにちは` + output := render(t, fortunesRow("1", message)) + t.Logf("P2 text path: %q", output) + + // Every emitted spelling must be inside the N5 table. + assertSpellingsInsideN5(t, "text path", output) + + // Pin the exact observed spellings (templ.EscapeString → html.EscapeString: five + // characters, decimal quotes). + const wantRow = `1& < > " ' こんにちは` + if output != wantRow { + t.Fatalf("text-path bytes changed:\n want %q\n got %q", wantRow, output) + } + + // After N5 the output must carry the canonical spellings, byte-for-byte. + canonical := corpus.N5Canonicalize(output) + const wantCanonical = `1& < > " ' こんにちは` + if canonical != wantCanonical { + t.Fatalf("N5 canonicalization mismatch:\n want %q\n got %q", wantCanonical, canonical) + } + + // The Japanese string is byte-intact (the stdlib escaper touches only the five ASCII). + if !strings.Contains(output, "こんにちは") { + t.Fatal("Japanese string must pass through byte-intact") + } +} + +func TestP2AttributePathEscaperBytes(t *testing.T) { + // An encoded-loop-shaped row: data-tag={ tag } attribute plus two text expressions, + // using the pinned row-0 values (tag covers & and '; name covers < > and "). + row := model.EncodedLoop.Items[0] + output := render(t, encodedRow(row.Tag, row.Name, row.Comment)) + t.Logf("P2 attribute path: %q", output) + + assertSpellingsInsideN5(t, "attribute path", output) + + // Pin the exact observed bytes: templ auto-quotes the attribute and escapes both paths + // with the same five-character decimal-quote table. + const wantRow = `item <0> & "co"'q' & <angle> "d" こんにちは 0` + if output != wantRow { + t.Fatalf("attribute-path bytes changed:\n want %q\n got %q", wantRow, output) + } + + // After N5, the bytes equal the oracle's canonical row 0 exactly. + const wantCanonical = `item <0> & "co"'q' & <angle> "d" こんにちは 0` + if canonical := corpus.N5Canonicalize(output); canonical != wantCanonical { + t.Fatalf("N5 canonicalization mismatch:\n want %q\n got %q", wantCanonical, canonical) + } +} + +func TestP2EscapeFreeDataRoundTripsUnescaped(t *testing.T) { + // '+'-free (and escapable-free) data round-trips byte-identical — the raw suites' + // no-op-escaper premise. + output := render(t, fortunesRow("7", "Computers make very fast, very accurate mistakes.")) + const want = "7Computers make very fast, very accurate mistakes." + if output != want { + t.Fatalf("escape-free data must round-trip unescaped:\n want %q\n got %q", want, output) + } +} + +// ---- P3 — style passthrough ------------------------------------------------------------------ + +// styleCSS is the exact mixed-page " + if !strings.HasPrefix(output, prefix) || !strings.HasSuffix(output, suffix) { + t.Fatalf("style element shape changed: %q", output) + } + content := output[len(prefix) : len(output)-len(suffix)] + if content == styleCSS { + return // rendered without any changes — no fallback needed + } + // Only a confirmed NON-whitespace change routes to the @templ.Raw fallback; + // a whitespace-only difference passes via N3b. + if corpus.N3bStrip(content) == corpus.N3bStrip(styleCSS) { + t.Logf("P3: whitespace-only difference in style content (reconciled by N3b): %q", content) + return + } + t.Fatalf("P3: NON-whitespace change to style content — the @templ.Raw fallback branch applies:\n want %q\n got %q", styleCSS, content) +} + +// ---- P4 — inter-statement whitespace (evidence only) ----------------------------------------- + +func TestP4ComposedPageBoundaryBytes(t *testing.T) { + // The composed-page CSS-comment neighborhood: assets_styles → custom_styles → + // head_scripts, issued as consecutive @templ.Raw calls on separate lines. The + // fragments are literals here: all composed-page chrome text moved out of the + // model tier into the templates, so the probe pins the bytes it exercises directly + // (byte-identical to the retired embedded copies it originally read). + link := `` + css := `/* CSS Comment Test */` + script := `` + output := render(t, boundary(link, css, script)) + + // Evidence: the exact bytes templ emits between consecutive statement nodes. + zeroSeparator := link + css + script + switch { + case output == zeroSeparator: + t.Log("P4: templ emits ZERO separator bytes between consecutive @templ.Raw nodes — boundary already byte-exact vs the oracle") + case corpus.N3bStrip(output) == corpus.N3bStrip(zeroSeparator): + t.Logf("P4: whitespace-only separator between @templ.Raw nodes (passes via N3b). Observed output: %q", output) + default: + t.Fatalf("P4: NON-whitespace divergence at the inter-statement boundary:\n want (stripped) %q\n got %q", + zeroSeparator, output) + } + + // The oracle's non-tag-flanked boundary must survive the comparison projection: the + // stripped candidate must contain the oracle's `/>/*CSSCommentTest*//*CSSCommentTest*/holiday shipping{{end}} +{{define "secondary_wholesale_menu"}} {{end}} +{{define "secondary_retail_menu"}} {{end}} +{{define "alert_below"}}{{end}} +{{define "assets_styles"}}{{end}} +{{define "assets_scripts"}}{{end}} +{{define "custom_styles"}}/* CSS Comment Test */{{end}} +{{define "head_scripts"}}{{end}} +{{define "body_scripts"}}{{end}} +{{define "body_end_scripts"}}{{end}}` + +// composedLayoutSrc is the definition-only layout parse: the four overridable section +// defaults, the four nav fragment definitions (nested — menu → column → +// section → link, dispatching on the precomputed .TitleLinked/.HasDropdown booleans), and +// the "layout" definition holding the full literal chrome with {{block "body" .}} at the +// body-slot position and {{range .Nav.Menus}}/{{range .Nav.FooterColumns}} at the nav +// call sites. Parsing it renders nothing. +const composedLayoutSrc = `{{define "meta"}}Title{{end}} +{{define "socialmeta"}} + + {{end}} +{{define "page_scripts"}}{{end}} +{{define "endpage_scripts"}}{{end}} +{{define "nav_link"}}{{end}} +{{define "nav_section"}}{{end}} +{{define "nav_column"}}{{end}} +{{define "mega_menu"}}
      {{range .Tabs}}
    • {{.Label}}{{if .HasDropdown}}
      {{range .Columns}}{{template "nav_column" .}}{{end}}
      {{end}}
    • {{end}}
    {{end}} +{{define "layout"}} + + + + + + + + + {{template "meta"}} + {{template "socialmeta"}} + + + + + + {{template "assets_styles"}} + + {{template "head_scripts"}} + + + {{template "body_scripts"}} +
    +
    + +
    +
    +
    +
    + {{template "alert_top"}} +
    +
    +
    +
    +
    + + +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    +
    + + {{range .Nav.Menus}}{{template "mega_menu" .}}{{end}} +
    +
    +
    + {{template "alert_below"}} +
    +
    + {{block "body" .}}{{end}} +
    +
    +
    +
    +
    + +
    +
    + {{template "assets_scripts"}} + + {{template "page_scripts"}} + {{template "endpage_scripts"}} + {{template "body_end_scripts"}} + +{{end}}` + +// composedHomeSrc is the page parse: {{define "body"}} carries the slider markup (the +// verifier's removed-segment calibration pin — an empty body fails) and, being a later +// non-empty definition in the associated set, overrides the layout's empty block default; +// the root action then renders the layout. +const composedHomeSrc = `{{define "body"}}
    +
    +
    +
    +
    + + + +
    +
    +
    {{end}}{{template "layout" .}}` + +// ---- workload 2 — trivial-substitution (text/template) --------------------------------------- + +// Dense one-line
    card, ten {{.Member}} substitutions in pinned order, including +// the two attribute positions. +const trivialSubstitutionSrc = `

    {{.Title}}

    {{.Sku}}

    {{.Price}}

    {{.Brand}}

    {{.Category}}

    {{.Availability}}

    {{.Summary}}

    {{.Rating}}

    ` + +// ---- workload 3 — large-loop (text/template) ------------------------------------------------- + +// The display name row-{i} is composed by the template as the literal `row-` + the value +// substitution (the model carries only the int). text/template renders ints via fmt +// (%v), identical bytes to strconv.Itoa. +const largeLoopSrc = `{{range .Items}}row-{{.Value}}{{.Value}}{{end}}` + +// ---- workload 4 — mixed-page (text/template) ------------------------------------------------- + +// The pinned skeleton transcribed line-for-line (line breaks between sibling elements are +// N2/N3-erased; the + + +
    +

    {{.StoreName}}

    + +
    +
    +{{if .ShowBanner}}{{end}} +
    +

    {{.HeroHeading}}

    +

    {{.HeroTagline}}

    +
    +
    +{{range .Products}}

    {{.Name}}

    MX-{{.SkuNumber}}

    {{.Price}}

    {{if .OnSale}}

    On sale

    {{end}}

    A dependable workshop staple from batch {{.Batch}}, checked for daily use and backed by our lifetime guarantee.

    {{end}} +
    +{{if .ShowDebugPanel}}
    debug
    {{end}} +
    +
    +

    {{.FooterNote}}

    +

    {{.StoreName}} {{.Year}} {{.SupportEmail}}

    +
    + +` + +// ---- workload 5 — conditional-heavy (text/template) ------------------------------------------ + +// The pinned single-line
      body: four-way chain per row plus the two +// toggles. The note text is composed as the literal `note ` + {{.Seq}}. +const conditionalHeavySrc = `
        {{range .Rows}}
      • {{if .IsBronze}}bronze{{else if .IsSilver}}silver{{else if .IsGold}}gold{{else}}platinum{{end}}{{.Name}}{{if .HasNote}}note {{.Seq}}{{end}}{{if .IsActive}}active{{end}}
      • {{end}}
      ` + +// ---- workload 6 — fragment-heavy (text/template) --------------------------------------------- + +// Six {{define}}s (tile, badge, price, card — which nests badge + price +// against the row's .Promo, the one nesting level — media_row, stat), dispatched per row by +// the boolean {{if .IsTile}}/{{else if}} chain — dispatch stays on precomputed booleans, +// never on the Kind string. Derived display text is composed by the template as +// literal-plus-substitution: /img/{{.Name}}.jpg, Caption for {{.Name}}, +// {{.Promo.Price}} rendered through the price partial as {{.Price}}.99. +const fragmentHeavySrc = `{{define "tile"}}

      {{.Name}}

      {{.Value}}

      {{.Badge}}
      {{end}}{{define "badge"}}{{.Label}}{{end}}{{define "price"}}

      {{.Price}}.99

      {{end}}{{define "card"}}

      {{.Name}}

      {{template "badge" .Promo}}{{template "price" .Promo}}

      {{.Value}}

      {{end}}{{define "media_row"}}
      {{.Name}}

      {{.Name}}

      Caption for {{.Name}}

      {{end}}{{define "stat"}}
      {{.Name}}{{.Value}}{{.Delta}}
      {{end}}
      {{range .Items}}{{if .IsTile}}{{template "tile" .}}{{else if .IsCard}}{{template "card" .}}{{else if .IsMedia}}{{template "media_row" .}}{{else}}{{template "stat" .}}{{end}}{{end}}
      ` + +// ---- workload 7 — fortunes-encoded (html/template) ------------------------------------------- + +// The pinned one-line skeleton; html/template's contextual escaper fires on the +// text-context substitutions ({{.Message}}), with spellings reconciled by N5. +const fortunesEncodedSrc = `Fortunes{{range .Rows}}{{end}}
      idmessage
      {{.Id}}{{.Message}}
      ` + +// ---- workload 8 — encoded-loop (html/template) ----------------------------------------------- + +// {{.Tag}} sits in quoted-attribute context; the other two substitutions in text context. +const encodedLoopSrc = `{{range .Items}}{{end}}
      {{.Name}}{{.Comment}}
      ` + +// ---- parsed templates (once, at package init — the cached-template render path) -------------- + +var ( + composedTpl = func() *texttemplate.Template { + t := texttemplate.New("composed-page") + texttemplate.Must(t.Parse(composedChromeSrc)) + texttemplate.Must(t.Parse(composedLayoutSrc)) + return texttemplate.Must(t.Parse(composedHomeSrc)) + }() + trivialSubstitutionTpl = texttemplate.Must(texttemplate.New("trivial-substitution").Parse(trivialSubstitutionSrc)) + largeLoopTpl = texttemplate.Must(texttemplate.New("large-loop").Parse(largeLoopSrc)) + mixedPageTpl = texttemplate.Must(texttemplate.New("mixed-page").Parse(mixedPageSrc)) + conditionalHeavyTpl = texttemplate.Must(texttemplate.New("conditional-heavy").Parse(conditionalHeavySrc)) + fragmentHeavyTpl = texttemplate.Must(texttemplate.New("fragment-heavy").Parse(fragmentHeavySrc)) + fortunesEncodedTpl = htmltemplate.Must(htmltemplate.New("fortunes-encoded").Parse(fortunesEncodedSrc)) + encodedLoopTpl = htmltemplate.Must(htmltemplate.New("encoded-loop").Parse(encodedLoopSrc)) +) diff --git a/benchmarks/go/internal/stdlibtpl/idiomatic/idiomatic.go b/benchmarks/go/internal/stdlibtpl/idiomatic/idiomatic.go new file mode 100644 index 00000000..8ff93e29 --- /dev/null +++ b/benchmarks/go/internal/stdlibtpl/idiomatic/idiomatic.go @@ -0,0 +1,764 @@ +// Package idiomatic holds the idiomatic-track ports for the stdlib surfaces: text/template on the six raw workloads, +// html/template on the two encoded workloads (same surface split as the controlled +// track). Authoring standard: naturally formatted multi-line +// templates with indentation, {{- -}} trim markers where the Go docs use them, and template +// composition via the {{define}}/{{template}}/{{block}} idiom — the way the official docs +// teach the engine, not the byte-exact controlled shape. These sources may diverge freely +// in whitespace and structure; they are gated by the shared idiomatic verifier +// (.verify.json semantics), not the byte gate. +// +// Official documentation patterns followed here: +// - https://pkg.go.dev/text/template (Actions, Text and spaces / trim markers, +// Nested template definitions, the {{block}} shorthand for define-plus-invoke) +// - https://pkg.go.dev/html/template (same template API; contextual auto-escaping) +package idiomatic + +import ( + htmltemplate "html/template" + texttemplate "text/template" + + "heddle.dev/benchmarks/go/internal/model" +) + +// ---- workload 1 — composed-page (text/template) ---------------------------------------------- +// +// Layout composition with the engine's own documented mechanism (text/template §Nested +// template definitions + the {{block}} action): the layout template carries the full +// literal page chrome (all display text lives in the template tier) with a live +// {{block "body" .}} slot; the page's parse adds a non-empty {{define "body"}} that +// overrides the block's empty default in the associated set. The chrome fragments are +// per-fragment {{define}}s and the structured nav renders through nested definitions +// (menu → column → section → link), branching on the precomputed .HasDropdown / +// .TitleLinked booleans. The slider body is the SAME as the controlled track's — the +// verifier's removed-segment calibration pin is the slider, so an empty body fails, +// deliberately. + +// idiomaticComposedChromeSrc is the definition-only chrome-fragment library: +// parsing it renders nothing; the layout calls each fragment at its composition point. +const idiomaticComposedChromeSrc = `{{define "alert_top"}}
      holiday shipping
      {{end}} +{{define "secondary_wholesale_menu"}} {{end}} +{{define "secondary_retail_menu"}} {{end}} +{{define "alert_below"}}{{end}} +{{define "assets_styles"}}{{end}} +{{define "assets_scripts"}}{{end}} +{{define "custom_styles"}}/* CSS Comment Test */{{end}} +{{define "head_scripts"}}{{end}} +{{define "body_scripts"}}{{end}} +{{define "body_end_scripts"}}{{end}}` + +// idiomaticComposedLayoutSrc is the definition-only layout parse: overridable section +// defaults, the nested nav definitions, and the "layout" definition holding the full +// literal chrome with the {{block "body" .}} slot. +const idiomaticComposedLayoutSrc = `{{define "meta"}}Title{{end}} +{{define "socialmeta"}} + + {{end}} +{{define "page_scripts"}}{{end}} +{{define "endpage_scripts"}}{{end}} + +{{define "nav_link"}}{{end}} + +{{define "nav_section"}} + +{{- end}} + +{{define "nav_column"}} + +{{- end}} + +{{define "mega_menu"}} +
      +
        + {{- range .Tabs}} +
      • + {{.Label}} + {{- if .HasDropdown}} +
        + {{- range .Columns}} + {{template "nav_column" .}} + {{- end}} +
        + {{- end}} +
      • + {{- end}} +
      +
      +{{- end}} + +{{define "layout"}} + + + + + + + + + {{template "meta"}} + {{template "socialmeta"}} + + + + + + {{template "assets_styles"}} + + {{template "head_scripts"}} + + + {{template "body_scripts"}} +
      +
      + +
      +
      +
      +
      + {{template "alert_top"}} +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + {{range .Nav.Menus}}{{template "mega_menu" .}}{{end}} +
      +
      +
      + {{template "alert_below"}} +
      +
      + {{block "body" .}}{{end}} +
      +
      +
      +
      +
      + +
      +
      + {{template "assets_scripts"}} + + {{template "page_scripts"}} + {{template "endpage_scripts"}} + {{template "body_end_scripts"}} + +{{end}}` + +// idiomaticComposedHomeSrc is the page: the body definition (the slider) overriding the +// layout's empty block default, then the root action rendering the layout. +const idiomaticComposedHomeSrc = `{{define "body"}} +
      +
      +
      +
      +
      + + + +
      +
      +
      +{{end}} +{{- template "layout" .}}` + +// ---- workload 2 — trivial-substitution (text/template) --------------------------------------- + +const idiomaticTrivialSubstitutionSrc = `
      +

      {{.Title}}

      +

      {{.Sku}}

      +

      {{.Price}}

      +

      {{.Brand}}

      +

      {{.Category}}

      +

      {{.Availability}}

      + +

      {{.Summary}}

      +

      {{.Rating}}

      +
      +` + +// ---- workload 3 — large-loop (text/template) ------------------------------------------------- + +// Trim markers around the range body, the shape the text/template docs' "Text and spaces" +// section teaches for loop output; the display name is composed as the literal row- + the +// value substitution. +const idiomaticLargeLoopSrc = `{{range .Items -}} + + row-{{.Value}} + {{.Value}} + +{{end -}} +` + +// ---- workload 4 — mixed-page (text/template) ------------------------------------------------- + +// Single-file by rule (layout composition is composed-page's dimension). The display +// SKU is composed as MX-{{.SkuNumber}} and the blurb sentence lives in the template around +// {{.Batch}}. +const idiomaticMixedPageSrc = ` + + + + {{.PageTitle}} + + + +
      +

      {{.StoreName}}

      + +
      +
      + {{if .ShowBanner}}{{end}} +
      +

      {{.HeroHeading}}

      +

      {{.HeroTagline}}

      +
      +
      + {{range .Products -}} +
      +

      {{.Name}}

      +

      MX-{{.SkuNumber}}

      +

      {{.Price}}

      + {{if .OnSale}}

      On sale

      {{end}} +

      A dependable workshop staple from batch {{.Batch}}, checked for daily use and backed by our lifetime guarantee.

      +
      + {{end -}} +
      + {{if .ShowDebugPanel}}
      debug
      {{end}} +
      +
      +

      {{.FooterNote}}

      +

      {{.StoreName}} {{.Year}} {{.SupportEmail}}

      +
      + + +` + +// ---- workload 5 — conditional-heavy (text/template) ------------------------------------------ + +// The note text is composed as the literal note + {{.Seq}}. +const idiomaticConditionalHeavySrc = `
        + {{range .Rows -}} +
      • + {{if .IsBronze -}} + bronze + {{- else if .IsSilver -}} + silver + {{- else if .IsGold -}} + gold + {{- else -}} + platinum + {{- end}} + {{.Name}} + {{if .HasNote}}note {{.Seq}}{{end}} + {{if .IsActive}}active{{end}} +
      • + {{end -}} +
      +` + +// ---- workload 6 — fragment-heavy (text/template) --------------------------------------------- + +// The four-kind dispatch exactly as the docs' nested-template-definition examples show +// it: one named {{define}} per fragment kind plus the badge/price sub-definitions the card +// invokes against its .Promo (the one nesting level), selected per row by the boolean +// {{if}}/{{else if}} chain. Derived display text is composed by the template: +// /img/{{.Name}}.jpg, Caption for {{.Name}}, {{.Price}}.99. +const idiomaticFragmentHeavySrc = `{{define "tile"}} +
      +

      {{.Name}}

      +

      {{.Value}}

      + {{.Badge}} +
      +{{end}} + +{{- define "badge"}}{{.Label}}{{end}} + +{{- define "price"}}

      {{.Price}}.99

      {{end}} + +{{- define "card"}} +
      +

      {{.Name}}

      + {{template "badge" .Promo}}{{template "price" .Promo}} +

      {{.Value}}

      +
      +{{end}} + +{{- define "media_row"}} +
      + {{.Name}} +
      +

      {{.Name}}

      +

      Caption for {{.Name}}

      +
      +
      +{{end}} + +{{- define "stat"}} +
      + {{.Name}} + {{.Value}} + {{.Delta}} +
      +{{end}} + +{{- define "panel"}} +
      + {{- range .Items}} + {{- if .IsTile}}{{template "tile" .}}{{else if .IsCard}}{{template "card" .}}{{else if .IsMedia}}{{template "media_row" .}}{{else}}{{template "stat" .}}{{end}} + {{- end}} +
      +{{end}} + +{{- template "panel" .}}` + +// ---- workload 7 — fortunes-encoded (html/template) ------------------------------------------- + +// html/template's contextual auto-escaper fires on {{.Id}}/{{.Message}}; the authoring is +// otherwise identical to how the html/template docs teach a data-driven page. +const idiomaticFortunesEncodedSrc = ` + + + Fortunes + + + + + {{range .Rows -}} + + + + + {{end -}} +
      idmessage
      {{.Id}}{{.Message}}
      + + +` + +// ---- workload 8 — encoded-loop (html/template) ----------------------------------------------- + +// {{.Tag}} in quoted-attribute context, the other two substitutions in text context — the +// escaper picks the context per the html/template package docs. +const idiomaticEncodedLoopSrc = ` + {{range .Items -}} + + + + + {{end -}} +
      {{.Name}}{{.Comment}}
      +` + +// ---- parsed templates (once, at package init — the cached-template render path) -------------- + +var ( + idiomaticComposedTpl = func() *texttemplate.Template { + t := texttemplate.New("composed-page") + texttemplate.Must(t.Parse(idiomaticComposedChromeSrc)) + texttemplate.Must(t.Parse(idiomaticComposedLayoutSrc)) + return texttemplate.Must(t.Parse(idiomaticComposedHomeSrc)) + }() + idiomaticTrivialSubstitutionTpl = texttemplate.Must(texttemplate.New("trivial-substitution").Parse(idiomaticTrivialSubstitutionSrc)) + idiomaticLargeLoopTpl = texttemplate.Must(texttemplate.New("large-loop").Parse(idiomaticLargeLoopSrc)) + idiomaticMixedPageTpl = texttemplate.Must(texttemplate.New("mixed-page").Parse(idiomaticMixedPageSrc)) + idiomaticConditionalHeavyTpl = texttemplate.Must(texttemplate.New("conditional-heavy").Parse(idiomaticConditionalHeavySrc)) + idiomaticFragmentHeavyTpl = texttemplate.Must(texttemplate.New("fragment-heavy").Parse(idiomaticFragmentHeavySrc)) + idiomaticFortunesEncodedTpl = htmltemplate.Must(htmltemplate.New("fortunes-encoded").Parse(idiomaticFortunesEncodedSrc)) + idiomaticEncodedLoopTpl = htmltemplate.Must(htmltemplate.New("encoded-loop").Parse(idiomaticEncodedLoopSrc)) +) + +// ---- per-cell reused buffers (render.go's newBuf; same sizing cases as controlled) ----------- + +var ( + idComposedBuf = newBuf(64 << 10) + idTrivialBuf = newBuf(1 << 10) + idLargeLoopBuf = newBuf(256 << 10) + idMixedBuf = newBuf(32 << 10) + idConditionalBuf = newBuf(32 << 10) + idFragmentBuf = newBuf(16 << 10) + idFortunesBuf = newBuf(4 << 10) + idEncodedLoopBuf = newBuf(2 << 20) +) + +// ---- the eight idiomatic cells (raw = stdlib-text, encoded = stdlib-html) -------------------- + +// RenderComposedPage renders workload 1 idiomatically via text/template. +func RenderComposedPage() string { + return render(idiomaticComposedTpl, idComposedBuf, model.Composed()) +} + +// RenderTrivialSubstitution renders workload 2 idiomatically via text/template. +func RenderTrivialSubstitution() string { + return render(idiomaticTrivialSubstitutionTpl, idTrivialBuf, model.Substitution) +} + +// RenderLargeLoop renders workload 3 idiomatically via text/template. +func RenderLargeLoop() string { + return render(idiomaticLargeLoopTpl, idLargeLoopBuf, model.LargeLoop) +} + +// RenderMixedPage renders workload 4 idiomatically via text/template. +func RenderMixedPage() string { + return render(idiomaticMixedPageTpl, idMixedBuf, model.Mixed) +} + +// RenderConditionalHeavy renders workload 5 idiomatically via text/template. +func RenderConditionalHeavy() string { + return render(idiomaticConditionalHeavyTpl, idConditionalBuf, model.Conditional) +} + +// RenderFragmentHeavy renders workload 6 idiomatically via text/template. +func RenderFragmentHeavy() string { + return render(idiomaticFragmentHeavyTpl, idFragmentBuf, model.Fragment) +} + +// RenderFortunesEncoded renders workload 7 idiomatically via html/template. +func RenderFortunesEncoded() string { + return render(idiomaticFortunesEncodedTpl, idFortunesBuf, model.Fortunes) +} + +// RenderEncodedLoop renders workload 8 idiomatically via html/template. +func RenderEncodedLoop() string { + return render(idiomaticEncodedLoopTpl, idEncodedLoopBuf, model.EncodedLoop) +} diff --git a/benchmarks/go/internal/stdlibtpl/idiomatic/render.go b/benchmarks/go/internal/stdlibtpl/idiomatic/render.go new file mode 100644 index 00000000..c4606aec --- /dev/null +++ b/benchmarks/go/internal/stdlibtpl/idiomatic/render.go @@ -0,0 +1,32 @@ +// Idiomatic-track render path for the stdlib surfaces — the same reused pre-grown +// per-cell bytes.Buffer shape as the controlled track's render.go, stated per track so +// each package is self-contained (the templ engine splits its tracks the same way). +package idiomatic + +import ( + "bytes" + "io" +) + +// executer is the shared surface of *text/template.Template and *html/template.Template. +type executer interface { + Execute(wr io.Writer, data any) error +} + +// newBuf returns a buffer pre-grown to the workload's output size (encoded-loop's ~1.1 MB +// escaped output is the sizing case), so growth never lands in a timed region. +func newBuf(capacity int) *bytes.Buffer { + buf := new(bytes.Buffer) + buf.Grow(capacity) + return buf +} + +// render resets the cell's buffer, executes the cached template, and returns the output. +// A template execution error is a harness defect, never a gate outcome — panic loudly. +func render(t executer, buf *bytes.Buffer, data any) string { + buf.Reset() + if err := t.Execute(buf, data); err != nil { + panic("stdlibtpl/idiomatic: render failed: " + err.Error()) + } + return buf.String() +} diff --git a/benchmarks/go/internal/templeng/controlled/composed_page.templ b/benchmarks/go/internal/templeng/controlled/composed_page.templ new file mode 100644 index 00000000..6232b567 --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/composed_page.templ @@ -0,0 +1,415 @@ +// Workload 1 — composed-page, templ controlled port: byte-parity with the shared golden +// after normalization. templ's native layout mechanism with a live body slot: the chrome lives in +// templ layout(m) with { children... } at the body-slot position (the @out() analogue), +// and composedPage invokes @layout(m) { …slider markup… } — the caller body splices at the +// slot (templ.guide template-composition, children). The inert chrome fragments are +// LITERAL template text in per-fragment components mirroring chrome-fragments.heddle +// (no fragment text is model data any more); the structured nav renders through +// nested components (megaMenu → navColumn → navSection → navLink) over model.ComposedModel. +// +// Raw discipline (byte-gate accommodations only, each over pinned template literal text — +// the mixed-page doctype precedent): (1) the doctype — templ lowercases a literal +// ; (2) the nine void elements the oracle spells with a self-closing " />" +// or "/>" — templ's generator normalizes void elements to the slashless form (probed at +// v0.3.1020), a NON-whitespace divergence, so those exact pinned bytes are emitted via +// @templ.Raw. Every other node — conditional comments included, which templ passes through +// byte-exact — is authored natively. Nav values carry no escapable characters, so templ's always-on +// escaper is a byte-level no-op on them (escaped == raw); no templ.Raw touches nav data. +// +// Component-boundary note: custom_styles renders the whole element (Heddle splices the fragment INSIDE a +} + +templ headScripts() { + +} + +templ bodyScripts() { + +} + +templ bodyEndScripts() { + +} + +// ---- structured nav (nested components over nav.json's model) -------------------------- + +templ navLink(l model.NavLink) { + +} + +templ navSection(s model.NavSection) { + +} + +templ navColumn(c model.NavColumn) { + +} + +templ megaMenu(menu model.MegaMenu) { +
      +
        + for _, t := range menu.Tabs { +
      • + { t.Label } + if t.HasDropdown { +
        + for _, c := range t.Columns { + @navColumn(c) + } +
        + } +
      • + } +
      +
      +} + +// ---- the layout (layout.heddle definition; { children... } is the @out() slot) ------ + +templ layout(m model.ComposedModel) { + @templ.Raw("") + + + + + + + + + @metaSection() + @socialMetaSection() + + @templ.Raw(``) + + + + @assetsStyles() + @customStyles() + @headScripts() + + + @bodyScripts() +
      +
      + +
      +
      +
      +
      + @alertTop() +
      +
      +
      +
      +
      + +
      +
      +
      +
      + + @templ.Raw(``) + @templ.Raw(``) +
      +
      + +
      +
      + +
      +
      +
      + + for _, menu := range m.Nav.Menus { + @megaMenu(menu) + } +
      +
      +
      + @alertBelow() +
      +
      + { children... } +
      +
      +
      +
      + +
      +
      + @assetsScripts() + + @pageScriptsSection() + @endpageScriptsSection() + @bodyEndScripts() + + +} + +// ---- the page (composed-page.heddle: @<<{{layout.heddle}} + @layout(){{ …slider… }}) ------------------ + +templ composedPage(m model.ComposedModel) { + @layout(m) { +
      +
      + +
      + } +} diff --git a/benchmarks/go/internal/templeng/controlled/composed_page_templ.go b/benchmarks/go/internal/templeng/controlled/composed_page_templ.go new file mode 100644 index 00000000..9ef38ecb --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/composed_page_templ.go @@ -0,0 +1,1012 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 1 — composed-page, templ controlled port: byte-parity with the shared golden + +// after normalization. templ's native layout mechanism with a live body slot: the chrome lives in + +// templ layout(m) with { children... } at the body-slot position (the @out() analogue), + +// and composedPage invokes @layout(m) { …slider markup… } — the caller body splices at the + +// slot (templ.guide template-composition, children). The inert chrome fragments are + +// LITERAL template text in per-fragment components mirroring chrome-fragments.heddle + +// (no fragment text is model data any more); the structured nav renders through + +// nested components (megaMenu → navColumn → navSection → navLink) over model.ComposedModel. + +// + +// Raw discipline (byte-gate accommodations only, each over pinned template literal text — + +// the mixed-page doctype precedent): (1) the doctype — templ lowercases a literal + +// ; (2) the nine void elements the oracle spells with a self-closing " />" + +// or "/>" — templ's generator normalizes void elements to the slashless form (probed at + +// v0.3.1020), a NON-whitespace divergence, so those exact pinned bytes are emitted via + +// @templ.Raw. Every other node — conditional comments included, which templ passes through + +// byte-exact — is authored natively. Nav values carry no escapable characters, so templ's always-on + +// escaper is a byte-level no-op on them (escaped == raw); no templ.Raw touches nav data. + +// + +// Component-boundary note: custom_styles renders the whole element (Heddle splices the fragment INSIDE a ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func headScripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var12 := templ.GetChildren(ctx) + if templ_7745c5c3_Var12 == nil { + templ_7745c5c3_Var12 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func bodyScripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var13 := templ.GetChildren(ctx) + if templ_7745c5c3_Var13 == nil { + templ_7745c5c3_Var13 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func bodyEndScripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var14 := templ.GetChildren(ctx) + if templ_7745c5c3_Var14 == nil { + templ_7745c5c3_Var14 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// ---- structured nav (nested components over nav.json's model) -------------------------- +func navLink(l model.NavLink) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var15 := templ.GetChildren(ctx) + if templ_7745c5c3_Var15 == nil { + templ_7745c5c3_Var15 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
    • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var17 string + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(l.Label) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/composed_page.templ`, Line: 229, Col: 50} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
    • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func navSection(s model.NavSection) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var18 := templ.GetChildren(ctx) + if templ_7745c5c3_Var18 == nil { + templ_7745c5c3_Var18 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if s.TitleLinked { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(s.Title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/composed_page.templ`, Line: 235, Col: 55} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(s.Title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/composed_page.templ`, Line: 237, Col: 36} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
        ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, l := range s.Links { + templ_7745c5c3_Err = navLink(l).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func navColumn(c model.NavColumn) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var22 := templ.GetChildren(ctx) + if templ_7745c5c3_Var22 == nil { + templ_7745c5c3_Var22 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, s := range c.Sections { + templ_7745c5c3_Err = navSection(s).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func megaMenu(menu model.MegaMenu) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var23 := templ.GetChildren(ctx) + if templ_7745c5c3_Var23 == nil { + templ_7745c5c3_Var23 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// ---- the layout (layout.heddle definition; { children... } is the @out() slot) ------ +func layout(m model.ComposedModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var30 := templ.GetChildren(ctx) + if templ_7745c5c3_Var30 == nil { + templ_7745c5c3_Var30 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templ.Raw("").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = metaSection().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = socialMetaSection().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.Raw(``).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = assetsStyles().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = customStyles().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = headScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = bodyScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = alertTop().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.Raw(``).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.Raw(``).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, menu := range m.Nav.Menus { + templ_7745c5c3_Err = megaMenu(menu).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = alertBelow().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ_7745c5c3_Var30.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = assetsScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = pageScriptsSection().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = endpageScriptsSection().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = bodyEndScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// ---- the page (composed-page.heddle: @<<{{layout.heddle}} + @layout(){{ …slider… }}) ------------------ +func composedPage(m model.ComposedModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var31 := templ.GetChildren(ctx) + if templ_7745c5c3_Var31 == nil { + templ_7745c5c3_Var31 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var32 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) + templ_7745c5c3_Err = layout(m).Render(templ.WithChildren(ctx, templ_7745c5c3_Var32), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/controlled/conditional_heavy.templ b/benchmarks/go/internal/templeng/controlled/conditional_heavy.templ new file mode 100644 index 00000000..7eb7a975 --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/conditional_heavy.templ @@ -0,0 +1,34 @@ +// Workload 5 — conditional-heavy, templ controlled port: byte-parity with the shared +// golden after normalization. The note text is composed IN THE TEMPLATE as the literal +// "note " plus the Seq substitution (the model carries data only). +// Every branch body is a complete dense element; the four-way chain uses +// templ's Go-statement if/else if/else syntax, which requires the chain on its own lines — +// that whitespace sits between elements and is N3/N3b-erased. +package controlled + +import "heddle.dev/benchmarks/go/internal/model" + +templ conditionalHeavy(m model.ConditionalModel) { +
        + for _, r := range m.Rows { +
      • + if r.IsBronze { + bronze + } else if r.IsSilver { + silver + } else if r.IsGold { + gold + } else { + platinum + } + { r.Name } + if r.HasNote { + note { r.Seq } + } + if r.IsActive { + active + } +
      • + } +
      +} diff --git a/benchmarks/go/internal/templeng/controlled/conditional_heavy_templ.go b/benchmarks/go/internal/templeng/controlled/conditional_heavy_templ.go new file mode 100644 index 00000000..62ff83cc --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/conditional_heavy_templ.go @@ -0,0 +1,131 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 5 — conditional-heavy, templ controlled port: byte-parity with the shared + +// golden after normalization. The note text is composed IN THE TEMPLATE as the literal + +// "note " plus the Seq substitution (the model carries data only). + +// Every branch body is a complete dense element; the four-way chain uses + +// templ's Go-statement if/else if/else syntax, which requires the chain on its own lines — + +// that whitespace sits between elements and is N3/N3b-erased. + +package controlled + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func conditionalHeavy(m model.ConditionalModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
        ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, r := range m.Rows { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
      • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if r.IsBronze { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "bronze ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else if r.IsSilver { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "silver ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else if r.IsGold { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "gold ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "platinum ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/conditional_heavy.templ`, Line: 24, Col: 16} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if r.HasNote { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "note ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(r.Seq) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/conditional_heavy.templ`, Line: 26, Col: 24} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + if r.IsActive { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "active") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
      • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/controlled/encoded_loop.templ b/benchmarks/go/internal/templeng/controlled/encoded_loop.templ new file mode 100644 index 00000000..68538ffd --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/encoded_loop.templ @@ -0,0 +1,15 @@ +// Workload 8 — encoded-loop, templ controlled port: byte-parity with the shared golden +// after normalization. data-tag={ r.Tag } is templ's attribute expression (auto-quoted and +// attribute-encoded); the other two substitutions are text-context. All emitted spellings +// sit inside the N5 table (the feasibility spike's P2 probe pinned the exact bytes). +package controlled + +import "heddle.dev/benchmarks/go/internal/model" + +templ encodedLoop(m model.EncodedLoopModel) { + + for _, r := range m.Items { + + } +
      { r.Name }{ r.Comment }
      +} diff --git a/benchmarks/go/internal/templeng/controlled/encoded_loop_templ.go b/benchmarks/go/internal/templeng/controlled/encoded_loop_templ.go new file mode 100644 index 00000000..34134989 --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/encoded_loop_templ.go @@ -0,0 +1,99 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 8 — encoded-loop, templ controlled port: byte-parity with the shared golden + +// after normalization. data-tag={ r.Tag } is templ's attribute expression (auto-quoted and + +// attribute-encoded); the other two substitutions are text-context. All emitted spellings + +// sit inside the N5 table (the feasibility spike's P2 probe pinned the exact bytes). + +package controlled + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func encodedLoop(m model.EncodedLoopModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, r := range m.Items { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/encoded_loop.templ`, Line: 12, Col: 38} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(r.Comment) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/encoded_loop.templ`, Line: 12, Col: 60} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/controlled/fortunes_encoded.templ b/benchmarks/go/internal/templeng/controlled/fortunes_encoded.templ new file mode 100644 index 00000000..848bcdab --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/fortunes_encoded.templ @@ -0,0 +1,31 @@ +// Workload 7 — fortunes-encoded, templ controlled port: byte-parity with the shared +// golden after normalization. Dense text discipline: every { } expression directly flanked by /; +// newlines only between sibling elements/statements. templ's default escaping path fires on +// the text-context substitutions; its "/' spellings are reconciled by N5, the +// Japanese row passes through byte-intact (pinned by the feasibility spike's P2 probe). +// +// Doctype authoring note: templ's generator normalizes a literal to +// lowercase — a NON-whitespace byte change vs the pinned skeleton — so the +// doctype is emitted via @templ.Raw over the exact pinned literal (the engine's documented +// raw mechanism, applied to constant template text, not data). Every other node is authored +// natively. +package controlled + +import "heddle.dev/benchmarks/go/internal/model" + +templ fortunesEncoded(m model.FortuneModel) { + @templ.Raw("") + + + Fortunes + + + + + for _, r := range m.Rows { + + } +
      idmessage
      { r.Id }{ r.Message }
      + + +} diff --git a/benchmarks/go/internal/templeng/controlled/fortunes_encoded_templ.go b/benchmarks/go/internal/templeng/controlled/fortunes_encoded_templ.go new file mode 100644 index 00000000..23fa8dd5 --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/fortunes_encoded_templ.go @@ -0,0 +1,104 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 7 — fortunes-encoded, templ controlled port: byte-parity with the shared + +// golden after normalization. Dense text discipline: every { } expression directly flanked by /; + +// newlines only between sibling elements/statements. templ's default escaping path fires on + +// the text-context substitutions; its "/' spellings are reconciled by N5, the + +// Japanese row passes through byte-intact (pinned by the feasibility spike's P2 probe). + +// + +// Doctype authoring note: templ's generator normalizes a literal to + +// lowercase — a NON-whitespace byte change vs the pinned skeleton — so the + +// doctype is emitted via @templ.Raw over the exact pinned literal (the engine's documented + +// raw mechanism, applied to constant template text, not data). Every other node is authored + +// natively. + +package controlled + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func fortunesEncoded(m model.FortuneModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templ.Raw("").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "Fortunes") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, r := range m.Rows { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
      idmessage
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(r.Id) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fortunes_encoded.templ`, Line: 26, Col: 19} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(r.Message) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fortunes_encoded.templ`, Line: 26, Col: 41} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/controlled/fragment_heavy.templ b/benchmarks/go/internal/templeng/controlled/fragment_heavy.templ new file mode 100644 index 00000000..141e5ce1 --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/fragment_heavy.templ @@ -0,0 +1,56 @@ +// Workload 6 — fragment-heavy, templ controlled port: byte-parity with the shared golden +// after normalization. Six components — tile, card (which nests @badge(r.Promo) + @price(r.Promo), +// the one nesting level), badge, price, mediaRow, stat — dispatched per row by the +// controlled boolean if/else if/else chain (never on the Kind string). Derived display +// text is composed IN THE TEMPLATE as literal-plus-substitution (the model carries data only): the display price +// is { p.Price } + the literal ".99", the media caption is the literal "Caption for " + +// { r.Name }, and the media image source is "/img/" + Name + ".jpg". +// +// Raw discipline (byte-gate accommodation, the mixed-page doctype precedent): the media +// row's — the oracle spells the void element with a self-closing " />", which +// templ's generator normalizes to the slashless form (a NON-whitespace divergence, probed +// at v0.3.1020) — is emitted via @templ.Raw over the pinned literal-plus-substitution +// text (Name carries no escapable characters). Every other node is authored natively. +package controlled + +import "heddle.dev/benchmarks/go/internal/model" + +templ tile(r model.FragmentRow) { +

      { r.Name }

      { r.Value }

      { r.Badge }
      +} + +templ badge(p model.FragmentPromo) { + { p.Label } +} + +templ price(p model.FragmentPromo) { +

      { p.Price }.99

      +} + +templ card(r model.FragmentRow) { +

      { r.Name }

      @badge(r.Promo)@price(r.Promo)

      { r.Value }

      +} + +templ mediaRow(r model.FragmentRow) { +
      @templ.Raw(`` + r.Name + ``)

      { r.Name }

      Caption for { r.Name }

      +} + +templ stat(r model.FragmentRow) { +
      { r.Name }{ r.Value }{ r.Delta }
      +} + +templ fragmentHeavy(m model.FragmentModel) { +
      + for _, r := range m.Items { + if r.IsTile { + @tile(r) + } else if r.IsCard { + @card(r) + } else if r.IsMedia { + @mediaRow(r) + } else { + @stat(r) + } + } +
      +} diff --git a/benchmarks/go/internal/templeng/controlled/fragment_heavy_templ.go b/benchmarks/go/internal/templeng/controlled/fragment_heavy_templ.go new file mode 100644 index 00000000..cf0b4d63 --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/fragment_heavy_templ.go @@ -0,0 +1,445 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 6 — fragment-heavy, templ controlled port: byte-parity with the shared golden + +// after normalization. Six components — tile, card (which nests @badge(r.Promo) + @price(r.Promo), + +// the one nesting level), badge, price, mediaRow, stat — dispatched per row by the + +// controlled boolean if/else if/else chain (never on the Kind string). Derived display + +// text is composed IN THE TEMPLATE as literal-plus-substitution (the model carries data only): the display price + +// is { p.Price } + the literal ".99", the media caption is the literal "Caption for " + + +// { r.Name }, and the media image source is "/img/" + Name + ".jpg". + +// + +// Raw discipline (byte-gate accommodation, the mixed-page doctype precedent): the media + +// row's — the oracle spells the void element with a self-closing " />", which + +// templ's generator normalizes to the slashless form (a NON-whitespace divergence, probed + +// at v0.3.1020) — is emitted via @templ.Raw over the pinned literal-plus-substitution + +// text (Name carries no escapable characters). Every other node is authored natively. + +package controlled + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func tile(r model.FragmentRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 19, Col: 35} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(r.Value) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 19, Col: 64} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(r.Badge) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 19, Col: 99} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func badge(p model.FragmentPromo) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var5 := templ.GetChildren(ctx) + if templ_7745c5c3_Var5 == nil { + templ_7745c5c3_Var5 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(p.Label) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 23, Col: 36} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func price(p model.FragmentPromo) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var7 := templ.GetChildren(ctx) + if templ_7745c5c3_Var7 == nil { + templ_7745c5c3_Var7 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(p.Price) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 27, Col: 27} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, ".99

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func card(r model.FragmentRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var9 := templ.GetChildren(ctx) + if templ_7745c5c3_Var9 == nil { + templ_7745c5c3_Var9 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 31, Col: 35} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = badge(r.Promo).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = price(r.Promo).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(r.Value) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 31, Col: 94} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func mediaRow(r model.FragmentRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var12 := templ.GetChildren(ctx) + if templ_7745c5c3_Var12 == nil { + templ_7745c5c3_Var12 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.Raw(``+r.Name+``).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 35, Col: 132} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

      Caption for ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 35, Col: 162} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func stat(r model.FragmentRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var15 := templ.GetChildren(ctx) + if templ_7745c5c3_Var15 == nil { + templ_7745c5c3_Var15 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var16 string + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 39, Col: 51} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var17 string + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(r.Value) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 39, Col: 94} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var18 string + templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(r.Delta) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/fragment_heavy.templ`, Line: 39, Col: 137} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func fragmentHeavy(m model.FragmentModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var19 := templ.GetChildren(ctx) + if templ_7745c5c3_Var19 == nil { + templ_7745c5c3_Var19 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, r := range m.Items { + if r.IsTile { + templ_7745c5c3_Err = tile(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else if r.IsCard { + templ_7745c5c3_Err = card(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else if r.IsMedia { + templ_7745c5c3_Err = mediaRow(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = stat(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/controlled/large_loop.templ b/benchmarks/go/internal/templeng/controlled/large_loop.templ new file mode 100644 index 00000000..adb9734d --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/large_loop.templ @@ -0,0 +1,14 @@ +// Workload 3 — large-loop, templ controlled port: byte-parity with the shared golden +// after normalization. Dense single-line row body; the display name is composed IN THE +// TEMPLATE as the literal "row-" plus the value substitution (the model carries +// ONLY Value). Value is an int — templ renders numbers natively, identical bytes to +// strconv.Itoa on the raw alphabet. +package controlled + +import "heddle.dev/benchmarks/go/internal/model" + +templ largeLoop(m model.LoopModel) { + for _, r := range m.Items { + row-{ r.Value }{ r.Value } + } +} diff --git a/benchmarks/go/internal/templeng/controlled/large_loop_templ.go b/benchmarks/go/internal/templeng/controlled/large_loop_templ.go new file mode 100644 index 00000000..bce232d1 --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/large_loop_templ.go @@ -0,0 +1,80 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 3 — large-loop, templ controlled port: byte-parity with the shared golden + +// after normalization. Dense single-line row body; the display name is composed IN THE + +// TEMPLATE as the literal "row-" plus the value substitution (the model carries + +// ONLY Value). Value is an int — templ renders numbers natively, identical bytes to + +// strconv.Itoa on the raw alphabet. + +package controlled + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func largeLoop(m model.LoopModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + for _, r := range m.Items { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "row-") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(r.Value) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/large_loop.templ`, Line: 12, Col: 23} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(r.Value) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/large_loop.templ`, Line: 12, Col: 43} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/controlled/mixed_page.templ b/benchmarks/go/internal/templeng/controlled/mixed_page.templ new file mode 100644 index 00000000..42b25b9b --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/mixed_page.templ @@ -0,0 +1,65 @@ +// Workload 4 — mixed-page, templ controlled port: byte-parity with the shared golden +// after normalization. The display SKU is composed IN THE TEMPLATE as the literal +// "MX-" plus the SkuNumber substitution, and the blurb sentence lives in the template +// around the { p.Batch } substitution (the model carries data only). +// The pinned skeleton with newlines only between sibling +// elements/statements (N2/N3-erased); all text-bearing elements dense; the + + +
      +

      { m.StoreName }

      + +
      +
      + if m.ShowBanner { + + } +
      +

      { m.HeroHeading }

      +

      { m.HeroTagline }

      +
      +
      + for _, p := range m.Products { +
      +

      { p.Name }

      +

      MX-{ p.SkuNumber }

      +

      { p.Price }

      + if p.OnSale { +

      On sale

      + } +

      A dependable workshop staple from batch { p.Batch }, checked for daily use and backed by our lifetime guarantee.

      +
      + } +
      + if m.ShowDebugPanel { +
      debug
      + } +
      +
      +

      { m.FooterNote }

      +

      { m.StoreName } { m.Year } { m.SupportEmail }

      +
      + + +} diff --git a/benchmarks/go/internal/templeng/controlled/mixed_page_templ.go b/benchmarks/go/internal/templeng/controlled/mixed_page_templ.go new file mode 100644 index 00000000..3756c7bc --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/mixed_page_templ.go @@ -0,0 +1,287 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 4 — mixed-page, templ controlled port: byte-parity with the shared golden + +// after normalization. The display SKU is composed IN THE TEMPLATE as the literal + +// "MX-" plus the SkuNumber substitution, and the blurb sentence lives in the template + +// around the { p.Batch } substitution (the model carries data only). + +// The pinned skeleton with newlines only between sibling + +// elements/statements (N2/N3-erased); all text-bearing elements dense; the

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(m.StoreName) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 31, Col: 21} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if m.ShowBanner { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(m.BannerText) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 36, Col: 39} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(m.HeroHeading) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 39, Col: 24} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(m.HeroTagline) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 40, Col: 23} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, p := range m.Products { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 45, Col: 19} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

      MX-") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(p.SkuNumber) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 46, Col: 38} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(p.Price) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 47, Col: 33} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if p.OnSale { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

      On sale

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "

      A dependable workshop staple from batch ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(p.Batch) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 51, Col: 73} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, ", checked for daily use and backed by our lifetime guarantee.

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if m.ShowDebugPanel { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
      debug
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(m.FooterNote) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 60, Col: 21} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(m.StoreName) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 61, Col: 20} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(m.Year) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 61, Col: 31} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(m.SupportEmail) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/mixed_page.templ`, Line: 61, Col: 50} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/controlled/render.go b/benchmarks/go/internal/templeng/controlled/render.go new file mode 100644 index 00000000..2332ce5b --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/render.go @@ -0,0 +1,79 @@ +// Package controlled hosts the templ controlled ports (one .templ file per workload, +// generated *_templ.go committed, regenerated only with the pinned CLI). Render path: +// component.Render(ctx, buf) into a reused pre-grown bytes.Buffer with a background +// context.Context created once; construction of the component value (a cheap closure) is +// inside the render — it is templ's per-render entry point, exactly how a caller invokes a +// cached templ template (there is no separate parse to exclude). +package controlled + +import ( + "bytes" + "context" + + "github.com/a-h/templ" + + "heddle.dev/benchmarks/go/internal/model" +) + +// ctx is the background context, built once and shared by every render. +var ctx = context.Background() + +// newBuf returns a buffer pre-grown to the workload's output size, so growth never lands +// in a timed region (encoded-loop's ~1.1 MB escaped output is the sizing case). +func newBuf(capacity int) *bytes.Buffer { + buf := new(bytes.Buffer) + buf.Grow(capacity) + return buf +} + +var ( + composedBuf = newBuf(64 << 10) + trivialBuf = newBuf(1 << 10) + largeLoopBuf = newBuf(256 << 10) + mixedBuf = newBuf(32 << 10) + conditionalBuf = newBuf(32 << 10) + fragmentBuf = newBuf(16 << 10) + fortunesBuf = newBuf(4 << 10) + encodedLoopBuf = newBuf(2 << 20) +) + +// render resets the cell's buffer, renders the component, and returns the output. +// A render error is a harness defect, never a gate outcome — panic loudly. +func render(c templ.Component, buf *bytes.Buffer) string { + buf.Reset() + if err := c.Render(ctx, buf); err != nil { + panic("templeng/controlled: render failed: " + err.Error()) + } + return buf.String() +} + +// ---- the eight controlled cells -------------------------------------------------------------- + +// RenderComposedPage renders workload 1 via templ (model.Composed() loads the nav fixture +// exactly once — sync.Once — so the per-render cost is a call plus a struct copy). +func RenderComposedPage() string { return render(composedPage(model.Composed()), composedBuf) } + +// RenderTrivialSubstitution renders workload 2 via templ. +func RenderTrivialSubstitution() string { + return render(trivialSubstitution(model.Substitution), trivialBuf) +} + +// RenderLargeLoop renders workload 3 via templ. +func RenderLargeLoop() string { return render(largeLoop(model.LargeLoop), largeLoopBuf) } + +// RenderMixedPage renders workload 4 via templ. +func RenderMixedPage() string { return render(mixedPage(model.Mixed), mixedBuf) } + +// RenderConditionalHeavy renders workload 5 via templ. +func RenderConditionalHeavy() string { + return render(conditionalHeavy(model.Conditional), conditionalBuf) +} + +// RenderFragmentHeavy renders workload 6 via templ. +func RenderFragmentHeavy() string { return render(fragmentHeavy(model.Fragment), fragmentBuf) } + +// RenderFortunesEncoded renders workload 7 via templ (its default escaping path). +func RenderFortunesEncoded() string { return render(fortunesEncoded(model.Fortunes), fortunesBuf) } + +// RenderEncodedLoop renders workload 8 via templ (its default escaping path). +func RenderEncodedLoop() string { return render(encodedLoop(model.EncodedLoop), encodedLoopBuf) } diff --git a/benchmarks/go/internal/templeng/controlled/trivial_substitution.templ b/benchmarks/go/internal/templeng/controlled/trivial_substitution.templ new file mode 100644 index 00000000..c52c5ebc --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/trivial_substitution.templ @@ -0,0 +1,11 @@ +// Workload 2 — trivial-substitution, templ controlled port: byte-parity with the shared +// golden after normalization. The pinned one-line
      card, ten substitutions in +// pinned order including the two attribute positions — identical authoring to the +// feasibility spike's P1 probe, which passed the full byte gate. +package controlled + +import "heddle.dev/benchmarks/go/internal/model" + +templ trivialSubstitution(m model.SubstitutionModel) { +

      { m.Title }

      { m.Sku }

      { m.Price }

      { m.Brand }

      { m.Category }

      { m.Availability }

      { m.Summary }

      { m.Rating }

      +} diff --git a/benchmarks/go/internal/templeng/controlled/trivial_substitution_templ.go b/benchmarks/go/internal/templeng/controlled/trivial_substitution_templ.go new file mode 100644 index 00000000..a398ace8 --- /dev/null +++ b/benchmarks/go/internal/templeng/controlled/trivial_substitution_templ.go @@ -0,0 +1,180 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 2 — trivial-substitution, templ controlled port: byte-parity with the shared + +// golden after normalization. The pinned one-line
      card, ten substitutions in + +// pinned order including the two attribute positions — identical authoring to the + +// feasibility spike's P1 probe, which passed the full byte gate. + +package controlled + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func trivialSubstitution(m model.SubstitutionModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(m.Title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/trivial_substitution.templ`, Line: 10, Col: 23} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(m.Sku) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/trivial_substitution.templ`, Line: 10, Col: 52} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(m.Price) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/trivial_substitution.templ`, Line: 10, Col: 84} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(m.Brand) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/trivial_substitution.templ`, Line: 10, Col: 116} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(m.Category) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/trivial_substitution.templ`, Line: 10, Col: 149} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(m.Availability) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/trivial_substitution.templ`, Line: 10, Col: 188} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(m.Summary) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/trivial_substitution.templ`, Line: 10, Col: 279} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(m.Rating) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/controlled/trivial_substitution.templ`, Line: 10, Col: 313} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/idiomatic/composed_page.templ b/benchmarks/go/internal/templeng/idiomatic/composed_page.templ new file mode 100644 index 00000000..fbd8b928 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/composed_page.templ @@ -0,0 +1,412 @@ +// Workload 1 — composed-page, templ idiomatic port: verifier-gated, authored the way +// the official docs teach. templ's native layout mechanism with a live body slot: a layout component +// takes { children... } at the body-slot position and the page invokes +// @layout(m) { …slider markup… } — the documented children-composition idiom. The inert +// chrome fragments are literal template text in per-fragment components; the +// structured navigation renders through nested components (megaMenu → navColumn → +// navSection → navLink) over the nav model loaded from the corpus fixture. +// +// Doctype authoring note (same variant as mixed-page): templ's generator normalizes a +// literal to lowercase , which would miss the verifier's +// "" ordered marker — so the doctype is emitted via @templ.Raw over the +// exact pinned literal (the engine's documented raw mechanism, applied to constant +// template text, not data). +// +// Official templ documentation for the constructs used here: +// - https://templ.guide/syntax-and-usage/template-composition/ (layout with children, +// component nesting) +// - https://templ.guide/syntax-and-usage/statements/ (for loops, if/else) +// - https://templ.guide/syntax-and-usage/expressions/ (text and attribute expressions) +// - https://templ.guide/syntax-and-usage/rendering-raw-html/ (doctype literal) +package idiomatic + +import "heddle.dev/benchmarks/go/internal/model" + +// ---- section defaults -------------------------------------------------------------------------- +templ metaSection() { + Title +} + +templ socialMetaSection() { + + + +} + +templ pageScriptsSection() { +} + +templ endpageScriptsSection() { +} + +// ---- chrome fragments (literal template text) -------------------------------------------- +templ alertTop() { +
      + + holiday shipping + +
      +} + +templ secondaryWholesaleMenu() { + +} + +templ secondaryRetailMenu() { + +} + +templ alertBelow() { +} + +templ assetsStyles() { + +} + +templ assetsScripts() { + +} + +templ customStyles() { + +} + +templ headScripts() { + +} + +templ bodyScripts() { + +} + +templ bodyEndScripts() { + +} + +// ---- structured nav (nested components) -------------------------------------------------- +templ navLink(l model.NavLink) { + +} + +templ navSection(s model.NavSection) { + +} + +templ navColumn(c model.NavColumn) { + +} + +templ megaMenu(menu model.MegaMenu) { +
      +
        + for _, t := range menu.Tabs { +
      • + { t.Label } + if t.HasDropdown { +
        + for _, c := range t.Columns { + @navColumn(c) + } +
        + } +
      • + } +
      +
      +} + +// ---- the layout ({ children... } is the live body slot) ---------------------------------------- +templ layout(m model.ComposedModel) { + @templ.Raw("") + + + + + + + + + @metaSection() + @socialMetaSection() + + + + + + @assetsStyles() + @customStyles() + @headScripts() + + + @bodyScripts() +
      +
      + +
      +
      +
      +
      + @alertTop() +
      +
      +
      +
      +
      + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + for _, menu := range m.Nav.Menus { + @megaMenu(menu) + } +
      +
      +
      + @alertBelow() +
      +
      + { children... } +
      +
      +
      +
      + +
      +
      + @assetsScripts() + + @pageScriptsSection() + @endpageScriptsSection() + @bodyEndScripts() + + +} + +// ---- the page (both tracks carry the SAME slider body) ----------------------------------- +templ composedPage(m model.ComposedModel) { + @layout(m) { +
      +
      +
      +
      + + + +
      +
      +
      + } +} diff --git a/benchmarks/go/internal/templeng/idiomatic/composed_page_templ.go b/benchmarks/go/internal/templeng/idiomatic/composed_page_templ.go new file mode 100644 index 00000000..0770da0c --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/composed_page_templ.go @@ -0,0 +1,956 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 1 — composed-page, templ idiomatic port: verifier-gated, authored the way + +// the official docs teach. templ's native layout mechanism with a live body slot: a layout component + +// takes { children... } at the body-slot position and the page invokes + +// @layout(m) { …slider markup… } — the documented children-composition idiom. The inert + +// chrome fragments are literal template text in per-fragment components; the + +// structured navigation renders through nested components (megaMenu → navColumn → + +// navSection → navLink) over the nav model loaded from the corpus fixture. + +// + +// Doctype authoring note (same variant as mixed-page): templ's generator normalizes a + +// literal to lowercase , which would miss the verifier's + +// "" ordered marker — so the doctype is emitted via @templ.Raw over the + +// exact pinned literal (the engine's documented raw mechanism, applied to constant + +// template text, not data). + +// + +// Official templ documentation for the constructs used here: + +// - https://templ.guide/syntax-and-usage/template-composition/ (layout with children, + +// component nesting) + +// - https://templ.guide/syntax-and-usage/statements/ (for loops, if/else) + +// - https://templ.guide/syntax-and-usage/expressions/ (text and attribute expressions) + +// - https://templ.guide/syntax-and-usage/rendering-raw-html/ (doctype literal) + +package idiomatic + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +// ---- section defaults -------------------------------------------------------------------------- +func metaSection() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "Title") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func socialMetaSection() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var2 := templ.GetChildren(ctx) + if templ_7745c5c3_Var2 == nil { + templ_7745c5c3_Var2 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func pageScriptsSection() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var3 := templ.GetChildren(ctx) + if templ_7745c5c3_Var3 == nil { + templ_7745c5c3_Var3 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return nil + }) +} + +func endpageScriptsSection() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return nil + }) +} + +// ---- chrome fragments (literal template text) -------------------------------------------- +func alertTop() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var5 := templ.GetChildren(ctx) + if templ_7745c5c3_Var5 == nil { + templ_7745c5c3_Var5 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
      \"holiday
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func secondaryWholesaleMenu() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var6 := templ.GetChildren(ctx) + if templ_7745c5c3_Var6 == nil { + templ_7745c5c3_Var6 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func secondaryRetailMenu() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var7 := templ.GetChildren(ctx) + if templ_7745c5c3_Var7 == nil { + templ_7745c5c3_Var7 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func alertBelow() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var8 := templ.GetChildren(ctx) + if templ_7745c5c3_Var8 == nil { + templ_7745c5c3_Var8 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return nil + }) +} + +func assetsStyles() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var9 := templ.GetChildren(ctx) + if templ_7745c5c3_Var9 == nil { + templ_7745c5c3_Var9 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func assetsScripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var10 := templ.GetChildren(ctx) + if templ_7745c5c3_Var10 == nil { + templ_7745c5c3_Var10 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func customStyles() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var11 := templ.GetChildren(ctx) + if templ_7745c5c3_Var11 == nil { + templ_7745c5c3_Var11 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func headScripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var12 := templ.GetChildren(ctx) + if templ_7745c5c3_Var12 == nil { + templ_7745c5c3_Var12 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func bodyScripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var13 := templ.GetChildren(ctx) + if templ_7745c5c3_Var13 == nil { + templ_7745c5c3_Var13 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func bodyEndScripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var14 := templ.GetChildren(ctx) + if templ_7745c5c3_Var14 == nil { + templ_7745c5c3_Var14 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// ---- structured nav (nested components) -------------------------------------------------- +func navLink(l model.NavLink) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var15 := templ.GetChildren(ctx) + if templ_7745c5c3_Var15 == nil { + templ_7745c5c3_Var15 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
    • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var17 string + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(l.Label) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/composed_page.templ`, Line: 228, Col: 50} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
    • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func navSection(s model.NavSection) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var18 := templ.GetChildren(ctx) + if templ_7745c5c3_Var18 == nil { + templ_7745c5c3_Var18 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if s.TitleLinked { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(s.Title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/composed_page.templ`, Line: 234, Col: 55} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(s.Title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/composed_page.templ`, Line: 236, Col: 36} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
        ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, l := range s.Links { + templ_7745c5c3_Err = navLink(l).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func navColumn(c model.NavColumn) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var22 := templ.GetChildren(ctx) + if templ_7745c5c3_Var22 == nil { + templ_7745c5c3_Var22 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, s := range c.Sections { + templ_7745c5c3_Err = navSection(s).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func megaMenu(menu model.MegaMenu) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var23 := templ.GetChildren(ctx) + if templ_7745c5c3_Var23 == nil { + templ_7745c5c3_Var23 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// ---- the layout ({ children... } is the live body slot) ---------------------------------------- +func layout(m model.ComposedModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var30 := templ.GetChildren(ctx) + if templ_7745c5c3_Var30 == nil { + templ_7745c5c3_Var30 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templ.Raw("").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = metaSection().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = socialMetaSection().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = assetsStyles().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = customStyles().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = headScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = bodyScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = alertTop().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, menu := range m.Nav.Menus { + templ_7745c5c3_Err = megaMenu(menu).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = alertBelow().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ_7745c5c3_Var30.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
      \"See
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = assetsScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = pageScriptsSection().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = endpageScriptsSection().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = bodyEndScripts().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +// ---- the page (both tracks carry the SAME slider body) ----------------------------------- +func composedPage(m model.ComposedModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var31 := templ.GetChildren(ctx) + if templ_7745c5c3_Var31 == nil { + templ_7745c5c3_Var31 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var32 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) + templ_7745c5c3_Err = layout(m).Render(templ.WithChildren(ctx, templ_7745c5c3_Var32), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/idiomatic/conditional_heavy.templ b/benchmarks/go/internal/templeng/idiomatic/conditional_heavy.templ new file mode 100644 index 00000000..ecc7c231 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/conditional_heavy.templ @@ -0,0 +1,41 @@ +// Workload 5 — conditional-heavy, templ idiomatic port. Idiomatic decomposition: a row +// component holding the four-way if/else if/else chain and the two toggles, invoked from +// the loop. The note text is composed in the template as the literal "note " plus the Seq +// substitution (the model carries data only). +// +// Official templ documentation for the constructs used here: +// - https://templ.guide/syntax-and-usage/statements/ (if/else if/else, for) +// - https://templ.guide/syntax-and-usage/expressions/ +// - https://templ.guide/syntax-and-usage/template-composition/ +package idiomatic + +import "heddle.dev/benchmarks/go/internal/model" + +templ matrixRow(r model.ConditionalRow) { +
    • + if r.IsBronze { + bronze + } else if r.IsSilver { + silver + } else if r.IsGold { + gold + } else { + platinum + } + { r.Name } + if r.HasNote { + note { r.Seq } + } + if r.IsActive { + active + } +
    • +} + +templ conditionalHeavy(m model.ConditionalModel) { +
        + for _, r := range m.Rows { + @matrixRow(r) + } +
      +} diff --git a/benchmarks/go/internal/templeng/idiomatic/conditional_heavy_templ.go b/benchmarks/go/internal/templeng/idiomatic/conditional_heavy_templ.go new file mode 100644 index 00000000..e134bc1b --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/conditional_heavy_templ.go @@ -0,0 +1,166 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 5 — conditional-heavy, templ idiomatic port. Idiomatic decomposition: a row + +// component holding the four-way if/else if/else chain and the two toggles, invoked from + +// the loop. The note text is composed in the template as the literal "note " plus the Seq + +// substitution (the model carries data only). + +// + +// Official templ documentation for the constructs used here: + +// - https://templ.guide/syntax-and-usage/statements/ (if/else if/else, for) + +// - https://templ.guide/syntax-and-usage/expressions/ + +// - https://templ.guide/syntax-and-usage/template-composition/ + +package idiomatic + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func matrixRow(r model.ConditionalRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
    • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if r.IsBronze { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "bronze ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else if r.IsSilver { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "silver ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else if r.IsGold { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "gold ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "platinum ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/conditional_heavy.templ`, Line: 25, Col: 14} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if r.HasNote { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "note ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(r.Seq) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/conditional_heavy.templ`, Line: 27, Col: 22} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + if r.IsActive { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "active") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
    • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func conditionalHeavy(m model.ConditionalModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
        ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, r := range m.Rows { + templ_7745c5c3_Err = matrixRow(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/idiomatic/encoded_loop.templ b/benchmarks/go/internal/templeng/idiomatic/encoded_loop.templ new file mode 100644 index 00000000..d395672d --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/encoded_loop.templ @@ -0,0 +1,27 @@ +// Workload 8 — encoded-loop, templ idiomatic port. Idiomatic decomposition: a row +// component invoked from the loop; data-tag={ r.Tag } is templ's attribute expression +// (auto-quoted and attribute-encoded), the other two substitutions are text-context — all +// emitted spellings sit inside the N5 table. +// +// Official templ documentation for the constructs used here: +// - https://templ.guide/syntax-and-usage/expressions/ +// - https://templ.guide/syntax-and-usage/statements/ +// - https://templ.guide/syntax-and-usage/template-composition/ +package idiomatic + +import "heddle.dev/benchmarks/go/internal/model" + +templ encodedLoopRow(r model.EncodedLoopRow) { + + { r.Name } + { r.Comment } + +} + +templ encodedLoop(m model.EncodedLoopModel) { + + for _, r := range m.Items { + @encodedLoopRow(r) + } +
      +} diff --git a/benchmarks/go/internal/templeng/idiomatic/encoded_loop_templ.go b/benchmarks/go/internal/templeng/idiomatic/encoded_loop_templ.go new file mode 100644 index 00000000..8aad0228 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/encoded_loop_templ.go @@ -0,0 +1,138 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 8 — encoded-loop, templ idiomatic port. Idiomatic decomposition: a row + +// component invoked from the loop; data-tag={ r.Tag } is templ's attribute expression + +// (auto-quoted and attribute-encoded), the other two substitutions are text-context — all + +// emitted spellings sit inside the N5 table. + +// + +// Official templ documentation for the constructs used here: + +// - https://templ.guide/syntax-and-usage/expressions/ + +// - https://templ.guide/syntax-and-usage/statements/ + +// - https://templ.guide/syntax-and-usage/template-composition/ + +package idiomatic + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func encodedLoopRow(r model.EncodedLoopRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/encoded_loop.templ`, Line: 16, Col: 33} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(r.Comment) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/encoded_loop.templ`, Line: 17, Col: 17} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func encodedLoop(m model.EncodedLoopModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var5 := templ.GetChildren(ctx) + if templ_7745c5c3_Var5 == nil { + templ_7745c5c3_Var5 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, r := range m.Items { + templ_7745c5c3_Err = encodedLoopRow(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/idiomatic/fortunes_encoded.templ b/benchmarks/go/internal/templeng/idiomatic/fortunes_encoded.templ new file mode 100644 index 00000000..a6c800da --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/fortunes_encoded.templ @@ -0,0 +1,45 @@ +// Workload 7 — fortunes-encoded, templ idiomatic port. Idiomatic decomposition: a row +// component invoked from the loop; templ's default escaping path fires on the { } +// expressions (its "/' spellings are reconciled by N5). +// +// Doctype authoring note (same variant as the controlled port): templ's generator +// normalizes a literal to lowercase — a non-whitespace byte +// change that would miss the verifier's "" ordered marker — so the doctype +// is emitted via @templ.Raw over the exact pinned literal (the engine's documented raw +// mechanism, applied to constant template text, not data). +// +// Official templ documentation for the constructs used here: +// - https://templ.guide/syntax-and-usage/expressions/ +// - https://templ.guide/syntax-and-usage/statements/ +// - https://templ.guide/syntax-and-usage/template-composition/ +// - https://templ.guide/syntax-and-usage/rendering-raw-html/ (doctype literal) +package idiomatic + +import "heddle.dev/benchmarks/go/internal/model" + +templ fortuneRow(r model.FortuneRow) { + + { r.Id } + { r.Message } + +} + +templ fortunesEncoded(m model.FortuneModel) { + @templ.Raw("") + + + Fortunes + + + + + + + + for _, r := range m.Rows { + @fortuneRow(r) + } +
      idmessage
      + + +} diff --git a/benchmarks/go/internal/templeng/idiomatic/fortunes_encoded_templ.go b/benchmarks/go/internal/templeng/idiomatic/fortunes_encoded_templ.go new file mode 100644 index 00000000..373c0e87 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/fortunes_encoded_templ.go @@ -0,0 +1,141 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 7 — fortunes-encoded, templ idiomatic port. Idiomatic decomposition: a row + +// component invoked from the loop; templ's default escaping path fires on the { } + +// expressions (its "/' spellings are reconciled by N5). + +// + +// Doctype authoring note (same variant as the controlled port): templ's generator + +// normalizes a literal to lowercase — a non-whitespace byte + +// change that would miss the verifier's "" ordered marker — so the doctype + +// is emitted via @templ.Raw over the exact pinned literal (the engine's documented raw + +// mechanism, applied to constant template text, not data). + +// + +// Official templ documentation for the constructs used here: + +// - https://templ.guide/syntax-and-usage/expressions/ + +// - https://templ.guide/syntax-and-usage/statements/ + +// - https://templ.guide/syntax-and-usage/template-composition/ + +// - https://templ.guide/syntax-and-usage/rendering-raw-html/ (doctype literal) + +package idiomatic + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func fortuneRow(r model.FortuneRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(r.Id) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fortunes_encoded.templ`, Line: 22, Col: 12} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(r.Message) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fortunes_encoded.templ`, Line: 23, Col: 17} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func fortunesEncoded(m model.FortuneModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templ.Raw("").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "Fortunes") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, r := range m.Rows { + templ_7745c5c3_Err = fortuneRow(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
      idmessage
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/idiomatic/fragment_heavy.templ b/benchmarks/go/internal/templeng/idiomatic/fragment_heavy.templ new file mode 100644 index 00000000..07726c22 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/fragment_heavy.templ @@ -0,0 +1,75 @@ +// Workload 6 — fragment-heavy, templ idiomatic port. Six components — tile, card +// (nesting @badge/@price against the row's Promo, +// the one nesting level), badge, price, mediaRow, stat — dispatched per row with templ's +// native switch statement over Kind (the sanctioned idiomatic dispatch form for templ, +// where the controlled port keeps the boolean chain). Derived display text is composed in the template as +// literal-plus-substitution (the model carries data only): price + ".99", "Caption for " + name, "/img/" + name + +// ".jpg". +// +// Official templ documentation for the constructs used here: +// - https://templ.guide/syntax-and-usage/statements/ (switch, for) +// - https://templ.guide/syntax-and-usage/template-composition/ (component nesting) +// - https://templ.guide/syntax-and-usage/expressions/ (text and attribute expressions) +package idiomatic + +import "heddle.dev/benchmarks/go/internal/model" + +templ tile(r model.FragmentRow) { +
      +

      { r.Name }

      +

      { r.Value }

      + { r.Badge } +
      +} + +templ badge(p model.FragmentPromo) { + { p.Label } +} + +templ price(p model.FragmentPromo) { +

      { p.Price }.99

      +} + +templ card(r model.FragmentRow) { +
      +

      { r.Name }

      + @badge(r.Promo) + @price(r.Promo) +

      { r.Value }

      +
      +} + +templ mediaRow(r model.FragmentRow) { +
      + { +
      +

      { r.Name }

      +

      Caption for { r.Name }

      +
      +
      +} + +templ stat(r model.FragmentRow) { +
      + { r.Name } + { r.Value } + { r.Delta } +
      +} + +templ fragmentHeavy(m model.FragmentModel) { +
      + for _, r := range m.Items { + switch r.Kind { + case "tile": + @tile(r) + case "card": + @card(r) + case "media": + @mediaRow(r) + default: + @stat(r) + } + } +
      +} diff --git a/benchmarks/go/internal/templeng/idiomatic/fragment_heavy_templ.go b/benchmarks/go/internal/templeng/idiomatic/fragment_heavy_templ.go new file mode 100644 index 00000000..0c7947f5 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/fragment_heavy_templ.go @@ -0,0 +1,462 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 6 — fragment-heavy, templ idiomatic port. Six components — tile, card + +// (nesting @badge/@price against the row's Promo, + +// the one nesting level), badge, price, mediaRow, stat — dispatched per row with templ's + +// native switch statement over Kind (the sanctioned idiomatic dispatch form for templ, + +// where the controlled port keeps the boolean chain). Derived display text is composed in the template as + +// literal-plus-substitution (the model carries data only): price + ".99", "Caption for " + name, "/img/" + name + + +// ".jpg". + +// + +// Official templ documentation for the constructs used here: + +// - https://templ.guide/syntax-and-usage/statements/ (switch, for) + +// - https://templ.guide/syntax-and-usage/template-composition/ (component nesting) + +// - https://templ.guide/syntax-and-usage/expressions/ (text and attribute expressions) + +package idiomatic + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func tile(r model.FragmentRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 19, Col: 14} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(r.Value) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 20, Col: 24} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(r.Badge) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 21, Col: 31} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func badge(p model.FragmentPromo) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var5 := templ.GetChildren(ctx) + if templ_7745c5c3_Var5 == nil { + templ_7745c5c3_Var5 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(p.Label) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 26, Col: 36} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func price(p model.FragmentPromo) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var7 := templ.GetChildren(ctx) + if templ_7745c5c3_Var7 == nil { + templ_7745c5c3_Var7 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(p.Price) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 30, Col: 27} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, ".99

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func card(r model.FragmentRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var9 := templ.GetChildren(ctx) + if templ_7745c5c3_Var9 == nil { + templ_7745c5c3_Var9 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 35, Col: 14} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = badge(r.Promo).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = price(r.Promo).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(r.Value) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 38, Col: 24} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func mediaRow(r model.FragmentRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var12 := templ.GetChildren(ctx) + if templ_7745c5c3_Var12 == nil { + templ_7745c5c3_Var12 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
      \"")

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 46, Col: 15} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "

      Caption for ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var16 string + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 47, Col: 26} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func stat(r model.FragmentRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var17 := templ.GetChildren(ctx) + if templ_7745c5c3_Var17 == nil { + templ_7745c5c3_Var17 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var18 string + templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(r.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 54, Col: 34} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var19 string + templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(r.Value) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 55, Col: 36} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(r.Delta) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/fragment_heavy.templ`, Line: 56, Col: 36} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func fragmentHeavy(m model.FragmentModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var21 := templ.GetChildren(ctx) + if templ_7745c5c3_Var21 == nil { + templ_7745c5c3_Var21 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, r := range m.Items { + switch r.Kind { + case "tile": + templ_7745c5c3_Err = tile(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + case "card": + templ_7745c5c3_Err = card(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + case "media": + templ_7745c5c3_Err = mediaRow(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + default: + templ_7745c5c3_Err = stat(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/idiomatic/large_loop.templ b/benchmarks/go/internal/templeng/idiomatic/large_loop.templ new file mode 100644 index 00000000..9f3ac58c --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/large_loop.templ @@ -0,0 +1,25 @@ +// Workload 3 — large-loop, templ idiomatic port. Idiomatic component decomposition: a row +// component invoked from the loop; the display name is composed in the template as the +// literal "row-" plus the value substitution (the model carries only Value); ints +// render natively via { } expressions. +// +// Official templ documentation for the constructs used here: +// - https://templ.guide/syntax-and-usage/expressions/ +// - https://templ.guide/syntax-and-usage/statements/ +// - https://templ.guide/syntax-and-usage/template-composition/ +package idiomatic + +import "heddle.dev/benchmarks/go/internal/model" + +templ largeLoopRow(r model.LoopRow) { + + row-{ r.Value } + { r.Value } + +} + +templ largeLoop(m model.LoopModel) { + for _, r := range m.Items { + @largeLoopRow(r) + } +} diff --git a/benchmarks/go/internal/templeng/idiomatic/large_loop_templ.go b/benchmarks/go/internal/templeng/idiomatic/large_loop_templ.go new file mode 100644 index 00000000..fe6ce05b --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/large_loop_templ.go @@ -0,0 +1,117 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 3 — large-loop, templ idiomatic port. Idiomatic component decomposition: a row + +// component invoked from the loop; the display name is composed in the template as the + +// literal "row-" plus the value substitution (the model carries only Value); ints + +// render natively via { } expressions. + +// + +// Official templ documentation for the constructs used here: + +// - https://templ.guide/syntax-and-usage/expressions/ + +// - https://templ.guide/syntax-and-usage/statements/ + +// - https://templ.guide/syntax-and-usage/template-composition/ + +package idiomatic + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func largeLoopRow(r model.LoopRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "row-") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(r.Value) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/large_loop.templ`, Line: 16, Col: 19} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(r.Value) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/large_loop.templ`, Line: 17, Col: 15} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func largeLoop(m model.LoopModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + for _, r := range m.Items { + templ_7745c5c3_Err = largeLoopRow(r).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/idiomatic/mixed_page.templ b/benchmarks/go/internal/templeng/idiomatic/mixed_page.templ new file mode 100644 index 00000000..820e58d5 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/mixed_page.templ @@ -0,0 +1,79 @@ +// Workload 4 — mixed-page, templ idiomatic port. Single-file, no layout/body split (by rule, +// layout composition is composed-page's dimension — an idiomatic mixed-page that split +// into a layout plus body would measure the wrong thing on the wrong row); idiomatic +// decomposition is limited to a product-card component invoked from the loop. The display +// SKU is composed in the template as the literal "MX-" plus the SkuNumber substitution and +// the blurb sentence lives in the template around the Batch substitution (the model +// carries data only). +// +// Doctype authoring note (same variant as the controlled port): templ's generator +// normalizes a literal to lowercase — a non-whitespace byte +// change that would miss the verifier's "" ordered marker — so the doctype +// is emitted via @templ.Raw over the exact pinned literal (the engine's documented raw +// mechanism, applied to constant template text, not data). +// +// Official templ documentation for the constructs used here: +// - https://templ.guide/syntax-and-usage/expressions/ +// - https://templ.guide/syntax-and-usage/statements/ +// - https://templ.guide/syntax-and-usage/template-composition/ (component call in loop) +// - https://templ.guide/syntax-and-usage/rendering-raw-html/ (doctype literal) +package idiomatic + +import "heddle.dev/benchmarks/go/internal/model" + +templ productCard(p model.MixedProduct) { +
      +

      { p.Name }

      +

      MX-{ p.SkuNumber }

      +

      { p.Price }

      + if p.OnSale { +

      On sale

      + } +

      A dependable workshop staple from batch { p.Batch }, checked for daily use and backed by our lifetime guarantee.

      +
      +} + +templ mixedPage(m model.MixedModel) { + @templ.Raw("") + + + + { m.PageTitle } + + + +
      +

      { m.StoreName }

      + +
      +
      + if m.ShowBanner { + + } +
      +

      { m.HeroHeading }

      +

      { m.HeroTagline }

      +
      +
      + for _, p := range m.Products { + @productCard(p) + } +
      + if m.ShowDebugPanel { +
      debug
      + } +
      +
      +

      { m.FooterNote }

      +

      { m.StoreName } { m.Year } { m.SupportEmail }

      +
      + + +} diff --git a/benchmarks/go/internal/templeng/idiomatic/mixed_page_templ.go b/benchmarks/go/internal/templeng/idiomatic/mixed_page_templ.go new file mode 100644 index 00000000..7ae9bd77 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/mixed_page_templ.go @@ -0,0 +1,322 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 4 — mixed-page, templ idiomatic port. Single-file, no layout/body split (by rule, + +// layout composition is composed-page's dimension — an idiomatic mixed-page that split + +// into a layout plus body would measure the wrong thing on the wrong row); idiomatic + +// decomposition is limited to a product-card component invoked from the loop. The display + +// SKU is composed in the template as the literal "MX-" plus the SkuNumber substitution and + +// the blurb sentence lives in the template around the Batch substitution (the model + +// carries data only). + +// + +// Doctype authoring note (same variant as the controlled port): templ's generator + +// normalizes a literal to lowercase — a non-whitespace byte + +// change that would miss the verifier's "" ordered marker — so the doctype + +// is emitted via @templ.Raw over the exact pinned literal (the engine's documented raw + +// mechanism, applied to constant template text, not data). + +// + +// Official templ documentation for the constructs used here: + +// - https://templ.guide/syntax-and-usage/expressions/ + +// - https://templ.guide/syntax-and-usage/statements/ + +// - https://templ.guide/syntax-and-usage/template-composition/ (component call in loop) + +// - https://templ.guide/syntax-and-usage/rendering-raw-html/ (doctype literal) + +package idiomatic + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func productCard(p model.MixedProduct) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 26, Col: 14} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

      MX-") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(p.SkuNumber) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 27, Col: 33} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(p.Price) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 28, Col: 28} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if p.OnSale { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

      On sale

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

      A dependable workshop staple from batch ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(p.Batch) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 32, Col: 68} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, ", checked for daily use and backed by our lifetime guarantee.

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func mixedPage(m model.MixedModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var6 := templ.GetChildren(ctx) + if templ_7745c5c3_Var6 == nil { + templ_7745c5c3_Var6 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templ.Raw("").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(m.PageTitle) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 41, Col: 23} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(m.StoreName) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 46, Col: 21} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if m.ShowBanner { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(m.BannerText) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 58, Col: 39} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(m.HeroHeading) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 61, Col: 24} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(m.HeroTagline) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 62, Col: 23} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, p := range m.Products { + templ_7745c5c3_Err = productCard(p).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if m.ShowDebugPanel { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
      debug
      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(m.FooterNote) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 74, Col: 21} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(m.StoreName) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 75, Col: 20} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(m.Year) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 75, Col: 31} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(m.SupportEmail) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/mixed_page.templ`, Line: 75, Col: 50} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/internal/templeng/idiomatic/render.go b/benchmarks/go/internal/templeng/idiomatic/render.go new file mode 100644 index 00000000..4c3bfc32 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/render.go @@ -0,0 +1,81 @@ +// Package idiomatic hosts the templ idiomatic-track ports (one .templ file per workload, +// generated *_templ.go committed, regenerated only with the pinned CLI): naturally +// formatted (templ fmt), idiomatic component decomposition, official-doc citations per +// file. Render path is identical to the controlled track: +// component.Render(ctx, buf) into a reused pre-grown bytes.Buffer with a +// background context.Context created once; construction of the component value (a cheap +// closure) is inside the render — templ's per-render entry point. +package idiomatic + +import ( + "bytes" + "context" + + "github.com/a-h/templ" + + "heddle.dev/benchmarks/go/internal/model" +) + +// ctx is the background context, built once and shared by every render. +var ctx = context.Background() + +// newBuf returns a buffer pre-grown to the workload's output size, so growth never lands +// in a timed region (encoded-loop's ~1.1 MB escaped output is the sizing case). +func newBuf(capacity int) *bytes.Buffer { + buf := new(bytes.Buffer) + buf.Grow(capacity) + return buf +} + +var ( + composedBuf = newBuf(64 << 10) + trivialBuf = newBuf(1 << 10) + largeLoopBuf = newBuf(256 << 10) + mixedBuf = newBuf(32 << 10) + conditionalBuf = newBuf(32 << 10) + fragmentBuf = newBuf(16 << 10) + fortunesBuf = newBuf(4 << 10) + encodedLoopBuf = newBuf(2 << 20) +) + +// render resets the cell's buffer, renders the component, and returns the output. +// A render error is a harness defect, never a gate outcome — panic loudly. +func render(c templ.Component, buf *bytes.Buffer) string { + buf.Reset() + if err := c.Render(ctx, buf); err != nil { + panic("templeng/idiomatic: render failed: " + err.Error()) + } + return buf.String() +} + +// ---- the eight idiomatic cells --------------------------------------------------------------- + +// RenderComposedPage renders workload 1 idiomatically via templ (model.Composed() loads +// the nav fixture exactly once — sync.Once — so the per-render cost is a call plus a +// struct copy). +func RenderComposedPage() string { return render(composedPage(model.Composed()), composedBuf) } + +// RenderTrivialSubstitution renders workload 2 idiomatically via templ. +func RenderTrivialSubstitution() string { + return render(trivialSubstitution(model.Substitution), trivialBuf) +} + +// RenderLargeLoop renders workload 3 idiomatically via templ. +func RenderLargeLoop() string { return render(largeLoop(model.LargeLoop), largeLoopBuf) } + +// RenderMixedPage renders workload 4 idiomatically via templ. +func RenderMixedPage() string { return render(mixedPage(model.Mixed), mixedBuf) } + +// RenderConditionalHeavy renders workload 5 idiomatically via templ. +func RenderConditionalHeavy() string { + return render(conditionalHeavy(model.Conditional), conditionalBuf) +} + +// RenderFragmentHeavy renders workload 6 idiomatically via templ. +func RenderFragmentHeavy() string { return render(fragmentHeavy(model.Fragment), fragmentBuf) } + +// RenderFortunesEncoded renders workload 7 idiomatically via templ (default escaping path). +func RenderFortunesEncoded() string { return render(fortunesEncoded(model.Fortunes), fortunesBuf) } + +// RenderEncodedLoop renders workload 8 idiomatically via templ (default escaping path). +func RenderEncodedLoop() string { return render(encodedLoop(model.EncodedLoop), encodedLoopBuf) } diff --git a/benchmarks/go/internal/templeng/idiomatic/trivial_substitution.templ b/benchmarks/go/internal/templeng/idiomatic/trivial_substitution.templ new file mode 100644 index 00000000..d0b409f2 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/trivial_substitution.templ @@ -0,0 +1,25 @@ +// Workload 2 — trivial-substitution, templ idiomatic port. Naturally formatted — indented, +// one element per line (the shape templ fmt produces) — with { } text expressions and +// attribute expressions. +// +// Official templ documentation for the constructs used here: +// - https://templ.guide/syntax-and-usage/expressions/ +package idiomatic + +import "heddle.dev/benchmarks/go/internal/model" + +templ trivialSubstitution(m model.SubstitutionModel) { +
      +

      { m.Title }

      +

      { m.Sku }

      +

      { m.Price }

      +

      { m.Brand }

      +

      { m.Category }

      +

      { m.Availability }

      + + + +

      { m.Summary }

      +

      { m.Rating }

      +
      +} diff --git a/benchmarks/go/internal/templeng/idiomatic/trivial_substitution_templ.go b/benchmarks/go/internal/templeng/idiomatic/trivial_substitution_templ.go new file mode 100644 index 00000000..a62a53f0 --- /dev/null +++ b/benchmarks/go/internal/templeng/idiomatic/trivial_substitution_templ.go @@ -0,0 +1,184 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1020 +// Workload 2 — trivial-substitution, templ idiomatic port. Naturally formatted — indented, + +// one element per line (the shape templ fmt produces) — with { } text expressions and + +// attribute expressions. + +// + +// Official templ documentation for the constructs used here: + +// - https://templ.guide/syntax-and-usage/expressions/ + +package idiomatic + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "heddle.dev/benchmarks/go/internal/model" + +func trivialSubstitution(m model.SubstitutionModel) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(m.Title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/trivial_substitution.templ`, Line: 13, Col: 15} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(m.Sku) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/trivial_substitution.templ`, Line: 14, Col: 24} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(m.Price) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/trivial_substitution.templ`, Line: 15, Col: 28} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(m.Brand) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/trivial_substitution.templ`, Line: 16, Col: 28} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(m.Category) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/trivial_substitution.templ`, Line: 17, Col: 29} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(m.Availability) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/trivial_substitution.templ`, Line: 18, Col: 35} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(m.Summary) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/trivial_substitution.templ`, Line: 22, Col: 28} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(m.Rating) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templeng/idiomatic/trivial_substitution.templ`, Line: 23, Col: 30} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

      ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/benchmarks/go/run-benchmarks.ps1 b/benchmarks/go/run-benchmarks.ps1 new file mode 100644 index 00000000..fa315fec --- /dev/null +++ b/benchmarks/go/run-benchmarks.ps1 @@ -0,0 +1,112 @@ +# run-benchmarks.ps1 -- the Go harness's reproduce-it-yourself entry point. +# +# Performs, in order: +# 1. Toolchain version assertions (go1.26.5; templ v0.3.1020 via `go tool` — the pinned CLI). +# 2. `go tool templ generate` + `git diff --exit-code -- *_templ.go` (regeneration +# freshness -- committed generated code must match the pinned generator). +# 3. `go vet ./...` +# 4. `go test ./...` (gates + unit tests; TestMain gates before anything can time). +# 5. Prebuild: `go test -c -o bench.exe ./suites`. +# 6. Two timed invocations at High process priority via `cmd /c start /high /wait /b` +# (priority set at process creation, no race): BenchmarkRender, then the +# BenchmarkColdParse sidebar. Defaults: -test.count=28, -test.benchtime=1s (the pinned +# per-engine sample budget). +# 7. benchstat over each output. +# +# Windows PowerShell 5.1 compatible (no pipeline chain operators, ASCII only). +param( + [int]$Count = 28, + [string]$BenchTime = "1s", + [switch]$VersionCheckOnly +) + +$ErrorActionPreference = "Stop" +Set-Location $PSScriptRoot + +function Assert-LastExit([string]$step) { + if ($LASTEXITCODE -ne 0) { + Write-Host ("FAIL: " + $step + " (exit code " + $LASTEXITCODE + ")") + exit 1 + } +} + +# --- 1. Toolchain version assertions --------------------------------------------------------- +$goVersion = (& go version) -join " " +Assert-LastExit "go version" +if ($goVersion -notmatch "go1\.26\.5") { + Write-Host ("FAIL: pinned toolchain is go1.26.5; found: " + $goVersion) + exit 1 +} +$templVersion = ((& go tool templ version) -join " ").Trim() +Assert-LastExit "go tool templ version" +if ($templVersion -ne "v0.3.1020") { + Write-Host ("FAIL: pinned templ CLI is v0.3.1020; found: " + $templVersion) + exit 1 +} +Write-Host ("OK: " + $goVersion + "; templ " + $templVersion) +if ($VersionCheckOnly) { + Write-Host "Version asserts passed; exiting (VersionCheckOnly)." + exit 0 +} + +# --- 2. Regeneration freshness --------------------------------------------------------------- +& go tool templ generate +Assert-LastExit "go tool templ generate" +& git diff --exit-code -- "*_templ.go" +if ($LASTEXITCODE -ne 0) { + Write-Host "FAIL: committed *_templ.go does not match the pinned generator's output." + exit 1 +} + +# --- 3. Vet ---------------------------------------------------------------------------------- +& go vet ./... +Assert-LastExit "go vet" + +# --- 4. Gates + unit tests ------------------------------------------------------------------- +& go test ./... +Assert-LastExit "go test (gates + unit tests)" + +# --- 5. Prebuild ----------------------------------------------------------------------------- +& go test -c -o bench.exe ./suites +Assert-LastExit "go test -c (prebuild)" + +# --- 6. Timed invocations at High priority --------------------------------------------------- +if (-not (Test-Path "results")) { + New-Item -ItemType Directory -Path "results" | Out-Null +} +$stamp = Get-Date -Format "yyyyMMdd" +$renderOut = "results\bench-render-" + $stamp + ".txt" +$coldOut = "results\bench-coldparse-" + $stamp + ".txt" + +# Carets are cmd.exe escape characters, so the regex anchors are written ^^ below. +$renderCmd = "start /high /wait /b bench.exe -test.run ^^$ -test.bench ^^BenchmarkRender$ " + + "-test.benchtime " + $BenchTime + " -test.count " + $Count + " > " + $renderOut + " 2>&1" +& cmd /c $renderCmd +Assert-LastExit "BenchmarkRender timed run" +Write-Host ("BenchmarkRender run written to " + $renderOut) + +$coldCmd = "start /high /wait /b bench.exe -test.run ^^$ -test.bench ^^BenchmarkColdParse$ " + + "-test.benchtime " + $BenchTime + " -test.count " + $Count + " > " + $coldOut + " 2>&1" +& cmd /c $coldCmd +Assert-LastExit "BenchmarkColdParse timed run" +Write-Host ("BenchmarkColdParse run written to " + $coldOut) +Write-Host "Note: both stdlib cold rows are 'cold parse only' (html/template escape-compilation is lazy)." +Write-Host "Note: templ sidebar cells are 'AOT - no runtime parse (compiled by go generate)'." + +# --- 7. benchstat ---------------------------------------------------------------------------- +$benchstatRender = "results\benchstat-render-" + $stamp + ".txt" +$benchstatCold = "results\benchstat-coldparse-" + $stamp + ".txt" +# Redirected inside cmd.exe, NOT piped through Out-File. benchstat draws its table with U+2502 +# box-drawing characters, and consolidate.py locates the sec/op block by looking for them. Piping +# through PowerShell 5.1 decoded benchstat's UTF-8 stdout as the console codepage first, so the +# three bytes E2 94 82 became three separate mis-decoded characters, and Out-File then re-encoded +# that damage as UTF-8. The corruption was silent -- the file still looks like a table to a human +# skimming it -- and surfaced only as consolidate.py's "no sec/op block found", one whole +# measurement session later. cmd's `>` writes the child process's bytes straight to disk with +# nothing in between to decode them. +cmd /c ('go tool benchstat ' + $renderOut + ' > ' + $benchstatRender) +Assert-LastExit "benchstat (render)" +cmd /c ('go tool benchstat ' + $coldOut + ' > ' + $benchstatCold) +Assert-LastExit "benchstat (coldparse)" + +Write-Host ("Done. benchstat summaries: " + $benchstatRender + ", " + $benchstatCold) diff --git a/benchmarks/go/run-benchmarks.sh b/benchmarks/go/run-benchmarks.sh new file mode 100755 index 00000000..a21905c8 --- /dev/null +++ b/benchmarks/go/run-benchmarks.sh @@ -0,0 +1,133 @@ +#!/usr/bin/env bash +# run-benchmarks.sh -- Linux twin of run-benchmarks.ps1: the Go harness's +# reproduce-it-yourself entry point. +# +# Performs, in order: +# 1. Toolchain version assertions (go1.26.5; templ v0.3.1020 via `go tool` — the pinned CLI). +# 2. `go tool templ generate` + `git diff --exit-code -- *_templ.go` (regeneration +# freshness -- committed generated code must match the pinned generator). +# 3. `go vet ./...` +# 4. `go test ./...` (gates + unit tests; TestMain gates before anything can time). +# 5. Prebuild: `go test -c -o bench ./suites`. +# 6. Two timed invocations: BenchmarkRender, then the BenchmarkColdParse sidebar. +# Defaults: -test.count=28, -test.benchtime=1s (the pinned per-engine sample budget). +# 7. benchstat over each output. +# +# Priority posture: run-benchmarks.ps1 launches through `cmd /c start /high`; this twin +# approximates that with `taskset -c ` + `nice -n -20` (see +# benchmarks/bench-common.sh). That is a deliberate delta from +# benchmarks/linux-crosscheck/run-go.sh, which launches the prebuilt binary plain under the +# crosscheck's no-priority rule -- record the delta in the run report, or pass --no-priority. + +set -uo pipefail + +HARNESS_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +. "$(cd -- "$HARNESS_ROOT/.." >/dev/null 2>&1 && pwd)/bench-common.sh" + +usage() { + echo "usage: run-benchmarks.sh [--count N] [--benchtime D] [--version-check-only] [--no-priority]" + echo " --count N -test.count for both timed runs (default 28)" + echo " --benchtime D -test.benchtime for both timed runs (default 1s)" + echo " --version-check-only run the toolchain asserts and exit" + echo " --no-priority plain launch, no taskset/nice (the crosscheck posture)" +} + +COUNT=28 +BENCHTIME="1s" +VERSION_CHECK_ONLY=0 +while [ $# -gt 0 ]; do + case "$1" in + --count) COUNT="${2:?--count requires N}"; shift ;; + --benchtime) BENCHTIME="${2:?--benchtime requires a duration}"; shift ;; + --version-check-only) VERSION_CHECK_ONLY=1 ;; + --no-priority) BENCH_NO_PRIORITY=1 ;; + -h|--help) usage; exit 0 ;; + *) bench_die "unknown argument: $1" ;; + esac + shift +done +case "$COUNT" in + ''|*[!0-9]*) bench_die "--count must be an integer" ;; +esac + +cd "$HARNESS_ROOT" + +assert_last_exit() { # exit_code step + if [ "$1" -ne 0 ]; then + echo "FAIL: $2 (exit code $1)" >&2 + exit 1 + fi +} + +# --- 1. Toolchain version assertions ------------------------------------------------------ +GO_VERSION="$(go version)"; assert_last_exit $? "go version" +case "$GO_VERSION" in + *go1.26.5*) : ;; + *) echo "FAIL: pinned toolchain is go1.26.5; found: $GO_VERSION" >&2; exit 1 ;; +esac +# `go tool` may print "go: downloading ..." lines first; the version is the last line. +TEMPL_VERSION="$(go tool templ version)"; assert_last_exit $? "go tool templ version" +TEMPL_VERSION="$(printf '%s\n' "$TEMPL_VERSION" | tail -n 1 | tr -d '[:space:]')" +if [ "$TEMPL_VERSION" != "v0.3.1020" ]; then + echo "FAIL: pinned templ CLI is v0.3.1020; found: $TEMPL_VERSION" >&2 + exit 1 +fi +echo "OK: $GO_VERSION; templ $TEMPL_VERSION" +if [ "$VERSION_CHECK_ONLY" = "1" ]; then + echo "Version asserts passed; exiting (--version-check-only)." + exit 0 +fi + +# --- 2. Regeneration freshness ------------------------------------------------------------- +go tool templ generate; assert_last_exit $? "go tool templ generate" +if ! git diff --exit-code -- '*_templ.go'; then + echo "FAIL: committed *_templ.go does not match the pinned generator's output." >&2 + exit 1 +fi + +# --- 3. Vet -------------------------------------------------------------------------------- +go vet ./...; assert_last_exit $? "go vet" + +# --- 4. Gates + unit tests ----------------------------------------------------------------- +go test ./...; assert_last_exit $? "go test (gates + unit tests)" + +# --- 5. Prebuild --------------------------------------------------------------------------- +go test -c -o bench ./suites; assert_last_exit $? "go test -c (prebuild)" + +# --- 6. Timed invocations ------------------------------------------------------------------- +mkdir -p results +STAMP="$(date +%Y%m%d)" +RENDER_OUT="results/bench-render-$STAMP.txt" +COLD_OUT="results/bench-coldparse-$STAMP.txt" + +bench_priority_argv +[ -n "$BENCH_PRIORITY_RECORDED" ] && echo "run-benchmarks.sh: $BENCH_PRIORITY_RECORDED" +if [ "${#BENCH_PRIORITY_PREFIX[@]}" -gt 0 ]; then + echo "run-benchmarks.sh: launch prefix: ${BENCH_PRIORITY_PREFIX[*]}" +fi + +timed_run() { # bench_regex out_path + ${BENCH_PRIORITY_PREFIX[@]+"${BENCH_PRIORITY_PREFIX[@]}"} \ + ./bench -test.run '^$' -test.bench "$1" \ + -test.benchtime "$BENCHTIME" -test.count "$COUNT" > "$2" 2>&1 +} + +timed_run '^BenchmarkRender$' "$RENDER_OUT" +assert_last_exit $? "BenchmarkRender timed run" +echo "BenchmarkRender run written to $RENDER_OUT" + +timed_run '^BenchmarkColdParse$' "$COLD_OUT" +assert_last_exit $? "BenchmarkColdParse timed run" +echo "BenchmarkColdParse run written to $COLD_OUT" +echo "Note: both stdlib cold rows are 'cold parse only' (html/template escape-compilation is lazy)." +echo "Note: templ sidebar cells are 'AOT - no runtime parse (compiled by go generate)'." + +# --- 7. benchstat --------------------------------------------------------------------------- +BENCHSTAT_RENDER="results/benchstat-render-$STAMP.txt" +BENCHSTAT_COLD="results/benchstat-coldparse-$STAMP.txt" +go tool benchstat "$RENDER_OUT" > "$BENCHSTAT_RENDER" +assert_last_exit $? "benchstat (render)" +go tool benchstat "$COLD_OUT" > "$BENCHSTAT_COLD" +assert_last_exit $? "benchstat (coldparse)" + +echo "Done. benchstat summaries: $BENCHSTAT_RENDER, $BENCHSTAT_COLD" diff --git a/benchmarks/go/suites/bench_test.go b/benchmarks/go/suites/bench_test.go new file mode 100644 index 00000000..a31b7485 --- /dev/null +++ b/benchmarks/go/suites/bench_test.go @@ -0,0 +1,51 @@ +// BenchmarkRender — one sub-benchmark per gated cell, named for benchstat grouping: +// +// BenchmarkRender/// +// +// Body shape, normative: b.ReportAllocs() in every benchmark (allocation figures are +// structural, not flag-dependent); for b.Loop() with a package-level sink (keeps the +// result alive, excludes setup from timing). Template parse / templ component setup / +// model materialization all happen in package init or TestMain — never here — and every +// gate has already passed in TestMain before any benchmark in this package can time. +package suites + +import "testing" + +// sink keeps every timed render's result alive (belt-and-braces against dead-code +// elimination, alongside b.Loop's own guarantee). +var sink string + +// workloadOrder fixes the benchmark ordering to the pinned workload numbering. +var workloadOrder = []string{ + "composed-page", + "trivial-substitution", + "large-loop", + "mixed-page", + "conditional-heavy", + "fragment-heavy", + "fortunes-encoded", + "encoded-loop", +} + +func BenchmarkRender(b *testing.B) { + for _, track := range []string{"controlled", "idiomatic"} { + b.Run(track, func(b *testing.B) { + for _, workload := range workloadOrder { + b.Run(workload, func(b *testing.B) { + for _, c := range cells { + if c.Track != track || c.Workload != workload { + continue + } + render := c.Render + b.Run(c.Engine, func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + sink = render() + } + }) + } + }) + } + }) + } +} diff --git a/benchmarks/go/suites/coldparse_test.go b/benchmarks/go/suites/coldparse_test.go new file mode 100644 index 00000000..a363fb66 --- /dev/null +++ b/benchmarks/go/suites/coldparse_test.go @@ -0,0 +1,36 @@ +// BenchmarkColdParse — the per-ecosystem, non-comparable cold-cost sidebar. Two cells only: +// +// BenchmarkColdParse/stdlib-text — parse the six raw-suite template sources per iteration +// BenchmarkColdParse/stdlib-html — parse the two encoded-suite template sources per iteration +// +// Both rows are labeled "cold parse only" in the report: html/template's contextual +// escaping analysis runs lazily at the first Execute, not at Parse, so a Parse-only loop +// deliberately does not capture escape-compilation. templ has no runtime parse step — its +// report cells print "AOT — no runtime parse (compiled by go generate)" instead of a +// number; that asymmetry is the sidebar's only load-bearing point. These figures never +// appear as a cross-language column. +package suites + +import ( + "testing" + + stdlibcontrolled "heddle.dev/benchmarks/go/internal/stdlibtpl/controlled" +) + +// coldSink keeps each iteration's parsed template set alive. +var coldSink any + +func BenchmarkColdParse(b *testing.B) { + b.Run("stdlib-text", func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + coldSink = stdlibcontrolled.ColdParseText() + } + }) + b.Run("stdlib-html", func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + coldSink = stdlibcontrolled.ColdParseHTML() + } + }) +} diff --git a/benchmarks/go/suites/gate_test.go b/benchmarks/go/suites/gate_test.go new file mode 100644 index 00000000..4752dfe9 --- /dev/null +++ b/benchmarks/go/suites/gate_test.go @@ -0,0 +1,166 @@ +// Package suites hosts the harness's gates and benchmarks. TestMain runs every registered +// gate — corpus integrity, the untrusted-data alphabet assert, every controlled cell's byte +// gate, and every idiomatic cell's verification — before m.Run(), so no benchmark in the +// package can time until every gate passed in the same invocation. The same checks are +// exposed as ordinary Test functions so plain `go test ./suites` is the harness's parity +// command (the Go analogue of the .NET `-- parity` verb). +package suites + +import ( + "fmt" + "os" + "testing" + + "heddle.dev/benchmarks/go/internal/corpus" + "heddle.dev/benchmarks/go/internal/model" + stdlibcontrolled "heddle.dev/benchmarks/go/internal/stdlibtpl/controlled" + stdlibidiomatic "heddle.dev/benchmarks/go/internal/stdlibtpl/idiomatic" + templcontrolled "heddle.dev/benchmarks/go/internal/templeng/controlled" + templidiomatic "heddle.dev/benchmarks/go/internal/templeng/idiomatic" +) + +// cell is one gated workload × engine × track combination. +type cell struct { + Track string // "controlled" | "idiomatic" + Engine string // "stdlib-text" | "stdlib-html" | "templ" + Workload string // shared workload id + Suite string // "raw" | "encoded" + Render func() string +} + +// cells is the gate registry: every engine × workload × track combination that must pass +// before anything in this package times. +var cells = []cell{ + // stdlib controlled: text/template on the six raw workloads, html/template on + // the two encoded. + {"controlled", "stdlib-text", "composed-page", "raw", stdlibcontrolled.RenderComposedPage}, + {"controlled", "stdlib-text", "trivial-substitution", "raw", stdlibcontrolled.RenderTrivialSubstitution}, + {"controlled", "stdlib-text", "large-loop", "raw", stdlibcontrolled.RenderLargeLoop}, + {"controlled", "stdlib-text", "mixed-page", "raw", stdlibcontrolled.RenderMixedPage}, + {"controlled", "stdlib-text", "conditional-heavy", "raw", stdlibcontrolled.RenderConditionalHeavy}, + {"controlled", "stdlib-text", "fragment-heavy", "raw", stdlibcontrolled.RenderFragmentHeavy}, + {"controlled", "stdlib-html", "fortunes-encoded", "encoded", stdlibcontrolled.RenderFortunesEncoded}, + {"controlled", "stdlib-html", "encoded-loop", "encoded", stdlibcontrolled.RenderEncodedLoop}, + // templ controlled: all eight workloads (@templ.Raw only over pinned literal template + // text; the default escaping path on the encoded pair). + {"controlled", "templ", "composed-page", "raw", templcontrolled.RenderComposedPage}, + {"controlled", "templ", "trivial-substitution", "raw", templcontrolled.RenderTrivialSubstitution}, + {"controlled", "templ", "large-loop", "raw", templcontrolled.RenderLargeLoop}, + {"controlled", "templ", "mixed-page", "raw", templcontrolled.RenderMixedPage}, + {"controlled", "templ", "conditional-heavy", "raw", templcontrolled.RenderConditionalHeavy}, + {"controlled", "templ", "fragment-heavy", "raw", templcontrolled.RenderFragmentHeavy}, + {"controlled", "templ", "fortunes-encoded", "encoded", templcontrolled.RenderFortunesEncoded}, + {"controlled", "templ", "encoded-loop", "encoded", templcontrolled.RenderEncodedLoop}, + // stdlib idiomatic: the same surface split as controlled, authored per the + // official docs, gated by the shared idiomatic verifier. + {"idiomatic", "stdlib-text", "composed-page", "raw", stdlibidiomatic.RenderComposedPage}, + {"idiomatic", "stdlib-text", "trivial-substitution", "raw", stdlibidiomatic.RenderTrivialSubstitution}, + {"idiomatic", "stdlib-text", "large-loop", "raw", stdlibidiomatic.RenderLargeLoop}, + {"idiomatic", "stdlib-text", "mixed-page", "raw", stdlibidiomatic.RenderMixedPage}, + {"idiomatic", "stdlib-text", "conditional-heavy", "raw", stdlibidiomatic.RenderConditionalHeavy}, + {"idiomatic", "stdlib-text", "fragment-heavy", "raw", stdlibidiomatic.RenderFragmentHeavy}, + {"idiomatic", "stdlib-html", "fortunes-encoded", "encoded", stdlibidiomatic.RenderFortunesEncoded}, + {"idiomatic", "stdlib-html", "encoded-loop", "encoded", stdlibidiomatic.RenderEncodedLoop}, + // templ idiomatic: all eight workloads, naturally formatted with idiomatic + // component decomposition (internal/templeng/idiomatic). + {"idiomatic", "templ", "composed-page", "raw", templidiomatic.RenderComposedPage}, + {"idiomatic", "templ", "trivial-substitution", "raw", templidiomatic.RenderTrivialSubstitution}, + {"idiomatic", "templ", "large-loop", "raw", templidiomatic.RenderLargeLoop}, + {"idiomatic", "templ", "mixed-page", "raw", templidiomatic.RenderMixedPage}, + {"idiomatic", "templ", "conditional-heavy", "raw", templidiomatic.RenderConditionalHeavy}, + {"idiomatic", "templ", "fragment-heavy", "raw", templidiomatic.RenderFragmentHeavy}, + {"idiomatic", "templ", "fortunes-encoded", "encoded", templidiomatic.RenderFortunesEncoded}, + {"idiomatic", "templ", "encoded-loop", "encoded", templidiomatic.RenderEncodedLoop}, +} + +// checkCell dispatches one cell to its track's gate. +func checkCell(c cell) error { + switch c.Track { + case "controlled": + return corpus.CheckControlled(c.Workload, c.Suite, c.Engine, c.Render) + case "idiomatic": + def, err := corpus.LoadVerify(c.Workload) + if err != nil { + return err + } + if failures := corpus.Verify(def, c.Render()); len(failures) != 0 { + msg := fmt.Sprintf("verify: %s/%s", c.Workload, c.Engine) + for _, f := range failures { + msg += "\n " + f.String() + } + return fmt.Errorf("%s", msg) + } + return nil + default: + return fmt.Errorf("gate: %s/%s: unknown track %q", c.Workload, c.Engine, c.Track) + } +} + +// runAllGates runs corpus integrity, the alphabet assert, and every registered cell's gate. +func runAllGates() error { + if err := corpus.CheckManifest(); err != nil { + return err + } + for _, v := range model.EncodedValues() { + if err := corpus.CheckAlphabet(v.Name, v.Value); err != nil { + return err + } + } + for _, c := range cells { + if err := checkCell(c); err != nil { + return err + } + } + return nil +} + +// TestMain gates before any benchmark can time, in the same invocation. Any failure prints the failure surface and exits 1 — no numbers. +func TestMain(m *testing.M) { + if err := runAllGates(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + os.Exit(m.Run()) +} + +// ---- the same gates as ordinary Test functions ----------------------------------------------- + +func TestCorpusIntegrity(t *testing.T) { + if err := corpus.CheckManifest(); err != nil { + t.Fatal(err) + } +} + +func TestEncodedModelAlphabet(t *testing.T) { + for _, v := range model.EncodedValues() { + if err := corpus.CheckAlphabet(v.Name, v.Value); err != nil { + t.Fatal(err) + } + } +} + +func TestControlledGates(t *testing.T) { + for _, c := range cells { + if c.Track != "controlled" { + continue + } + t.Run(c.Workload+"/"+c.Engine, func(t *testing.T) { + if err := checkCell(c); err != nil { + t.Fatal(err) + } + }) + } +} + +func TestIdiomaticGates(t *testing.T) { + for _, c := range cells { + if c.Track != "idiomatic" { + continue + } + t.Run(c.Workload+"/"+c.Engine, func(t *testing.T) { + if err := checkCell(c); err != nil { + t.Fatal(err) + } + }) + } +} diff --git a/benchmarks/js/.gitattributes b/benchmarks/js/.gitattributes new file mode 100644 index 00000000..fcadb2cf --- /dev/null +++ b/benchmarks/js/.gitattributes @@ -0,0 +1 @@ +* text eol=lf diff --git a/benchmarks/js/.gitignore b/benchmarks/js/.gitignore new file mode 100644 index 00000000..fd3807ca --- /dev/null +++ b/benchmarks/js/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +artifacts/ diff --git a/benchmarks/js/.npmrc b/benchmarks/js/.npmrc new file mode 100644 index 00000000..d9ca8860 --- /dev/null +++ b/benchmarks/js/.npmrc @@ -0,0 +1,2 @@ +engine-strict=true +save-exact=true diff --git a/benchmarks/js/README.md b/benchmarks/js/README.md new file mode 100644 index 00000000..51e6efdc --- /dev/null +++ b/benchmarks/js/README.md @@ -0,0 +1,31 @@ +# Heddle cross-stack benchmarks — JS/Node harness + +JS/Node harness of the cross-stack benchmark program. The normative contract documents are +[js-harness-and-run.md](../docs/js-harness-and-run.md) and +[js-templates-and-models.md](../docs/js-templates-and-models.md); +the parity contract and golden corpus they implement are +[parity-contract-v2.md](../docs/parity-contract-v2.md) +and [golden-corpus.md](../docs/golden-corpus.md), with the workload set defined in +[workloads.md](../docs/workloads.md). +The golden corpus is consumed read-only from `benchmarks/dotnet/GoldenCorpus/`. + +## Pins + +- Node **24.x** (major pin; `engines` + `engine-strict=true` — any non-24 Node is refused, and the run records the exact version it used) +- handlebars **4.7.9**, eta **4.6.0**, mitata **1.0.34** (exact pins, committed lockfile) +- The only sanctioned install command is `npm ci`. + +## Reproduce + +``` +cd benchmarks/js +npm ci +npm run gate # both gates, all 32 cells +./run.ps1 bench/controlled.mjs # published runs go through the launcher (High priority) +./run.ps1 bench/idiomatic.mjs +./run.ps1 bench/cold-compile.mjs +./run.ps1 bench/controlled.mjs -Repeat 5 # Windows repeat-run stability verification +``` + +Development checks: `npm run selftest` (normalization fixtures + verifier calibration re-run), +`node test/gate-selftest.mjs` directly. diff --git a/benchmarks/js/bench/_shared.mjs b/benchmarks/js/bench/_shared.mjs new file mode 100644 index 00000000..3c605cfd --- /dev/null +++ b/benchmarks/js/bench/_shared.mjs @@ -0,0 +1,310 @@ +// Shared bench-script machinery. Provides: the in-process gates (run BEFORE any bench() +// registration — a failure exits 1 before run(), so no numbers exist for a failed gate), +// the group/bench registration helper (one group per workload, bodies +// `() => do_not_optimize(flatten(render()))` so no engine can defer or skip work), +// the single-run() capture (a `print` tap feeds +// the same lines that reach stdout into an in-process buffer), the artifact writer (one +// process, one sample set, two views: `.txt` from the capture buffer + `.json` +// from run()'s returned benchmarks, BigInt-safe), the DEOPT-CHECK trailer (scans the +// in-process capture buffer — never the externally redirected .txt — for mitata's `!` +// "likely optimized out" marker), and its companion MATERIALISATION-CHECK (implied output +// throughput against a physical ceiling; fatal, unlike DEOPT-CHECK). +import { mkdirSync, writeFileSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import path from "node:path"; +import { bench, group, run, do_not_optimize } from "mitata"; + +import { WORKLOADS, loadVerifyDefinition, loadCorpusEntry } from "../src/gate/corpus.mjs"; +import { assertControlledCell } from "../src/gate/controlled.mjs"; +import { verify } from "../src/gate/verifier.mjs"; + +/** The two engines of this phase, in disclosure order (Handlebars = credibility pick). */ +export const ENGINES = Object.freeze(["handlebars", "eta"]); + +/** The eight workload ids in workload order. */ +export const WORKLOAD_IDS = Object.freeze(WORKLOADS.map((w) => w.id)); + +// benchmarks/js/bench/_shared.mjs -> artifacts live at benchmarks/js/artifacts/ (gitignored). +const artifactsDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "artifacts"); + +// ---- the materialisation primitive: flatten the rendered value so no engine can defer work --- + +// Both engines build their output with `+=`, so `render()` hands back an unflattened V8 +// ConsString rope. mitata's `do_not_optimize(v)` is `{ $._ = v; }` in full: it makes the value +// escape so V8 cannot prove it unread, and never walks it. Timing that measures rope +// CONSTRUCTION, not output production — the 2026-07-22 run reported eta/composed-page at +// 330.7 ns for 34,847 B, i.e. ~105 GB/s, which is above this machine's store bandwidth. +// +// %FlattenString forces the rope into a flat sequential string, which is the work every other +// ecosystem's harness already does. Note `s.length` would NOT work: V8 stores the length on the +// ConsString, so reading it is O(1) and never flattens. +// +// Natives syntax is parse-time, and `npm run gate` / `npm run selftest` do not pass +// --allow-natives-syntax. Building the primitive through `new Function` keeps its absence a +// catchable runtime error instead of an unconditional module-load SyntaxError for every module +// that imports this one. +let nativeFlatten = true; + +/** + * Forces V8 to materialise `s`. The sanctioned measurement path is `%FlattenString`; the + * fallback exists only so the flag-less gate entry points can import this module, and a + * measurement run that lands on it is failed by `materialisationCheckTrailer`. + */ +export const flatten = (() => { + try { + // eslint-disable-next-line no-new-func + const native = new Function("s", "return %FlattenString(s);"); + native("ab" + String(Date.now() % 7)); // prove it runs, not just parses + return native; + } catch { + nativeFlatten = false; + return (s) => { + // charCodeAt on a ConsString forces a flatten; do_not_optimize keeps the read live. + do_not_optimize(s.charCodeAt(s.length - 1)); + return s; + }; + } +})(); + +/** Whether `flatten` is the natives-backed primitive. False means this is not a valid run. */ +export const nativeFlattenAvailable = () => nativeFlatten; + +// The physical ceiling for output bytes per nanosecond on the protocol machine. A cell above +// this claims more sustained single-core store bandwidth than the box has while also running +// template logic, so the harness cannot be materialising its output. Kept numerically in step +// with benchmarks/report/consolidate.py's PLAUSIBILITY_CEILING_B_PER_NS. +const PLAUSIBILITY_CEILING_B_PER_NS = 50.0; + +function failGate(messages) { + for (const message of Array.isArray(messages) ? messages : [messages]) console.error(message); + console.error( + "gate failed — exiting before any benchmark registration; no numbers exist for a failed gate.", + ); + process.exit(1); +} + +/** + * Controlled byte gate + encoded security floor over all 16 engine×workload cells. + * `renderers` is a per-track table: `renderers[engine][workloadId] -> () => string`. + * Exits 1 with the contract's failure surface before any bench() registration on any miss. + */ +export function assertControlledGate(renderers, label = "controlled") { + let cells = 0; + for (const engine of ENGINES) { + for (const id of WORKLOAD_IDS) { + const render = renderers?.[engine]?.[id]; + if (typeof render !== "function") { + failGate(`[FAIL] ${engine} ${id} [${label}]: no renderer registered`); + } + try { + assertControlledCell({ engine, workload: id, render }); + cells++; + } catch (error) { + failGate(error.message); + } + } + } + console.log(`gate: ${label} — ${cells}/${ENGINES.length * WORKLOAD_IDS.length} cells green (byte gate + security floor).`); +} + +/** + * Idiomatic functional-equivalence verifier over all 16 cells, fed from the corpus + * `.verify.json` definitions. Exits 1 before any bench() registration on any miss. + */ +export function assertIdiomaticGate(renderers) { + let cells = 0; + for (const engine of ENGINES) { + for (const id of WORKLOAD_IDS) { + const render = renderers?.[engine]?.[id]; + if (typeof render !== "function") { + failGate(`[FAIL] ${engine} ${id} [idiomatic]: no renderer registered`); + } + const failures = verify(loadVerifyDefinition(id), render(), `${engine} ${id}`); + if (failures.length > 0) failGate(failures.map((f) => f.message)); + cells++; + } + } + console.log(`gate: idiomatic — ${cells}/${ENGINES.length * WORKLOAD_IDS.length} cells green (verifier).`); +} + +// ---- registration ---------------------------------------------------------------------------- + +// Every bench name registered through this module, for the DEOPT-CHECK name resolution. +const registeredNames = new Set(); + +/** `bench()` wrapper that records the display name for the DEOPT-CHECK trailer. */ +export function namedBench(name, fn) { + registeredNames.add(name); + return bench(name, fn); +} + +/** + * Registration shape for the two track scripts: one `group(' []')` + * per workload containing the `handlebars` and `eta` benches, every body + * `() => do_not_optimize(flatten(render()))` — `flatten` materialises the rope and + * mitata's documented DCE guard then consumes the flat string. + */ +export function registerTrackGroups(track, renderers) { + for (const id of WORKLOAD_IDS) { + group(`${id} [${track}]`, () => { + for (const engine of ENGINES) { + const render = renderers[engine][id]; + namedBench(engine, () => do_not_optimize(flatten(render()))); + } + }); + } +} + +// ---- single run() + capture ------------------------------------------------------------------ + +// In-process capture buffer: the print tap hands run() a sink that both echoes to stdout and +// collects the identical lines here, so the DEOPT-CHECK trailer never depends on the +// externally redirected .txt being flushed. +const captured = []; + +/** + * The SINGLE `run()` of a bench script: default 'mitata' format to stdout, with every line + * also collected in the in-process buffer. One process, one sample set — the text and JSON + * artifacts are two views of the same run, never two runs. + */ +export async function runAndCapture() { + return await run({ + print: (s) => { + captured.push(s); + console.log(s); + }, + }); +} + +const bigintReplacer = (_key, value) => (typeof value === "bigint" ? value.toString() : value); + +/** + * Writes both artifacts from the single run: `artifacts/.txt` (the captured + * default-format output) and `artifacts/.json` (`result.benchmarks`, BigInt→string). + * When run.ps1 drives the process its stdout redirect owns `.txt`; the in-process + * rewrite of the identical lines is then skipped with a note (same stream either way). + */ +export function writeArtifacts(name, result) { + mkdirSync(artifactsDir, { recursive: true }); + writeFileSync( + path.join(artifactsDir, `${name}.json`), + JSON.stringify(result.benchmarks, bigintReplacer, 2), + "utf8", + ); + try { + writeFileSync(path.join(artifactsDir, `${name}.txt`), captured.join("\n") + "\n", "utf8"); + } catch (error) { + if (error?.code !== "EBUSY" && error?.code !== "EPERM" && error?.code !== "EACCES") throw error; + console.log( + `artifacts: ${name}.txt is held by the launcher's stdout redirect (run.ps1) — it captures the same lines.`, + ); + } + console.log(`artifacts: ${name}.txt + ${name}.json written under benchmarks/js/artifacts/ (single run, two views).`); +} + +// ---- DEOPT-CHECK trailer --------------------------------------------------------------------- + +// eslint-disable-next-line no-control-regex +const ANSI = /\x1b\[[0-9;]*m/g; + +/** + * Scans the in-process capture buffer (never the redirected .txt, which may be unflushed at + * trailer time) for mitata's `!` marker ("benchmark was likely optimized out"), and prints the + * publication-checklist trailer: `DEOPT-CHECK: clean` or `DEOPT-CHECK: flagged `. + * Advisory (exit 0); publication-blocking via the checklist. Returns the flagged list. + */ +export function deoptCheckTrailer() { + const flagged = []; + let currentGroup = null; + for (const line of captured) { + const plain = line.replace(ANSI, ""); + const groupHeader = plain.match(/^• (.*)$/); + if (groupHeader) { + currentGroup = groupHeader[1]; + continue; + } + // A flagged bench line ends in " !"; the legend line ends in "= !" and is not a bench. + if (!plain.endsWith(" !") || plain.endsWith("= !")) continue; + const name = [...registeredNames] + .filter((n) => plain.startsWith(n)) + .sort((a, b) => b.length - a.length)[0]; + if (name) flagged.push(currentGroup ? `${name} (${currentGroup})` : name); + } + console.log(flagged.length === 0 ? "DEOPT-CHECK: clean" : `DEOPT-CHECK: flagged ${flagged.join(", ")}`); + return flagged; +} + +// ---- MATERIALISATION-CHECK trailer ------------------------------------------------------------ + +/** + * Divides each cell's golden output size by its reported `avg` and fails the run if any cell + * claims more throughput than the machine can physically deliver — the signature of a harness + * that is not materialising its output. + * + * This is the companion DEOPT-CHECK cannot be: mitata's `!` marker fires only when + * `avg < 1.42 * noop.avg` against an EMPTY FUNCTION, so a cell can skip nearly all of its work + * and still sit three orders of magnitude above the trigger. The 2026-07-22 run reported + * `DEOPT-CHECK: clean` while measuring rope construction. + * + * Unlike DEOPT-CHECK, a violation here is fatal rather than explainable: it means the harness is + * not doing the work it reports. Exits 1 on a violation, and on a non-natives `flatten`, since a + * silent fallback would reintroduce the defect invisibly. + * + * `result.benchmarks` carries no workload name — `alias` is the engine only — so cells are + * matched positionally, exactly as registerTrackGroups() emitted them (WORKLOAD_IDS order, + * ENGINES within each group). The shape is asserted before it is trusted. + */ +export function materialisationCheckTrailer(result) { + if (!nativeFlatten) { + console.error( + "MATERIALISATION-CHECK: FAILED — %FlattenString is unavailable, so the benchmark bodies " + + "fell back to a non-sanctioned materialisation path. Run through run.ps1/run.sh or " + + "npm run bench:* so node receives --allow-natives-syntax.", + ); + process.exit(1); + } + + const benchmarks = result?.benchmarks ?? []; + const expected = ENGINES.length * WORKLOAD_IDS.length; + if (benchmarks.length !== expected) { + console.error( + `MATERIALISATION-CHECK: FAILED — expected ${expected} cells in run() output, found ` + + `${benchmarks.length}; the positional workload mapping cannot be trusted.`, + ); + process.exit(1); + } + + const flagged = []; + for (let i = 0; i < benchmarks.length; i++) { + const entry = benchmarks[i]; + const engine = ENGINES[i % ENGINES.length]; + if (entry.alias !== engine) { + console.error( + `MATERIALISATION-CHECK: FAILED — cell ${i} is '${entry.alias}', expected '${engine}'; ` + + "the positional workload mapping cannot be trusted.", + ); + process.exit(1); + } + const id = WORKLOAD_IDS[Math.floor(i / ENGINES.length)]; + const avg = Number(entry.runs?.[0]?.stats?.avg); + if (!Number.isFinite(avg) || avg <= 0) { + console.error(`MATERIALISATION-CHECK: FAILED — cell ${engine}/${id} has no usable avg.`); + process.exit(1); + } + const bytesPerNs = loadCorpusEntry(id).bytes.length / avg; + if (bytesPerNs > PLAUSIBILITY_CEILING_B_PER_NS) { + flagged.push(`${engine}/${id} (${bytesPerNs.toFixed(1)} B/ns)`); + } + } + + if (flagged.length > 0) { + console.error(`MATERIALISATION-CHECK: flagged ${flagged.join(", ")}`); + console.error( + `every flagged cell exceeds the ${PLAUSIBILITY_CEILING_B_PER_NS} B/ns ceiling, so its ` + + "output cannot be being produced — the numbers from this run are not publishable.", + ); + process.exit(1); + } + console.log("MATERIALISATION-CHECK: clean"); + return flagged; +} diff --git a/benchmarks/js/bench/aggregate.mjs b/benchmarks/js/bench/aggregate.mjs new file mode 100644 index 00000000..2bc2f529 --- /dev/null +++ b/benchmarks/js/bench/aggregate.mjs @@ -0,0 +1,231 @@ +// aggregate.mjs -- collapse N repeat passes of a bench script into the ecosystem's published +// artifact, and emit the cross-pass stability verdict from the same data. +// +// Why this exists. mitata exposes no per-cell time budget: `B.run()` builds its own +// options object internally and `run()` forwards only `throw`, so `min_cpu_time` (642 ms) cannot +// be raised through the public API. At that budget the JS leg measured 32 cells in 31 s -- about +// 1 s/cell, against 15-31 s/cell everywhere else. JS therefore spends its share of the uniform +// per-ecosystem budget on *many independent processes* rather than one long run, which is the +// same term JMH buys with forks and pyperf with its 20 workers, and is precisely the term a +// single-process harness lacks. +// +// The published `avg` becomes the MEDIAN of the per-pass `avg` values and the published +// dispersion becomes the min...max spread ACROSS passes, so the reported interval is +// cross-process variation rather than within-process sampling noise. The shape of the emitted +// JSON is byte-compatible with what `writeArtifacts` produces for a single run -- 16 entries, +// engine-paired groups in protocol order -- because benchmarks/report/consolidate.py asserts +// that shape (`load_js`). +// +// Stability verdict, per cell, on the cross-pass RSD of `avg`: <= 5% verified; 5-10% +// verified-with-disclosure (the report must carry the per-cell RSD table); > 10% failed, which +// exits 1 so no publication can be assembled from the run. + +import { mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const artifactsDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "artifacts"); +// Per-script, so two tracks cannot be medianed together; run.sh clears it before a sequence. +const stabilityDir = (name) => path.join(artifactsDir, "stability", name); + +/** Verdict thresholds, per cell, on cross-pass RSD of the mitata `avg`. */ +const RSD_VERIFIED = 5.0; +const RSD_DISCLOSE = 10.0; + +/** Five runs is the protocol floor; the time budget usually funds more. Fewer is not a verdict. */ +const MIN_PASSES = 5; + +const die = (message) => { + console.error(`aggregate: ${message}`); + process.exit(1); +}; + +const median = (xs) => { + const s = [...xs].sort((a, b) => a - b); + const m = s.length >> 1; + return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2; +}; + +const rsdPercent = (xs) => { + if (xs.length < 2) return 0; + const mean = xs.reduce((a, b) => a + b, 0) / xs.length; + if (mean === 0) return 0; + const variance = xs.reduce((a, b) => a + (b - mean) ** 2, 0) / (xs.length - 1); + return (Math.sqrt(variance) / mean) * 100; +}; + +const name = process.argv[2]; +if (!name) die("usage: node bench/aggregate.mjs "); + +// ---- load the passes ------------------------------------------------------------------------- + +const passDir = stabilityDir(name); +let dirEntries; +try { + dirEntries = readdirSync(passDir, { withFileTypes: true }); +} catch { + die(`no pass directory at artifacts/stability/${name}/ — run ./run.sh bench/${name}.mjs --repeat first`); +} +const files = dirEntries + .filter((d) => d.isFile()) + .map((d) => d.name) + .filter((f) => /^run-\d+\.json$/.test(f)) + .sort((a, b) => Number(a.match(/\d+/)[0]) - Number(b.match(/\d+/)[0])); + +if (files.length < MIN_PASSES) { + die( + `found ${files.length} pass artifact(s) under artifacts/stability/${name}/, need at least ${MIN_PASSES} ` + + `for a stability verdict. Run ./run.sh bench/${name}.mjs --repeat first.`, + ); +} + +const passes = files.map((f) => { + const full = path.join(passDir, f); + let data; + try { + data = JSON.parse(readFileSync(full, "utf8")); + } catch (error) { + die(`${f} is not readable JSON: ${error.message}`); + } + if (!Array.isArray(data) || data.length === 0) die(`${f} holds no benchmark entries`); + return { file: f, data }; +}); + +// Every pass must describe the same cells in the same order, or a positional median is nonsense. +const shapeOf = (data) => data.map((e) => `${e.alias}#${e.group}`).join("|"); +const reference = shapeOf(passes[0].data); +for (const p of passes.slice(1)) { + if (shapeOf(p.data) !== reference) { + die(`${p.file} does not describe the same cells in the same order as ${passes[0].file}`); + } +} + +// ---- aggregate ------------------------------------------------------------------------------- + +const cellCount = passes[0].data.length; +const rows = []; + +const aggregate = passes[0].data.map((entry, i) => { + const avgs = passes.map((p) => Number(p.data[i].runs[0].stats.avg)); + if (avgs.some((v) => !Number.isFinite(v) || v <= 0)) { + die(`cell ${entry.alias}[${i}] has a non-finite or non-positive avg in at least one pass`); + } + const med = median(avgs); + const rsd = rsdPercent(avgs); + rows.push({ index: i, alias: entry.alias, avgs, med, rsd }); + + // Heap is averaged rather than medianed: it is a byte count with no cross-pass spread to + // report, and consolidate.py reads only `heap.avg`. + const heaps = passes + .map((p) => p.data[i].runs[0].stats.heap?.avg) + .filter((v) => typeof v === "number" && Number.isFinite(v)); + + const stats = { + ...passes[0].data[i].runs[0].stats, + avg: med, + min: Math.min(...avgs), + max: Math.max(...avgs), + p50: med, + // Provenance, so an aggregate artifact is never mistaken for a single run. + aggregate: { + passes: passes.length, + source: files, + statistic: "median of per-pass avg", + dispersion: "min...max of per-pass avg (cross-process)", + perPassAvg: avgs, + rsdPercent: rsd, + }, + }; + if (heaps.length) stats.heap = { ...stats.heap, avg: heaps.reduce((a, b) => a + b, 0) / heaps.length }; + + return { + ...entry, + runs: [{ ...entry.runs[0], stats }], + }; +}); + +// ---- verdict --------------------------------------------------------------------------------- + +const worst = rows.reduce((a, b) => (b.rsd > a.rsd ? b : a)); +const failing = rows.filter((r) => r.rsd > RSD_DISCLOSE); +const disclosing = rows.filter((r) => r.rsd > RSD_VERIFIED && r.rsd <= RSD_DISCLOSE); +const verdict = failing.length ? "failed" : disclosing.length ? "verified-with-disclosure" : "verified"; + +// ---- write ----------------------------------------------------------------------------------- + +mkdirSync(artifactsDir, { recursive: true }); +writeFileSync(path.join(artifactsDir, `${name}.json`), JSON.stringify(aggregate, null, 2), "utf8"); + +const fixed = (v, n = 2) => v.toFixed(n); +const summary = [ + `# JS stability summary — \`${name}\``, + "", + `Stability verdict computed from **${passes.length} consecutive passes** of`, + `\`bench/${name}.mjs\`, each a separate node process. Thresholds are per cell on the`, + "cross-pass RSD of mitata's `avg`: ≤ 5% verified; 5–10% publishable but the report must carry", + "this table; > 10% blocks publication.", + "", + `STABILITY: ${verdict}`, + "", + `- passes: ${passes.length} (${files[0]} … ${files[files.length - 1]})`, + `- cells: ${cellCount}`, + `- cross-pass RSD: median ${fixed(median(rows.map((r) => r.rsd)))}% · max ${fixed(worst.rsd)}% (${worst.alias}, cell ${worst.index})`, + `- cells above 5%: ${disclosing.length} · above 10%: ${failing.length}`, + "", + "| # | Engine | Published (median of passes) | Cross-pass min … max | RSD |", + "| ---: | --- | ---: | --- | ---: |", + ...rows.map( + (r) => + `| ${r.index} | ${r.alias} | ${fixed(r.med, 1)} ns | ${fixed(Math.min(...r.avgs), 1)} … ${fixed(Math.max(...r.avgs), 1)} ns | ${fixed(r.rsd)}% |`, + ), + "", + "The published artifact `" + name + ".json` carries this aggregate: `stats.avg` is the median", + "of the per-pass averages and `stats.min`/`stats.max` span the passes, so its dispersion is", + "cross-process variation. Per-cell provenance is under `stats.aggregate`.", + "", +].join("\n"); +writeFileSync(path.join(artifactsDir, `stability-summary-${name}.md`), summary, "utf8"); + +// The human-readable capture and the machine-readable numbers must describe the SAME +// data, so the published tables and artifacts cannot disagree. Each pass still writes both views +// of itself (under stability//run-.txt|.json), but `writeArtifacts` also leaves +// artifacts/.txt holding the LAST pass while the JSON beside it is now the aggregate. +// Overwrite it so the pair matches again, and point at the per-pass captures. +writeFileSync( + path.join(artifactsDir, `${name}.txt`), + [ + `# ${name} — aggregate of ${passes.length} passes`, + "#", + "# This is NOT a single mitata run. The published statistic is the median of the per-pass", + "# `avg` values and the dispersion is their min…max spread, so the interval below is", + "# cross-process variation. Each pass's own mitata-format capture and JSON — the two views", + `# every run must publish — are under stability/${name}/run-.txt|.json.`, + "#", + `# STABILITY: ${verdict} (cross-pass RSD median ${fixed(median(rows.map((r) => r.rsd)))}%, max ${fixed(worst.rsd)}%)`, + `# Full verdict table: stability-summary-${name}.md`, + "", + ...rows.map( + (r) => + `${String(r.index).padStart(2)} ${r.alias.padEnd(12)} ${fixed(r.med, 1).padStart(14)} ns` + + ` ${fixed(Math.min(...r.avgs), 1)} … ${fixed(Math.max(...r.avgs), 1)} ns RSD ${fixed(r.rsd)}%`, + ), + "", + ].join("\n"), + "utf8", +); + +console.log( + `aggregate: ${passes.length} passes → artifacts/${name}.json ` + + `(median of per-pass avg; dispersion = cross-pass min…max)`, +); +console.log( + `aggregate: cross-pass RSD median ${fixed(median(rows.map((r) => r.rsd)))}% · ` + + `max ${fixed(worst.rsd)}% (${worst.alias}, cell ${worst.index})`, +); +console.log(`STABILITY: ${verdict}`); +if (failing.length) { + for (const r of failing) { + console.error(`aggregate: cell ${r.index} (${r.alias}) RSD ${fixed(r.rsd)}% exceeds ${RSD_DISCLOSE}%`); + } + die(`stability verdict is 'failed' — ${failing.length} cell(s) above ${RSD_DISCLOSE}% cross-pass RSD`); +} diff --git a/benchmarks/js/bench/cold-compile.mjs b/benchmarks/js/bench/cold-compile.mjs new file mode 100644 index 00000000..ef94b139 --- /dev/null +++ b/benchmarks/js/bench/cold-compile.mjs @@ -0,0 +1,157 @@ +// Cold-compile bench script. Invocation (canonical flags): +// node --expose-gc --allow-natives-syntax bench/cold-compile.mjs (npm run bench:cold) +// +// Measures cold compile + first render per controlled template, per engine: +// - Handlebars: fresh `Handlebars.create()` environment (+ partial registration where the +// workload has partials) + `compile(src)` + one render PER ITERATION — the render forces +// Handlebars' lazy compile, so pure-compile() timing would be a lie; +// - Eta: fresh `new Eta()` (+ `loadTemplate` of the workload's partials, the registration +// analogue) + `renderString(src, model)` per iteration — methodologically identical cells. +// Template sources are read from src/templates/*/controlled/ ONCE at startup; file I/O is +// never inside a timed body. The resulting figures are comparable within this ecosystem only, +// never across ecosystems. +// +// Support templates (partials + layout shells) are DISCOVERED from each engine's controlled +// track's `shared/` subdirectory (`src/templates//controlled/shared/` — only the eight +// entry templates sit at a track's top level; legacy top-level scan kept as fallback while a +// track has no `shared/`) by the shared file convention `.partial.` / `.layout.` +// (registered as `` for Handlebars, `@` for Eta — the names the engine modules +// register). The fragment-heavy partial set ({tile, card, badge, price, media_row, stat}) +// belongs to the fragment-heavy cell; every other support template belongs to composed-page +// (the native-layout shell, nav partials and literal chrome fragments). No helpers are +// registered anywhere in the suite: composed-page is pure template composition on every engine. +// +// Shape: in-process controlled byte gate (reuses the controlled render tables) over all 16 +// cells BEFORE any bench() registration (failure exits 1 before run()) → the 16 cold +// benches under group `cold-compile [per-ecosystem]`, +// bench names ` `, bodies +// `() => do_not_optimize(flatten(coldRender()))` (the compile is only half the cell; without +// flatten the first render's rope is never materialised) → a +// SINGLE run() → artifacts/cold-compile.txt + artifacts/cold-compile.json (two views of the +// same samples) → DEOPT-CHECK trailer over the in-process capture buffer. +// +// No MATERIALISATION-CHECK here: these cells time compile + first render together, so their +// implied output throughput is dominated by compilation and the physical ceiling says nothing +// about them. The two track scripts carry that check. +import { readFileSync, readdirSync, existsSync } from "node:fs"; +import { fileURLToPath } from "node:url"; +import path from "node:path"; +import Handlebars from "handlebars"; +import { Eta } from "eta"; +import { group, do_not_optimize } from "mitata"; + +import { tracks } from "../src/engines/index.mjs"; +import { + WORKLOAD_IDS, + assertControlledGate, + namedBench, + runAndCapture, + writeArtifacts, + deoptCheckTrailer, + flatten, +} from "./_shared.mjs"; + +import { model as composedPage } from "../src/models/composed-page.mjs"; +import { model as trivialSubstitution } from "../src/models/trivial-substitution.mjs"; +import { model as largeLoop } from "../src/models/large-loop.mjs"; +import { model as mixedPage } from "../src/models/mixed-page.mjs"; +import { model as conditionalHeavy } from "../src/models/conditional-heavy.mjs"; +import { model as fragmentHeavy } from "../src/models/fragment-heavy.mjs"; +import { model as fortunesEncoded } from "../src/models/fortunes-encoded.mjs"; +import { model as encodedLoop } from "../src/models/encoded-loop.mjs"; + +const MODELS = Object.freeze({ + "composed-page": composedPage, + "trivial-substitution": trivialSubstitution, + "large-loop": largeLoop, + "mixed-page": mixedPage, + "conditional-heavy": conditionalHeavy, + "fragment-heavy": fragmentHeavy, + "fortunes-encoded": fortunesEncoded, + "encoded-loop": encodedLoop, +}); + +// ---- template sources, read once at startup (outside every timed region) --------------------- + +const templatesDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "src", "templates"); +const readControlled = (engine, file) => readFileSync(path.join(templatesDir, engine, "controlled", file), "utf8"); + +const hbsSources = Object.fromEntries(WORKLOAD_IDS.map((id) => [id, readControlled("handlebars", `${id}.hbs`)])); +const etaSources = Object.fromEntries(WORKLOAD_IDS.map((id) => [id, readControlled("eta", `${id}.eta`)])); + +// The fragment-heavy partial family; every other support template is composed-page's. Both +// dash and underscore spellings of media_row are accepted so either engine's file naming +// resolves. +const FRAGMENT_PARTIAL_NAMES = new Set(["tile", "card", "badge", "price", "media_row", "media-row", "stat"]); +const SUPPORT_FILE = /^(.+)\.(?:partial|layout)\.(?:hbs|eta)$/; + +/** + * [{ name, src }] support templates of one engine's controlled track, by the file convention. + * Canonical location is the track's `shared/` subdirectory; when an engine's track has no + * `shared/` yet, the legacy top-level scan of the track directory applies (fallback, never + * both — `shared/` wins outright when present). + */ +function supportTemplates(engine) { + const trackDir = path.join(templatesDir, engine, "controlled"); + const sharedDir = path.join(trackDir, "shared"); + const scanDir = existsSync(sharedDir) ? sharedDir : trackDir; + const support = []; + for (const file of readdirSync(scanDir).sort()) { + const match = SUPPORT_FILE.exec(file); + if (match) support.push({ name: match[1], src: readFileSync(path.join(scanDir, file), "utf8") }); + } + return support; +} + +/** The support templates one workload's cold cell must register (empty for most workloads). */ +function supportFor(support, id) { + if (id === "fragment-heavy") return support.filter((s) => FRAGMENT_PARTIAL_NAMES.has(s.name)); + if (id === "composed-page") return support.filter((s) => !FRAGMENT_PARTIAL_NAMES.has(s.name)); + return []; +} + +const hbsSupport = supportTemplates("handlebars"); +const etaSupport = supportTemplates("eta"); + +/** Handlebars cold closure: fresh environment + registration + compile + one render. */ +function handlebarsCold(id) { + const src = hbsSources[id]; + const model = MODELS[id]; + const partials = supportFor(hbsSupport, id); + return () => { + const env = Handlebars.create(); + for (const { name, src: partialSrc } of partials) env.registerPartial(name, partialSrc); + return env.compile(src)(model); + }; +} + +/** Eta cold closure: fresh instance + partial loadTemplate + renderString. */ +function etaCold(id) { + const src = etaSources[id]; + const model = MODELS[id]; + const partials = supportFor(etaSupport, id); + return () => { + const eta = new Eta(); + for (const { name, src: partialSrc } of partials) eta.loadTemplate(`@${name}`, partialSrc); + return eta.renderString(src, model); + }; +} + +// ---- gate: reuses the controlled render tables; exits 1 before any registration -------------- + +assertControlledGate(tracks.controlled); + +// ---- the 16 cold benches, single group -------------------------------------------------------- + +group("cold-compile [per-ecosystem]", () => { + for (const id of WORKLOAD_IDS) { + const hb = handlebarsCold(id); + const et = etaCold(id); + namedBench(`handlebars ${id}`, () => do_not_optimize(flatten(hb()))); + namedBench(`eta ${id}`, () => do_not_optimize(flatten(et()))); + } +}); + +const result = await runAndCapture(); // default 'mitata' format → stdout + in-process buffer +writeArtifacts("cold-compile", result); // JSON: result.benchmarks, BigInt→string replacer +deoptCheckTrailer(); // scans the in-process capture buffer for '!' → DEOPT-CHECK line diff --git a/benchmarks/js/bench/controlled.mjs b/benchmarks/js/bench/controlled.mjs new file mode 100644 index 00000000..49bd93d3 --- /dev/null +++ b/benchmarks/js/bench/controlled.mjs @@ -0,0 +1,30 @@ +// Controlled-track bench script. Invocation (canonical flags): +// node --expose-gc --allow-natives-syntax bench/controlled.mjs (npm run bench:controlled) +// Shape: in-process controlled byte gate over all 16 cells BEFORE any bench() registration +// (failure exits 1 before run() — no numbers exist for a failed gate) → one group per +// workload with `handlebars`/`eta` benches, bodies +// `() => do_not_optimize(flatten(render()))` so every rendered rope is materialised → a +// SINGLE run() → artifacts/controlled.txt + artifacts/controlled.json (two views of the same +// samples) → DEOPT-CHECK trailer over the in-process capture buffer → its +// MATERIALISATION-CHECK companion, which exits 1 if any cell's implied output throughput is +// physically impossible. +import { tracks } from "../src/engines/index.mjs"; +import { + assertControlledGate, + registerTrackGroups, + runAndCapture, + writeArtifacts, + deoptCheckTrailer, + materialisationCheckTrailer, +} from "./_shared.mjs"; + +const renderers = tracks.controlled; // per-track render table: renderers.[id] -> () => string + +assertControlledGate(renderers); // throws/exits 1 → no numbers exist for a failed gate + +registerTrackGroups("controlled", renderers); + +const result = await runAndCapture(); // default 'mitata' format → stdout + in-process buffer +writeArtifacts("controlled", result); // JSON: result.benchmarks, BigInt→string replacer +deoptCheckTrailer(); // scans the in-process capture buffer for '!' → DEOPT-CHECK line +materialisationCheckTrailer(result); // implied throughput vs the physical ceiling; fatal diff --git a/benchmarks/js/bench/idiomatic.mjs b/benchmarks/js/bench/idiomatic.mjs new file mode 100644 index 00000000..9b4063e7 --- /dev/null +++ b/benchmarks/js/bench/idiomatic.mjs @@ -0,0 +1,30 @@ +// Idiomatic-track bench script. Invocation (canonical flags): +// node --expose-gc --allow-natives-syntax bench/idiomatic.mjs (npm run bench:idiomatic) +// Shape: in-process idiomatic verifier (corpus `.verify.json` definitions) over all 16 +// cells BEFORE any bench() registration (failure exits 1 before run()) → one group per +// workload with `handlebars`/`eta` benches, bodies +// `() => do_not_optimize(flatten(render()))` so every rendered rope is materialised → a +// SINGLE run() → artifacts/idiomatic.txt + artifacts/idiomatic.json (two views of the same +// samples) → DEOPT-CHECK trailer over the in-process capture buffer → its +// MATERIALISATION-CHECK companion, which exits 1 if any cell's implied output throughput is +// physically impossible. +import { tracks } from "../src/engines/index.mjs"; +import { + assertIdiomaticGate, + registerTrackGroups, + runAndCapture, + writeArtifacts, + deoptCheckTrailer, + materialisationCheckTrailer, +} from "./_shared.mjs"; + +const renderers = tracks.idiomatic; // per-track render table: renderers.[id] -> () => string + +assertIdiomaticGate(renderers); // exits 1 before any registration on any verifier miss + +registerTrackGroups("idiomatic", renderers); + +const result = await runAndCapture(); // default 'mitata' format → stdout + in-process buffer +writeArtifacts("idiomatic", result); // JSON: result.benchmarks, BigInt→string replacer +deoptCheckTrailer(); // scans the in-process capture buffer for '!' → DEOPT-CHECK line +materialisationCheckTrailer(result); // implied throughput vs the physical ceiling; fatal diff --git a/benchmarks/js/package-lock.json b/benchmarks/js/package-lock.json new file mode 100644 index 00000000..d9c01514 --- /dev/null +++ b/benchmarks/js/package-lock.json @@ -0,0 +1,100 @@ +{ + "name": "heddle-benchmarks-js", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "heddle-benchmarks-js", + "dependencies": { + "eta": "4.6.0", + "handlebars": "4.7.9", + "mitata": "1.0.34" + }, + "engines": { + "node": "24.x" + } + }, + "node_modules/eta": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-4.6.0.tgz", + "integrity": "sha512-lW6is4T1NFOYnmqGZIfvixqj7A7sSvScF+DN8EK6K58xI5MZ5UvYe0GjopxOXQtZvUn4eDdVuZ8XSoYWTMEKwA==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/bgub/eta?sponsor=1" + } + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mitata": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/mitata/-/mitata-1.0.34.tgz", + "integrity": "sha512-Mc3zrtNBKIMeHSCQ0XqRLo1vbdIx1wvFV9c8NJAiyho6AjNfMY8bVhbS12bwciUdd1t4rj8099CH3N3NFahaUA==", + "license": "MIT" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "license": "MIT" + } + } +} diff --git a/benchmarks/js/package.json b/benchmarks/js/package.json new file mode 100644 index 00000000..e8b8c075 --- /dev/null +++ b/benchmarks/js/package.json @@ -0,0 +1,18 @@ +{ + "name": "heddle-benchmarks-js", + "private": true, + "type": "module", + "engines": { "node": "24.x" }, + "dependencies": { + "eta": "4.6.0", + "handlebars": "4.7.9", + "mitata": "1.0.34" + }, + "scripts": { + "gate": "node src/gate/run-all.mjs", + "bench:controlled": "node --expose-gc --allow-natives-syntax bench/controlled.mjs", + "bench:idiomatic": "node --expose-gc --allow-natives-syntax bench/idiomatic.mjs", + "bench:cold": "node --expose-gc --allow-natives-syntax bench/cold-compile.mjs", + "selftest": "node test/gate-selftest.mjs" + } +} diff --git a/benchmarks/js/run.ps1 b/benchmarks/js/run.ps1 new file mode 100644 index 00000000..22917284 --- /dev/null +++ b/benchmarks/js/run.ps1 @@ -0,0 +1,112 @@ +<# +.SYNOPSIS + Protocol launcher for the JS benchmark harness. + +.DESCRIPTION + Starts `node --expose-gc --allow-natives-syntax ' }, + { id: 12, message: "フレームワークのベンチマーク" }, + ], +}); diff --git a/benchmarks/js/src/models/fragment-heavy.mjs b/benchmarks/js/src/models/fragment-heavy.mjs new file mode 100644 index 00000000..e9864442 --- /dev/null +++ b/benchmarks/js/src/models/fragment-heavy.mjs @@ -0,0 +1,29 @@ +// fragment-heavy model. 48 rows, i in [0, 47], four dispatched +// kinds (12 each); dispatch runs on the precomputed is_* booleans, never on the kind string +// (common-denominator dispatch). The model carries DATA only: promo.price is a NUMBER, +// and derived display text (media caption, image src, ".99" display price) is composed by the +// templates as literal-plus-substitution. +import { deepFreeze } from "./_deep-freeze.mjs"; + +const kinds = ["tile", "card", "media", "stat"]; +const badges = ["new", "hot", "sale", "std"]; + +const items = []; +for (let i = 0; i < 48; i++) { + const kind = kinds[i % 4]; + const badge = badges[i % 4]; + items.push({ + kind, + is_tile: kind === "tile", + is_card: kind === "card", + is_media: kind === "media", + is_stat: kind === "stat", + name: `item-${String(i).padStart(2, "0")}`, + value: i * 11, + badge, + delta: (i % 7) - 3, + promo: { label: badge, price: 9 + i }, + }); +} + +export const model = deepFreeze({ items }); diff --git a/benchmarks/js/src/models/large-loop.mjs b/benchmarks/js/src/models/large-loop.mjs new file mode 100644 index 00000000..fffca32b --- /dev/null +++ b/benchmarks/js/src/models/large-loop.mjs @@ -0,0 +1,11 @@ +// large-loop model: 5,000 rows, value i. Rows carry ONLY the value: the display +// name "row-{i}" is composed by the templates as the literal "row-" + the value substitution — +// pre-formatting it model-side would move rendering work out of the engine under test. +import { deepFreeze } from "./_deep-freeze.mjs"; + +const items = []; +for (let i = 0; i < 5000; i++) { + items.push({ value: i }); +} + +export const model = deepFreeze({ items }); diff --git a/benchmarks/js/src/models/mixed-page.mjs b/benchmarks/js/src/models/mixed-page.mjs new file mode 100644 index 00000000..c0e24690 --- /dev/null +++ b/benchmarks/js/src/models/mixed-page.mjs @@ -0,0 +1,31 @@ +// mixed-page model. Pinned scalars and product formulas transcribed from +// benchmarks/dotnet/src/Models/MixedContent.cs. 36 products, i in [1, 36]. sku_number and +// batch are NUMBERS: the display SKU ("MX-" + sku_number) and the blurb sentence around +// batch are composed by the templates as literal-plus-substitution. The zero-padded product +// name stays model-side by design (row identity, not display text). +import { deepFreeze } from "./_deep-freeze.mjs"; + +const products = []; +for (let i = 1; i <= 36; i++) { + products.push({ + name: `Product ${String(i).padStart(2, "0")}`, + sku_number: 1000 + i, + price: 950 + i * 7, + on_sale: i % 3 === 0, + batch: i, + }); +} + +export const model = deepFreeze({ + page_title: "Mercantile - Catalog", + store_name: "Mercantile", + hero_heading: "Autumn hardware sale", + hero_tagline: "Hand-picked tools, fair prices, shipped tomorrow.", + show_banner: true, + banner_text: "Free shipping on orders over 60.", + show_debug_panel: false, + footer_note: "Prices include VAT where applicable.", + year: 2026, + support_email: "support at mercantile.example", + products, +}); diff --git a/benchmarks/js/src/models/trivial-substitution.mjs b/benchmarks/js/src/models/trivial-substitution.mjs new file mode 100644 index 00000000..03d6e1cb --- /dev/null +++ b/benchmarks/js/src/models/trivial-substitution.mjs @@ -0,0 +1,18 @@ +// trivial-substitution model. +// Pinned scalar values transcribed from benchmarks/dotnet/src/Models/SubstitutionContent.cs +// (snake_case keys per the cross-stack dictionary-view convention; price is a .NET int -> JS +// number, rating is the pinned string "4.8"). +import { deepFreeze } from "./_deep-freeze.mjs"; + +export const model = deepFreeze({ + title: "Heddle Handbook", + sku: "HB-2001", + price: 4200, + brand: "Heddle Press", + category: "Reference", + availability: "In stock", + url: "/catalog/handbook", + image_url: "/img/handbook.png", + summary: "A concise field guide to the engine.", + rating: "4.8", +}); diff --git a/benchmarks/js/src/templates/eta/controlled/composed-page.eta b/benchmarks/js/src/templates/eta/controlled/composed-page.eta new file mode 100644 index 00000000..bbb38d8f --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/composed-page.eta @@ -0,0 +1 @@ +<% layout("@shell", it) %>
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/conditional-heavy.eta b/benchmarks/js/src/templates/eta/controlled/conditional-heavy.eta new file mode 100644 index 00000000..4d5b688a --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/conditional-heavy.eta @@ -0,0 +1 @@ +
        <% it.rows.forEach(r => { %>
      • <% if (r.is_bronze) { %>bronze<% } else if (r.is_silver) { %>silver<% } else if (r.is_gold) { %>gold<% } else { %>platinum<% } %><%~ r.name %><% if (r.has_note) { %>note <%~ r.seq %><% } %><% if (r.is_active) { %>active<% } %>
      • <% }) %>
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/encoded-loop.eta b/benchmarks/js/src/templates/eta/controlled/encoded-loop.eta new file mode 100644 index 00000000..71181633 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/encoded-loop.eta @@ -0,0 +1 @@ +<% it.items.forEach(r => { %><% }) %>
      <%= r.name %><%= r.comment %>
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/fortunes-encoded.eta b/benchmarks/js/src/templates/eta/controlled/fortunes-encoded.eta new file mode 100644 index 00000000..e1f99d0f --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/fortunes-encoded.eta @@ -0,0 +1 @@ +Fortunes<% it.rows.forEach(r => { %><% }) %>
      idmessage
      <%= r.id %><%= r.message %>
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/fragment-heavy.eta b/benchmarks/js/src/templates/eta/controlled/fragment-heavy.eta new file mode 100644 index 00000000..d153c925 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/fragment-heavy.eta @@ -0,0 +1 @@ +
      <% it.items.forEach(item => { %><% if (item.is_tile) { %><%~ include("@tile", item) %><% } else if (item.is_card) { %><%~ include("@card", item) %><% } else if (item.is_media) { %><%~ include("@media_row", item) %><% } else { %><%~ include("@stat", item) %><% } %><% }) %>
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/large-loop.eta b/benchmarks/js/src/templates/eta/controlled/large-loop.eta new file mode 100644 index 00000000..d982ac18 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/large-loop.eta @@ -0,0 +1 @@ +<% it.items.forEach(r => { %>row-<%~ r.value %><%~ r.value %><% }) %> \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/mixed-page.eta b/benchmarks/js/src/templates/eta/controlled/mixed-page.eta new file mode 100644 index 00000000..9ba23274 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/mixed-page.eta @@ -0,0 +1,29 @@ + + + + +<%~ it.page_title %> + + + +
      +

      <%~ it.store_name %>

      + +
      +
      +<% if (it.show_banner) { %><% } %> +
      +

      <%~ it.hero_heading %>

      +

      <%~ it.hero_tagline %>

      +
      +
      +<% it.products.forEach(p => { %>

      <%~ p.name %>

      MX-<%~ p.sku_number %>

      <%~ p.price %>

      <% if (p.on_sale) { %>

      On sale

      <% } %>

      A dependable workshop staple from batch <%~ p.batch %>, checked for daily use and backed by our lifetime guarantee.

      <% }) %> +
      +<% if (it.show_debug_panel) { %>
      debug
      <% } %> +
      +
      +

      <%~ it.footer_note %>

      +

      <%~ it.store_name %> <%~ it.year %> <%~ it.support_email %>

      +
      + + \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/alert_below.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/alert_below.partial.eta new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/alert_below.partial.eta @@ -0,0 +1 @@ + diff --git a/benchmarks/js/src/templates/eta/controlled/shared/alert_top.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/alert_top.partial.eta new file mode 100644 index 00000000..2abc9bf1 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/alert_top.partial.eta @@ -0,0 +1 @@ +
      holiday shipping
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/assets_scripts.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/assets_scripts.partial.eta new file mode 100644 index 00000000..e47cda12 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/assets_scripts.partial.eta @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/assets_styles.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/assets_styles.partial.eta new file mode 100644 index 00000000..cb6751d3 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/assets_styles.partial.eta @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/badge.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/badge.partial.eta new file mode 100644 index 00000000..988b7a7b --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/badge.partial.eta @@ -0,0 +1 @@ +<%~ it.label %> \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/body_end_scripts.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/body_end_scripts.partial.eta new file mode 100644 index 00000000..4a28491d --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/body_end_scripts.partial.eta @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/body_scripts.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/body_scripts.partial.eta new file mode 100644 index 00000000..cb28a558 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/body_scripts.partial.eta @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/card.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/card.partial.eta new file mode 100644 index 00000000..49b020b9 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/card.partial.eta @@ -0,0 +1 @@ +

      <%~ it.name %>

      <%~ include("@badge", it.promo) %><%~ include("@price", it.promo) %>

      <%~ it.value %>

      \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/custom_styles.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/custom_styles.partial.eta new file mode 100644 index 00000000..f635c77f --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/custom_styles.partial.eta @@ -0,0 +1 @@ +/* CSS Comment Test */ \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/head_scripts.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/head_scripts.partial.eta new file mode 100644 index 00000000..879142ca --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/head_scripts.partial.eta @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/media_row.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/media_row.partial.eta new file mode 100644 index 00000000..7b601919 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/media_row.partial.eta @@ -0,0 +1 @@ +
      <%~ it.name %>

      <%~ it.name %>

      Caption for <%~ it.name %>

      \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/mega_menu.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/mega_menu.partial.eta new file mode 100644 index 00000000..58da7c03 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/mega_menu.partial.eta @@ -0,0 +1 @@ +
        <% it.tabs.forEach(t => { %>
      • <%~ t.label %><% if (t.has_dropdown) { %>
        <% t.columns.forEach(c => { %><%~ include("@nav_column", c) %><% }) %>
        <% } %>
      • <% }) %>
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/nav_column.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/nav_column.partial.eta new file mode 100644 index 00000000..9d527664 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/nav_column.partial.eta @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/nav_link.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/nav_link.partial.eta new file mode 100644 index 00000000..fee5bb56 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/nav_link.partial.eta @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/nav_section.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/nav_section.partial.eta new file mode 100644 index 00000000..0c52cc26 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/nav_section.partial.eta @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/price.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/price.partial.eta new file mode 100644 index 00000000..08026427 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/price.partial.eta @@ -0,0 +1 @@ +

      <%~ it.price %>.99

      \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/controlled/shared/secondary_retail_menu.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/secondary_retail_menu.partial.eta new file mode 100644 index 00000000..6c6147b8 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/secondary_retail_menu.partial.eta @@ -0,0 +1,116 @@ + diff --git a/benchmarks/js/src/templates/eta/controlled/shared/secondary_wholesale_menu.partial.eta b/benchmarks/js/src/templates/eta/controlled/shared/secondary_wholesale_menu.partial.eta new file mode 100644 index 00000000..b80f8830 --- /dev/null +++ b/benchmarks/js/src/templates/eta/controlled/shared/secondary_wholesale_menu.partial.eta @@ -0,0 +1,138 @@ + diff --git a/src/Heddle.Performance/Views/layout.cshtml b/benchmarks/js/src/templates/eta/controlled/shared/shell.layout.eta similarity index 70% rename from src/Heddle.Performance/Views/layout.cshtml rename to benchmarks/js/src/templates/eta/controlled/shared/shell.layout.eta index 73b5c897..ca93160c 100644 --- a/src/Heddle.Performance/Views/layout.cshtml +++ b/benchmarks/js/src/templates/eta/controlled/shared/shell.layout.eta @@ -1,5 +1,3 @@ -@using Heddle.Performance.TestSuite -@using Heddle.Performance.TestSuite.Extensions + + + + + + + + Title + + + + + + + + + <%~ include("@assets_styles", it) %> + + <%~ include("@head_scripts", it) %> + + + <%~ include("@body_scripts", it) %> +
      +
      + +
      +
      +
      +
      + <%~ include("@alert_top", it) %> +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + <% it.nav.menus.forEach(m => { %><%~ include("@mega_menu", m) %><% }) %> +
      +
      +
      + <%~ include("@alert_below", it) %> +
      +
      + <%~ it.body %> +
      +
      +
      +
      +
      + +
      +
      + <%~ include("@assets_scripts", it) %> + + <%~ include("@body_end_scripts", it) %> + + \ No newline at end of file diff --git a/benchmarks/js/src/templates/eta/idiomatic/shared/stat.partial.eta b/benchmarks/js/src/templates/eta/idiomatic/shared/stat.partial.eta new file mode 100644 index 00000000..64cade98 --- /dev/null +++ b/benchmarks/js/src/templates/eta/idiomatic/shared/stat.partial.eta @@ -0,0 +1,9 @@ +<% /* idiomatic Eta implementation (Phase 4). + Patterns followed: https://eta.js.org/docs/4.x.x/syntax/cheatsheet, + https://eta.js.org/docs/4.x.x/syntax/layouts-and-blocks (layout, it.body), + https://eta.js.org/docs/4.x.x/api/overview (loadTemplate, render). */ %> +
      + <%= it.name %> + <%= it.value %> + <%= it.delta %> +
      diff --git a/benchmarks/js/src/templates/eta/idiomatic/shared/tile.partial.eta b/benchmarks/js/src/templates/eta/idiomatic/shared/tile.partial.eta new file mode 100644 index 00000000..365af32b --- /dev/null +++ b/benchmarks/js/src/templates/eta/idiomatic/shared/tile.partial.eta @@ -0,0 +1,9 @@ +<% /* idiomatic Eta implementation (Phase 4). + Patterns followed: https://eta.js.org/docs/4.x.x/syntax/cheatsheet, + https://eta.js.org/docs/4.x.x/syntax/layouts-and-blocks (layout, it.body), + https://eta.js.org/docs/4.x.x/api/overview (loadTemplate, render). */ %> +
      +

      <%= it.name %>

      +

      <%= it.value %>

      + <%= it.badge %> +
      diff --git a/benchmarks/js/src/templates/eta/idiomatic/trivial-substitution.eta b/benchmarks/js/src/templates/eta/idiomatic/trivial-substitution.eta new file mode 100644 index 00000000..b69c03c0 --- /dev/null +++ b/benchmarks/js/src/templates/eta/idiomatic/trivial-substitution.eta @@ -0,0 +1,15 @@ +<% /* idiomatic Eta implementation (Phase 4). + Patterns followed: https://eta.js.org/docs/4.x.x/syntax/cheatsheet, + https://eta.js.org/docs/4.x.x/syntax/layouts-and-blocks (layout, it.body), + https://eta.js.org/docs/4.x.x/api/overview (loadTemplate, render). */ %> +
      +

      <%= it.title %>

      +

      <%= it.sku %>

      +

      <%= it.price %>

      +

      <%= it.brand %>

      +

      <%= it.category %>

      +

      <%= it.availability %>

      + +

      <%= it.summary %>

      +

      <%= it.rating %>

      +
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/handlebars/controlled/composed-page.hbs b/benchmarks/js/src/templates/handlebars/controlled/composed-page.hbs new file mode 100644 index 00000000..93eb3999 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/composed-page.hbs @@ -0,0 +1,13 @@ +{{#> layout}} +
      +
      +
      +
      +
      + + + +
      +
      +
      +{{/layout}} diff --git a/benchmarks/js/src/templates/handlebars/controlled/conditional-heavy.hbs b/benchmarks/js/src/templates/handlebars/controlled/conditional-heavy.hbs new file mode 100644 index 00000000..8576a7c8 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/conditional-heavy.hbs @@ -0,0 +1 @@ +
        {{#each rows}}
      • {{#if is_bronze}}bronze{{else if is_silver}}silver{{else if is_gold}}gold{{else}}platinum{{/if}}{{{name}}}{{#if has_note}}note {{{seq}}}{{/if}}{{#if is_active}}active{{/if}}
      • {{/each}}
      diff --git a/benchmarks/js/src/templates/handlebars/controlled/encoded-loop.hbs b/benchmarks/js/src/templates/handlebars/controlled/encoded-loop.hbs new file mode 100644 index 00000000..5b8e5cfa --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/encoded-loop.hbs @@ -0,0 +1 @@ +{{#each items}}{{/each}}
      {{name}}{{comment}}
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/handlebars/controlled/fortunes-encoded.hbs b/benchmarks/js/src/templates/handlebars/controlled/fortunes-encoded.hbs new file mode 100644 index 00000000..42b60b2a --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/fortunes-encoded.hbs @@ -0,0 +1 @@ +Fortunes{{#each rows}}{{/each}}
      idmessage
      {{id}}{{message}}
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/handlebars/controlled/fragment-heavy.hbs b/benchmarks/js/src/templates/handlebars/controlled/fragment-heavy.hbs new file mode 100644 index 00000000..79976846 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/fragment-heavy.hbs @@ -0,0 +1 @@ +
      {{#each items}}{{#if is_tile}}{{> tile this}}{{else if is_card}}{{> card this}}{{else if is_media}}{{> media_row this}}{{else}}{{> stat this}}{{/if}}{{/each}}
      diff --git a/benchmarks/js/src/templates/handlebars/controlled/large-loop.hbs b/benchmarks/js/src/templates/handlebars/controlled/large-loop.hbs new file mode 100644 index 00000000..ec0f6b3c --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/large-loop.hbs @@ -0,0 +1 @@ +{{#each items}}row-{{{value}}}{{{value}}}{{/each}} diff --git a/benchmarks/js/src/templates/handlebars/controlled/mixed-page.hbs b/benchmarks/js/src/templates/handlebars/controlled/mixed-page.hbs new file mode 100644 index 00000000..cb7b6788 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/mixed-page.hbs @@ -0,0 +1,29 @@ + + + + +{{{page_title}}} + + + +
      +

      {{{store_name}}}

      + +
      +
      +{{#if show_banner}}{{/if}} +
      +

      {{{hero_heading}}}

      +

      {{{hero_tagline}}}

      +
      +
      +{{#each products}}

      {{{name}}}

      MX-{{{sku_number}}}

      {{{price}}}

      {{#if on_sale}}

      On sale

      {{/if}}

      A dependable workshop staple from batch {{{batch}}}, checked for daily use and backed by our lifetime guarantee.

      {{/each}} +
      +{{#if show_debug_panel}}
      debug
      {{/if}} +
      +
      +

      {{{footer_note}}}

      +

      {{{store_name}}} {{{year}}} {{{support_email}}}

      +
      + + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/alert_below.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/alert_below.partial.hbs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/alert_below.partial.hbs @@ -0,0 +1 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/alert_top.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/alert_top.partial.hbs new file mode 100644 index 00000000..d889f879 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/alert_top.partial.hbs @@ -0,0 +1 @@ +
      holiday shipping
      diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/assets_scripts.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/assets_scripts.partial.hbs new file mode 100644 index 00000000..bf801bb9 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/assets_scripts.partial.hbs @@ -0,0 +1 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/assets_styles.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/assets_styles.partial.hbs new file mode 100644 index 00000000..28df0356 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/assets_styles.partial.hbs @@ -0,0 +1 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/badge.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/badge.partial.hbs new file mode 100644 index 00000000..ded4332b --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/badge.partial.hbs @@ -0,0 +1 @@ +{{{label}}} diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/body_end_scripts.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/body_end_scripts.partial.hbs new file mode 100644 index 00000000..51c5f27e --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/body_end_scripts.partial.hbs @@ -0,0 +1 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/body_scripts.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/body_scripts.partial.hbs new file mode 100644 index 00000000..7bcf90f9 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/body_scripts.partial.hbs @@ -0,0 +1 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/card.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/card.partial.hbs new file mode 100644 index 00000000..6e4847c6 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/card.partial.hbs @@ -0,0 +1 @@ +

      {{{name}}}

      {{> badge promo}}{{> price promo}}

      {{{value}}}

      diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/custom_styles.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/custom_styles.partial.hbs new file mode 100644 index 00000000..c03f73c5 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/custom_styles.partial.hbs @@ -0,0 +1 @@ +/* CSS Comment Test */ diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/head_scripts.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/head_scripts.partial.hbs new file mode 100644 index 00000000..35f0ac9a --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/head_scripts.partial.hbs @@ -0,0 +1 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/layout.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/layout.partial.hbs new file mode 100644 index 00000000..8573528b --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/layout.partial.hbs @@ -0,0 +1,126 @@ + + + + + + + + + + Title + + + + + + + + + {{> assets_styles}} + + {{> head_scripts}} + + + {{> body_scripts}} +
      +
      + +
      +
      +
      +
      + {{> alert_top}} +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + {{#each nav.menus}}{{> mega_menu}}{{/each}} +
      +
      +
      + {{> alert_below}} +
      +
      + {{> @partial-block}} +
      +
      +
      +
      +
      + +
      +
      + {{> assets_scripts}} + + {{> body_end_scripts}} + + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/media_row.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/media_row.partial.hbs new file mode 100644 index 00000000..38a1990f --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/media_row.partial.hbs @@ -0,0 +1 @@ +
      {{{name}}}

      {{{name}}}

      Caption for {{{name}}}

      diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/mega_menu.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/mega_menu.partial.hbs new file mode 100644 index 00000000..a57946fc --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/mega_menu.partial.hbs @@ -0,0 +1 @@ +
        {{#each tabs}}
      • {{{label}}}{{#if has_dropdown}}
        {{#each columns}}{{> nav_column}}{{/each}}
        {{/if}}
      • {{/each}}
      diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/nav_column.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/nav_column.partial.hbs new file mode 100644 index 00000000..71fdbc58 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/nav_column.partial.hbs @@ -0,0 +1 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/nav_link.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/nav_link.partial.hbs new file mode 100644 index 00000000..2a846b95 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/nav_link.partial.hbs @@ -0,0 +1 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/nav_section.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/nav_section.partial.hbs new file mode 100644 index 00000000..d3357f4d --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/nav_section.partial.hbs @@ -0,0 +1 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/price.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/price.partial.hbs new file mode 100644 index 00000000..99d73cd2 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/price.partial.hbs @@ -0,0 +1 @@ +

      {{{price}}}.99

      diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/secondary_retail_menu.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/secondary_retail_menu.partial.hbs new file mode 100644 index 00000000..6c6147b8 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/secondary_retail_menu.partial.hbs @@ -0,0 +1,116 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/secondary_wholesale_menu.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/secondary_wholesale_menu.partial.hbs new file mode 100644 index 00000000..b80f8830 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/secondary_wholesale_menu.partial.hbs @@ -0,0 +1,138 @@ + diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/stat.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/stat.partial.hbs new file mode 100644 index 00000000..87e8f5b9 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/stat.partial.hbs @@ -0,0 +1 @@ +
      {{{name}}}{{{value}}}{{{delta}}}
      diff --git a/benchmarks/js/src/templates/handlebars/controlled/shared/tile.partial.hbs b/benchmarks/js/src/templates/handlebars/controlled/shared/tile.partial.hbs new file mode 100644 index 00000000..35b7dd23 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/shared/tile.partial.hbs @@ -0,0 +1 @@ +

      {{{name}}}

      {{{value}}}

      {{{badge}}}
      diff --git a/benchmarks/js/src/templates/handlebars/controlled/trivial-substitution.hbs b/benchmarks/js/src/templates/handlebars/controlled/trivial-substitution.hbs new file mode 100644 index 00000000..d4862681 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/controlled/trivial-substitution.hbs @@ -0,0 +1 @@ +

      {{{title}}}

      {{{sku}}}

      {{{price}}}

      {{{brand}}}

      {{{category}}}

      {{{availability}}}

      {{{summary}}}

      {{{rating}}}

      \ No newline at end of file diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/composed-page.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/composed-page.hbs new file mode 100644 index 00000000..35ef43f5 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/composed-page.hbs @@ -0,0 +1,20 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +{{#> layout}} +
      +
      +
      +
      +
      + + + +
      +
      +
      +{{/layout}} diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/conditional-heavy.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/conditional-heavy.hbs new file mode 100644 index 00000000..a3d8e16f --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/conditional-heavy.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +
        {{#each rows}}
      • {{#if is_bronze}}bronze{{else if is_silver}}silver{{else if is_gold}}gold{{else}}platinum{{/if}}{{{name}}}{{#if has_note}}note {{{seq}}}{{/if}}{{#if is_active}}active{{/if}}
      • {{/each}}
      diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/encoded-loop.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/encoded-loop.hbs new file mode 100644 index 00000000..2d534ebc --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/encoded-loop.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +{{#each items}}{{/each}}
      {{name}}{{comment}}
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/fortunes-encoded.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/fortunes-encoded.hbs new file mode 100644 index 00000000..4b5ee307 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/fortunes-encoded.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +Fortunes{{#each rows}}{{/each}}
      idmessage
      {{id}}{{message}}
      \ No newline at end of file diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/fragment-heavy.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/fragment-heavy.hbs new file mode 100644 index 00000000..fbb8c234 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/fragment-heavy.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +
      {{#each items}}{{#if is_tile}}{{> tile this}}{{else if is_card}}{{> card this}}{{else if is_media}}{{> media_row this}}{{else}}{{> stat this}}{{/if}}{{/each}}
      diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/large-loop.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/large-loop.hbs new file mode 100644 index 00000000..54d71c61 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/large-loop.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +{{#each items}}row-{{{value}}}{{{value}}}{{/each}} diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/mixed-page.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/mixed-page.hbs new file mode 100644 index 00000000..56d27613 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/mixed-page.hbs @@ -0,0 +1,34 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + + + + +{{{page_title}}} + + + +
      +

      {{{store_name}}}

      + +
      +
      +{{#if show_banner}}{{/if}} +
      +

      {{{hero_heading}}}

      +

      {{{hero_tagline}}}

      +
      +
      +{{#each products}}

      {{{name}}}

      MX-{{{sku_number}}}

      {{{price}}}

      {{#if on_sale}}

      On sale

      {{/if}}

      A dependable workshop staple from batch {{{batch}}}, checked for daily use and backed by our lifetime guarantee.

      {{/each}} +
      +{{#if show_debug_panel}}
      debug
      {{/if}} +
      +
      +

      {{{footer_note}}}

      +

      {{{store_name}}} {{{year}}} {{{support_email}}}

      +
      + + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/alert_below.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/alert_below.partial.hbs new file mode 100644 index 00000000..88e24e78 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/alert_below.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/alert_top.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/alert_top.partial.hbs new file mode 100644 index 00000000..d2860e0f --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/alert_top.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +
      holiday shipping
      diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/assets_scripts.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/assets_scripts.partial.hbs new file mode 100644 index 00000000..da29ea2a --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/assets_scripts.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/assets_styles.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/assets_styles.partial.hbs new file mode 100644 index 00000000..fb5c4330 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/assets_styles.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/badge.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/badge.partial.hbs new file mode 100644 index 00000000..daf55ec0 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/badge.partial.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +{{{label}}} diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/body_end_scripts.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/body_end_scripts.partial.hbs new file mode 100644 index 00000000..1ec04b1f --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/body_end_scripts.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/body_scripts.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/body_scripts.partial.hbs new file mode 100644 index 00000000..68c51d7d --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/body_scripts.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/card.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/card.partial.hbs new file mode 100644 index 00000000..0b83ed11 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/card.partial.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +

      {{{name}}}

      {{> badge promo}}{{> price promo}}

      {{{value}}}

      diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/custom_styles.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/custom_styles.partial.hbs new file mode 100644 index 00000000..8a4955d1 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/custom_styles.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +/* CSS Comment Test */ diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/head_scripts.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/head_scripts.partial.hbs new file mode 100644 index 00000000..d3b35891 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/head_scripts.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/layout.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/layout.partial.hbs new file mode 100644 index 00000000..0af46393 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/layout.partial.hbs @@ -0,0 +1,133 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + + + + + + + + + + Title + + + + + + + + + {{> assets_styles}} + + {{> head_scripts}} + + + {{> body_scripts}} +
      +
      + +
      +
      +
      +
      + {{> alert_top}} +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + {{#each nav.menus}}{{> mega_menu}}{{/each}} +
      +
      +
      + {{> alert_below}} +
      +
      + {{> @partial-block}} +
      +
      +
      +
      +
      + +
      +
      + {{> assets_scripts}} + + {{> body_end_scripts}} + + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/media_row.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/media_row.partial.hbs new file mode 100644 index 00000000..210c80c6 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/media_row.partial.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +
      {{{name}}}

      {{{name}}}

      Caption for {{{name}}}

      diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/mega_menu.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/mega_menu.partial.hbs new file mode 100644 index 00000000..f1b97003 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/mega_menu.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +
        {{#each tabs}}
      • {{{label}}}{{#if has_dropdown}}
        {{#each columns}}{{> nav_column}}{{/each}}
        {{/if}}
      • {{/each}}
      diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/nav_column.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/nav_column.partial.hbs new file mode 100644 index 00000000..2d28aaf9 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/nav_column.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/nav_link.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/nav_link.partial.hbs new file mode 100644 index 00000000..85e2c139 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/nav_link.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/nav_section.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/nav_section.partial.hbs new file mode 100644 index 00000000..3f237482 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/nav_section.partial.hbs @@ -0,0 +1,8 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/price.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/price.partial.hbs new file mode 100644 index 00000000..75082114 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/price.partial.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +

      {{{price}}}.99

      diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/secondary_retail_menu.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/secondary_retail_menu.partial.hbs new file mode 100644 index 00000000..9c613041 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/secondary_retail_menu.partial.hbs @@ -0,0 +1,123 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/secondary_wholesale_menu.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/secondary_wholesale_menu.partial.hbs new file mode 100644 index 00000000..c94dd3b2 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/secondary_wholesale_menu.partial.hbs @@ -0,0 +1,145 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html#partial-blocks (partial-block layout: + {{#> layout}} + {{> @partial-block}} at the body slot), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts, partial parameters), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} + diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/stat.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/stat.partial.hbs new file mode 100644 index 00000000..21426281 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/stat.partial.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +
      {{{name}}}{{{value}}}{{{delta}}}
      diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/shared/tile.partial.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/shared/tile.partial.hbs new file mode 100644 index 00000000..0ee77d65 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/shared/tile.partial.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +

      {{{name}}}

      {{{value}}}

      {{{badge}}}
      diff --git a/benchmarks/js/src/templates/handlebars/idiomatic/trivial-substitution.hbs b/benchmarks/js/src/templates/handlebars/idiomatic/trivial-substitution.hbs new file mode 100644 index 00000000..dc1ed1c0 --- /dev/null +++ b/benchmarks/js/src/templates/handlebars/idiomatic/trivial-substitution.hbs @@ -0,0 +1,6 @@ +{{!-- idiomatic Handlebars implementation (Phase 4). + Patterns followed: https://handlebarsjs.com/guide/#simple-expressions, + https://handlebarsjs.com/guide/builtin-helpers.html (#if, #each), + https://handlebarsjs.com/guide/partials.html (partials, partial contexts), + https://handlebarsjs.com/guide/installation/precompilation.html (precompiled execution). --}} +

      {{{title}}}

      {{{sku}}}

      {{{price}}}

      {{{brand}}}

      {{{category}}}

      {{{availability}}}

      {{{summary}}}

      {{{rating}}}

      \ No newline at end of file diff --git a/benchmarks/js/test/gate-selftest.mjs b/benchmarks/js/test/gate-selftest.mjs new file mode 100644 index 00000000..074d7b43 --- /dev/null +++ b/benchmarks/js/test/gate-selftest.mjs @@ -0,0 +1,484 @@ +// Gate library self-test: fixtures for each pipeline step (CRLF, BOM survival, +// lone-surrogate rejection, inter-tag collapse incl. multi-run, N3b removal to nothing incl. a +// space-vs-nothing pair that must compare equal, edge trim, every N5 spelling variant incl. +// leading zeros and hex case, no-rescan, non-five-char NCRs untouched) plus the verifier +// calibration re-run: for each workload the verifier accepts the committed golden and rejects +// the canonical corruptions — two per raw workload, three per encoded — each with the +// correct failing check kind (pins mirror benchmarks/dotnet/src/Corpus/VerifierDefinitions.cs +// and the synthesis rules of GoldenCorpus.cs). +// Also runs the model smoke (pinned cardinalities and spot values). +import { + normalize, + stripWhitespace, + canonicalizeEntities, + countOccurrences, +} from "../src/gate/normalize.mjs"; +import { assertControlledCell, assertSecurityFloor, GateFailure } from "../src/gate/controlled.mjs"; +import { verify } from "../src/gate/verifier.mjs"; +import { WORKLOADS, loadCorpusEntry, loadVerifyDefinition } from "../src/gate/corpus.mjs"; + +let passed = 0; +let failed = 0; +const failures = []; + +function check(name, fn) { + try { + fn(); + passed++; + } catch (error) { + failed++; + failures.push(` [FAIL] ${name}: ${error.message}`); + } +} + +function assertEqual(actual, expected, what = "value") { + if (actual !== expected) { + throw new Error(`${what}: expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`); + } +} + +function assertThrows(fn, substring) { + try { + fn(); + } catch (error) { + if (substring && !error.message.includes(substring)) { + throw new Error(`threw, but message lacks "${substring}": ${error.message}`); + } + return; + } + throw new Error("expected an exception, none was thrown"); +} + +// ---- 1. Normalization fixtures (N1–N4, N3b) --------------------------------------------------- + +check("N2: CRLF and lone CR unify to LF", () => + assertEqual(normalize("a\r\nb\rc", "raw"), "a\nb\nc")); + +check("N3: inter-tag whitespace run collapses to nothing", () => + assertEqual(normalize("x \t\n y", "raw"), "xy")); + +check("N3: multiple inter-tag runs collapse in one pass", () => + assertEqual(normalize(" \n\t ", "raw"), "")); + +check("N3: six-character class includes VT and FF", () => + assertEqual(normalize("\v\f", "raw"), "")); + +check("N4: edge trim strips only the six-character class", () => + assertEqual(normalize(" \t\v\f\r\nx y \n", "raw"), "x y")); + +check("N4: is not String.trim — U+00A0 NBSP survives the edge trim", () => + assertEqual(normalize(" x ", "raw"), " x ")); + +check("N3b: every whitespace run anywhere is removed to nothing", () => + assertEqual(stripWhitespace("a b\t\tc\nd \r e"), "abcde")); + +check("N3b: space-vs-nothing pair compares equal (presence-vs-absence)", () => + assertEqual(stripWhitespace("a b"), stripWhitespace("ab"))); + +check("N3b: run-length pair compares equal", () => + assertEqual(stripWhitespace("a b"), stripWhitespace("a b"))); + +check("N3b: does not touch non-whitespace Unicode (Japanese intact)", () => + assertEqual(stripWhitespace("こんにちは 0"), "こんにちは0")); + +check("N1: lone surrogate is rejected as invalid UTF-8", () => + assertThrows(() => normalize("ok\uD800broken", "raw"), "lone surrogate")); + +check("N1/BOM: leading U+FEFF is not stripped by the pipeline", () => + assertEqual(normalize("x", "raw"), "x")); + +check("N1/BOM: BOM is not whitespace — it survives the N3b strip", () => + assertEqual(stripWhitespace(" x"), "x")); + +// ---- 2. N5 entity canonicalization fixtures --------------------------------------------------- + +const n5Cases = [ + // named (case-sensitive) + ["&", "&"], + ["<", "<"], + [">", ">"], + [""", """], + ["'", "'"], + ["&", "&"], // wrong-case named entity: untouched + // decimal, with and without leading zeros + ["&", "&"], + ["&", "&"], + ["<", "<"], + [">", ">"], + [""", """], + ["'", "'"], + ["'", "'"], + // hex, case-insensitive in `x` and digits, with leading zeros + ["&", "&"], + ["&", "&"], + ["<", "<"], + ["<", "<"], + [">", ">"], + [">", ">"], + [""", """], + ["'", "'"], // the hex apostrophe spelling Handlebars-JS emits + ["'", "'"], + // non-five-character references: untouched + ["™", "™"], + ["`", "`"], + ["=", "="], + ["é", "é"], + ["ż", "ż"], // shares the digits "38" but is a different codepoint +]; +for (const [input, expected] of n5Cases) { + check(`N5: ${JSON.stringify(input)} -> ${JSON.stringify(expected)}`, () => + assertEqual(canonicalizeEntities(input), expected)); +} + +check("N5: single pass, output never rescanned (&#39; is not double-canonicalized)", () => + assertEqual(canonicalizeEntities("&#39;"), "&#39;")); + +check("N5: mixed sentence canonicalizes each spelling independently", () => + assertEqual( + canonicalizeEntities("a'b"c&d'e™f"), + "a'b"c&d'e™f", + )); + +check("N5: applies to encoded suite only in normalize()", () => { + assertEqual(normalize("'", "encoded"), "'"); + assertEqual(normalize("'", "raw"), "'"); +}); + +// ---- 3. Controlled gate fixtures against the real corpus machinery ---------------------------- + +check("controlled: golden text accepted verbatim (identity candidate)", () => { + const entry = loadCorpusEntry("trivial-substitution"); + assertControlledCell({ engine: "selftest", workload: "trivial-substitution", output: entry.text }); +}); + +check("controlled: whitespace-only divergence passes (CRLF + inter-tag + inner runs)", () => { + const entry = loadCorpusEntry("trivial-substitution"); + const mangled = ` ${entry.text.replaceAll("><", "> \r\n <").replaceAll(" ", " ")}\t\n`; + assertControlledCell({ engine: "selftest", workload: "trivial-substitution", output: mangled }); +}); + +check("controlled: a leading BOM survives to fail the byte compare", () => { + const entry = loadCorpusEntry("trivial-substitution"); + assertThrows( + () => + assertControlledCell({ + engine: "selftest", + workload: "trivial-substitution", + output: `${entry.text}`, + }), + "first diff at 0", + ); +}); + +check("controlled: lone surrogate fails as invalid UTF-8 (N1)", () => { + const entry = loadCorpusEntry("trivial-substitution"); + assertThrows( + () => + assertControlledCell({ + engine: "selftest", + workload: "trivial-substitution", + output: `${entry.text}\uDFFF`, + }), + "lone surrogate", + ); +}); + +check("controlled: non-whitespace divergence fails with the contract surface", () => { + const entry = loadCorpusEntry("trivial-substitution"); + assertThrows( + () => + assertControlledCell({ + engine: "selftest", + workload: "trivial-substitution", + output: entry.text.replace("HB-2001", "HB-9999"), + }), + "first diff at", + ); +}); + +check("controlled: Handlebars-style ' output passes an encoded cell via N5", () => { + const entry = loadCorpusEntry("fortunes-encoded"); + const hexSpelled = entry.text.replaceAll("'", "'"); + if (hexSpelled === entry.text) throw new Error("fixture inert: golden contains no '"); + assertControlledCell({ engine: "selftest", workload: "fortunes-encoded", output: hexSpelled }); +}); + +check("security floor: raw payload is rejected on un-normalized output", () => { + const entry = loadCorpusEntry("fortunes-encoded"); + assertThrows( + () => + assertSecurityFloor({ + engine: "selftest", + workload: "fortunes-encoded", + rawOutput: entry.text.replace("<script>alert(", "', + "row-11 XSS payload", + ); + assertEqual(models["fortunes-encoded"].rows[11].message, "フレームワークのベンチマーク"); + assertEqual(models["encoded-loop"].items[0].tag, "tag-0&'0'"); + assertEqual(models["encoded-loop"].items[4999].comment, `'q' & "d" こんにちは 4999`); + assertEqual(models["trivial-substitution"].sku, "HB-2001"); + assertEqual(models["trivial-substitution"].price, 4200); + assertEqual(models["composed-page"].nav.menus.length, 2, "nav menus"); + assertEqual(models["composed-page"].nav.menus[0].tabs.length, 6, "menu 0 tabs"); + assertEqual(models["composed-page"].nav.footer_columns.length, 4, "footer columns"); + assertEqual(models["composed-page"].nav.menus[0].tabs[0].has_dropdown, true, "tab 0 has_dropdown"); + const firstLink = models["composed-page"].nav.menus[0].tabs[0].columns[0].sections[0].links[0]; + assertEqual(firstLink.label, "Salmon", "first nav link label"); + assertEqual(firstLink.href, "/products/wild-salmon", "first nav link href"); + assertEqual(models["composed-page"].nav.footer_columns[0].sections[0].title, "Need Help?"); + assertEqual(models["composed-page"].nav.footer_columns[0].sections[0].title_linked, false); +}); + +check("models: removed display fields are gone (models carry data only)", () => { + const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k); + if (has(models["large-loop"].items[0], "name")) throw new Error("large-loop rows still carry name (templates compose display text)"); + if (has(models["conditional-heavy"].rows[0], "note")) throw new Error("conditional-heavy rows still carry note (templates compose display text)"); + if (has(models["mixed-page"].products[0], "sku")) throw new Error("mixed-page products still carry sku (templates compose display text)"); + if (has(models["mixed-page"].products[0], "blurb")) throw new Error("mixed-page products still carry blurb (templates compose display text)"); + for (const key of ["caption", "image_url"]) { + if (has(models["fragment-heavy"].items[2], key)) { + throw new Error(`fragment-heavy rows still carry ${key} (templates compose display text)`); + } + } + if (typeof models["fragment-heavy"].items[0].promo.price !== "number") { + throw new Error("fragment-heavy promo.price is not a number"); + } + for (const key of ["section", "comp", "area_names", "areas"]) { + if (has(models["composed-page"], key)) { + throw new Error(`composed-page still carries ${key} (no text blobs in the model tier)`); + } + } +}); + +check("models: deep-frozen at module load", () => { + for (const { id } of WORKLOADS) { + if (!Object.isFrozen(models[id])) throw new Error(`${id} model is not frozen`); + } + if (!Object.isFrozen(models["mixed-page"].products[0])) throw new Error("nested row not frozen"); + if (!Object.isFrozen(models["composed-page"].nav)) throw new Error("nav not frozen"); + if (!Object.isFrozen(models["composed-page"].nav.menus[0].tabs[0].columns[0].sections[0].links[0])) { + throw new Error("nested nav link not frozen"); + } +}); + +check("models: composed-page nav expansion matches the verifier pins and the golden bytes", () => { + // The structured nav fixture replaced the blob transcription (and its concatenation check — + // the chrome text now lives in the templates, whose presence/order the verifier's ordered + // markers prove). The model side is re-expressed as an independent expansion: count + // columns and links from the loaded nav.json against the verifier definition's pinned counts, + // then require every link's rendered form in the golden byte-for-byte (per-link check). + const { nav } = models["composed-page"]; + const def = loadVerifyDefinition("composed-page"); + const columns = [ + ...nav.menus.flatMap((m) => m.tabs.flatMap((t) => t.columns)), + ...nav.footer_columns, + ]; + const links = columns.flatMap((c) => c.sections.flatMap((s) => s.links)); + const linkPin = def.values.find((v) => v.text === '`; + if (!golden.includes(rendered)) throw new Error(`golden lacks nav link ${rendered}`); + } +}); + +// ---- 5. Verifier calibration re-run ----------------------------------------------------------- +// Corruption synthesis mirrors GoldenCorpus.cs (RemoveFirst / SwapFirst / ReplaceFirst) and the +// per-workload pins of IdiomaticChecks.cs. Two corruptions per +// raw workload, three per encoded workload; each must be rejected with the expected check kind. + +function removeFirst(text, segment) { + const at = text.indexOf(segment); + return at < 0 ? null : text.slice(0, at) + text.slice(at + segment.length); +} + +function replaceFirst(text, from, to) { + const at = text.indexOf(from); + return at < 0 ? null : text.slice(0, at) + to + text.slice(at + from.length); +} + +/** Swaps the first occurrence of `a` with the first occurrence of `b` after it. */ +function swapFirst(text, a, b) { + const atA = text.indexOf(a); + if (atA < 0) return null; + const atB = text.indexOf(b, atA + a.length); + if (atB < 0) return null; + return ( + text.slice(0, atA) + b + text.slice(atA + a.length, atB) + a + text.slice(atB + b.length) + ); +} + +// Per-workload calibration pins (IdiomaticChecks.cs; composed-page pins are its exported +// markers[0]/markers[1], resolved from the verify.json to avoid re-transcription). +const fortunesFirstRow = + "1A bad random number generator: 1, 1, 1, 1, 1, 4.33e67, 1, 1, 1"; +const encodedLoopTag0 = "tag-0&'0'"; +const encodedLoopFirstRow = + `item <0> & "co"` + + "'q' & <angle> "d" こんにちは 0"; + +const calibrationPins = { + "composed-page": (def) => ({ + removedSegment: def.markers[1], + removedKind: "marker", + swapA: def.markers[0], + swapB: def.markers[1], + }), + "trivial-substitution": () => ({ + removedSegment: "HB-2001", + removedKind: "value", + swapA: 'class="sku"', + swapB: 'class="rating"', + }), + "large-loop": () => ({ + removedSegment: "row-00", + removedKind: "value", + swapA: "row-00", + swapB: "row-25002500", + }), + "mixed-page": () => ({ + removedSegment: '
      ', + removedKind: "value", + swapA: "
      ", + swapB: 'class="hero"', + }), + "conditional-heavy": () => ({ + removedSegment: "unit-000", + removedKind: "value", + swapA: "unit-000", + swapB: "unit-100", + }), + "fragment-heavy": () => ({ + removedSegment: "item-00", + removedKind: "value", + swapA: "item-00", + swapB: "item-24", + }), + "fortunes-encoded": () => ({ + removedSegment: fortunesFirstRow, + removedKind: "value", + swapA: "idmessage", + swapB: "フレームワークのベンチマーク", + unescapeEscaped: "<script>alert(", + unescapeRaw: ""}; + + System.out.println("Escaper probe — spellings per escaping path:"); + System.out.println(); + System.out.printf("%-22s %-7s %-7s %-7s %-7s %-7s%n", + "path", "&", "<", ">", "\"", "'"); + int failures = 0; + for (ProbePath path : paths) { + String[] got = new String[five.length]; + for (int i = 0; i < five.length; i++) { + char c = five[i]; + got[i] = path.escape().apply(String.valueOf(c)); + String want = path.spellings().get(c); + if (!got[i].equals(want)) { + System.out.println("[FAIL] " + path.name() + ": char '" + c + + "' rendered \"" + got[i] + "\", expected \"" + want + "\""); + failures++; + } + } + System.out.printf("%-22s %-7s %-7s %-7s %-7s %-7s%n", + path.name(), got[0], got[1], got[2], got[3], got[4]); + + for (String payload : payloads) { + String expected = mapPayload(payload, path.spellings()); + String actual = path.escape().apply(payload); + if (!actual.equals(expected)) { + System.out.println("[FAIL] " + path.name() + ": payload \"" + payload + + "\" rendered \"" + actual + "\", expected \"" + expected + "\""); + failures++; + } + } + } + System.out.println(); + if (failures == 0) { + System.out.println("[PASS] all 6 escaping paths match the pinned spelling table" + + " byte-for-byte (payload set: &<>\"' / こんにちは /" + + " )"); + return 0; + } + System.out.println(failures + " probe failure(s) — contract evidence; escalate the" + + " divergence, never normalize it away."); + return 1; + } + + private static String jteCustom(String value, String tag, String attribute) { + FiveEntityHtmlOutput out = new FiveEntityHtmlOutput(); + out.setContext(tag, attribute); + out.writeUserContent(value); + return out.toString(); + } + + private static String jteStock(String value, String tag, String attribute) { + StringOutput sink = new StringOutput(); + OwaspHtmlTemplateOutput out = new OwaspHtmlTemplateOutput(sink); + out.setContext(tag, attribute); + out.writeUserContent(value); + return sink.toString(); + } + + private static String mapPayload(String payload, Map spellings) { + StringBuilder sb = new StringBuilder(payload.length() + 16); + for (int i = 0; i < payload.length(); i++) { + char c = payload.charAt(i); + String spelling = spellings.get(c); + sb.append(spelling != null ? spelling : String.valueOf(c)); + } + return sb.toString(); + } + + // ---- gate -------------------------------------------------------------------------- + + private static int gate(String[] args) { + String engineFilter = null; + String trackFilter = null; + String workloadFilter = null; + for (int i = 1; i < args.length; i++) { + switch (args[i]) { + case "--engine" -> engineFilter = argValue(args, ++i, "--engine"); + case "--track" -> trackFilter = argValue(args, ++i, "--track"); + case "--workload" -> workloadFilter = argValue(args, ++i, "--workload"); + default -> { + System.err.println("GateCli gate: unknown option '" + args[i] + "'"); + return 1; + } + } + } + + Corpus corpus = Corpus.load(); + int pass = 0; + int fail = 0; + int excluded = 0; + for (Corpus.Entry entry : corpus.entries()) { + if (workloadFilter != null && !workloadFilter.equals(entry.workload)) { + continue; + } + for (String engine : new String[] {"jte", "thymeleaf"}) { + if (engineFilter != null && !engineFilter.equals(engine)) { + continue; + } + for (String track : new String[] {"controlled", "idiomatic"}) { + if (trackFilter != null && !trackFilter.equals(track)) { + continue; + } + String cell = engine + "/" + track + "/" + entry.workload; + if ("controlled".equals(track) + && EXCLUDED_CONTROLLED_CELLS.contains(engine + "/" + entry.workload)) { + System.out.println("[EXCLUDED — documented evidence] " + cell); + excluded++; + continue; + } + String failure = runCell(entry, engine, track); + if (failure == null) { + System.out.println("[PASS] " + cell); + pass++; + } else { + System.out.println("[FAIL] " + cell + ": " + failure); + fail++; + } + } + } + } + System.out.println(); + System.out.println("gate summary: " + pass + " passed, " + fail + " failed, " + + excluded + " excluded"); + return fail == 0 ? 0 : 1; + } + + private static String argValue(String[] args, int index, String option) { + if (index >= args.length) { + throw new IllegalArgumentException(option + " requires a value"); + } + return args[index]; + } + + /** Runs one cell's gate; returns null on pass, a failure description otherwise. */ + private static String runCell(Corpus.Entry entry, String engine, String track) { + String candidate; + try { + candidate = render(entry, engine, track); + } catch (JteEngines.MissingTemplate | IllegalStateException e) { + return "missing template/resources — " + e.getMessage(); + } + return "controlled".equals(track) + ? controlledGate(entry, engine, candidate) + : idiomaticGate(entry, engine, candidate); + } + + private static String render(Corpus.Entry entry, String engine, String track) { + if ("thymeleaf".equals(engine)) { + return ThymeleafEngines.render(track, entry.workload); + } + String template = track + "/" + entry.workload + ".jte"; + Object model = modelFor(entry.workload); + if (!entry.isEncoded()) { + return JteEngines.renderPlain(template, model); + } + return "controlled".equals(track) + ? JteEngines.renderHtmlControlled(template, model) + : JteEngines.renderHtmlIdiomatic(template, model); + } + + private static Object modelFor(String workload) { + return switch (workload) { + case "composed-page" -> Models.composed(); + case "trivial-substitution" -> Models.SUBSTITUTION; + case "large-loop" -> Models.LOOP_ROWS; + case "mixed-page" -> Models.MIXED; + case "conditional-heavy" -> Models.CONDITIONAL_ROWS; + case "fragment-heavy" -> Models.FRAGMENT_ROWS; + case "fortunes-encoded" -> Models.FORTUNE_ROWS; + case "encoded-loop" -> Models.ENCODED_ITEMS; + default -> throw new IllegalArgumentException("Unknown workload '" + workload + "'"); + }; + } + + /** + * The controlled byte gate: normalize N1-N5, + * apply N3b to both sides, compare non-whitespace UTF-8 bytes; encoded suites also + * assert the security floor on the un-normalized candidate. Returns null on pass. + */ + static String controlledGate(Corpus.Entry entry, String engine, String candidate) { + if (entry.isEncoded()) { + int raw = Verifier.countOccurrences(candidate, RAW_PAYLOAD); + if (raw != 0) { + return "Security floor failed: " + entry.workload + " / " + engine + + ": raw \"" + RAW_PAYLOAD + "\" found " + raw + " times (expected 0)"; + } + int expectedEscaped = Verifier.countOccurrences(entry.golden, ESCAPED_PAYLOAD); + int actualEscaped = Verifier.countOccurrences( + Normalizer.normalize(candidate, true), ESCAPED_PAYLOAD); + if (actualEscaped != expectedEscaped) { + return "Security floor failed: " + entry.workload + " / " + engine + + ": escaped \"" + ESCAPED_PAYLOAD + "\" found " + actualEscaped + + " times (expected " + expectedEscaped + ")"; + } + } + String normalized = Normalizer.normalize(candidate, entry.isEncoded()); + String strippedCandidate = Normalizer.strip(normalized); + String strippedGolden = Normalizer.strip(entry.golden); + byte[] act = strippedCandidate.getBytes(StandardCharsets.UTF_8); + byte[] exp = strippedGolden.getBytes(StandardCharsets.UTF_8); + if (java.util.Arrays.equals(exp, act)) { + return null; + } + int diff = 0; + int max = Math.min(exp.length, act.length); + while (diff < max && exp[diff] == act[diff]) { + diff++; + } + return "Controlled gate failed: " + entry.workload + " / " + engine + + ". first diff at index " + diff + " (of exp " + exp.length + "/act " + + act.length + ").\n expected: " + excerptAround(strippedGolden, exp, diff) + + "\n actual: " + excerptAround(strippedCandidate, act, diff); + } + + /** ±40-char excerpt in a 120-char \n-escaped window (ParityCheck.Describe shape). */ + private static String excerptAround(String stripped, byte[] utf8, int byteIndex) { + // Map the byte index back to a char index (the stripped strings are what we show). + int charIndex = new String(utf8, 0, Math.min(byteIndex, utf8.length), + StandardCharsets.UTF_8).length(); + int from = Math.max(0, charIndex - 40); + int to = Math.min(stripped.length(), from + 120); + String window = stripped.substring(from, Math.max(from, Math.min(to, stripped.length()))); + return "..." + window.replace("\n", "\\n") + "..."; + } + + /** The idiomatic verifier gate. Returns null on pass. */ + static String idiomaticGate(Corpus.Entry entry, String engine, String candidate) { + List failures = Verifier.verify(entry.verifier, candidate); + if (failures.isEmpty()) { + return null; + } + return "Idiomatic gate failed: " + entry.workload + " / " + engine + " " + + String.join("; ", failures); + } + + // ---- calibrate --------------------------------------------------------------------- + + private record Corruption(String kind, String expectedCheckKind, String corrupted) { + } + + private static int calibrate() { + Corpus corpus = Corpus.load(); + int failures = 0; + boolean dirtyWarned = false; + for (Corpus.Entry entry : corpus.entries()) { + if (!dirtyWarned && entry.generatingCommit.endsWith("+dirty")) { + System.out.println("[WARN] manifest generatingCommit carries +dirty (" + + entry.generatingCommit + ") — a committed +dirty manifest fails" + + " review by inspection"); + dirtyWarned = true; + } + List golden = Verifier.verify(entry.verifier, entry.golden); + if (!golden.isEmpty()) { + System.out.println("[FAIL] " + entry.workload + + " calibration: golden rejected: " + golden.get(0)); + failures++; + continue; + } + List corruptions; + try { + corruptions = corruptionsFor(entry); + } catch (IllegalStateException e) { + System.out.println("[FAIL] " + entry.workload + " calibration: " + e.getMessage()); + failures++; + continue; + } + boolean allRejected = true; + for (Corruption corruption : corruptions) { + List got = Verifier.verify(entry.verifier, corruption.corrupted()); + boolean rejectedWithKind = got.stream().anyMatch( + f -> f.startsWith("verifier " + corruption.expectedCheckKind() + ":")); + if (!rejectedWithKind) { + String detail = got.isEmpty() + ? "was NOT rejected" + : "was rejected, but not by the '" + corruption.expectedCheckKind() + + "' check (got: " + got.get(0) + ")"; + System.out.println("[FAIL] " + entry.workload + " calibration: corruption '" + + corruption.kind() + "' " + detail); + allRejected = false; + } + } + if (allRejected) { + System.out.println("[PASS] " + entry.workload + " calibration: golden accepted, " + + corruptions.size() + " corruption(s) rejected with the correct check kind"); + } else { + failures++; + } + } + System.out.println(); + if (failures == 0) { + System.out.println("calibrate: all 8 workloads calibrated" + + " (raw: 2 corruptions each, encoded: 3)"); + return 0; + } + System.out.println("calibrate: " + failures + " workload(s) failed calibration"); + return 1; + } + + /** + * The synthesized corruptions calibration must reject, pinned per workload exactly as + * the .NET harness's {@code IdiomaticChecks} pins them: removed + * row/segment, reordered sections, and (encoded only) unescaped payload - + * encoded-loop's pinned escaped->raw pair is {@code <angle>} -> + * {@code } (the workload carries no script payload). + */ + private static List corruptionsFor(Corpus.Entry entry) { + Map pins = calibrationPins(entry); + List corruptions = new ArrayList<>(3); + + String[] removed = pins.get("removed"); + corruptions.add(new Corruption("removed-row", removed[1], + deleteFirst(entry.golden, removed[0]))); + + String[] swap = pins.get("swap"); + corruptions.add(new Corruption("reordered-section", "marker", + swapFirst(entry.golden, swap[0], swap[1]))); + + String[] unescape = pins.get("unescape"); + if (unescape != null) { + corruptions.add(new Corruption("unescaped-payload", "forbidden", + replaceFirst(entry.golden, unescape[0], unescape[1]))); + } + return corruptions; + } + + private static Map calibrationPins(Corpus.Entry entry) { + Map pins = new LinkedHashMap<>(); + switch (entry.workload) { + case "composed-page" -> { + // Mirrors the .NET harness's VerifierDefinitions.ComposedPage() pins: the + // removed segment is the slider fragment the page splices into the layout's + // live body slot - so an idiomatic page with an EMPTY body fails - and the + // swap pair is one anchor unique to each mega menu (wholesale vs retail). + pins.put("removed", new String[] { + "", + "marker"}); + pins.put("swap", new String[] { + "/product/coming-soon-paleo-pork", "/products/paleo-friendly-pork"}); + } + case "trivial-substitution" -> { + pins.put("removed", new String[] {"HB-2001", "value"}); + pins.put("swap", new String[] {"class=\"sku\"", "class=\"rating\""}); + } + case "large-loop" -> { + pins.put("removed", new String[] {"row-00", "value"}); + pins.put("swap", new String[] {"row-00", + "row-25002500"}); + } + case "mixed-page" -> { + pins.put("removed", new String[] {"
      ", "value"}); + pins.put("swap", new String[] {"
      ", "class=\"hero\""}); + } + case "conditional-heavy" -> { + pins.put("removed", new String[] {"unit-000", "value"}); + pins.put("swap", new String[] {"unit-000", "unit-100"}); + } + case "fragment-heavy" -> { + // Mirrors the .NET harness's VerifierDefinitions.FragmentHeavy() pins: row 0 + // is a tile; its whole fragment is the removed-row corruption, computed + // from the model so the pin cannot drift. Rows 0 and 24 are both tiles. + Models.FragmentRow row0 = Models.FRAGMENT_ROWS.get(0); + String firstTile = "

      " + row0.getName() + + "

      " + row0.getValue() + + "

      " + row0.getBadge() + "
      "; + pins.put("removed", new String[] {firstTile, "value"}); + pins.put("swap", new String[] {"item-00", "item-24"}); + } + case "fortunes-encoded" -> { + Models.FortuneRow row0 = Models.FORTUNE_ROWS.get(0); + String firstRow = "" + row0.getId() + "" + + FiveEntityHtmlOutput.escape(row0.getMessage()) + ""; + pins.put("removed", new String[] {firstRow, "value"}); + pins.put("swap", new String[] {"idmessage", + "フレームワークのベンチマーク"}); + pins.put("unescape", new String[] {ESCAPED_PAYLOAD, RAW_PAYLOAD}); + } + case "encoded-loop" -> { + Models.EncodedLoopRow row0 = Models.ENCODED_ITEMS.get(0); + String tag0 = FiveEntityHtmlOutput.escape(row0.getTag()); + String firstRow = "" + + FiveEntityHtmlOutput.escape(row0.getName()) + "" + + FiveEntityHtmlOutput.escape(row0.getComment()) + ""; + pins.put("removed", new String[] {firstRow, "value"}); + pins.put("swap", new String[] {tag0, "item <2500>"}); + // This workload carries no script payload; the escaped->raw pair is + // the comment's angle text (forbidden: ). + pins.put("unescape", new String[] {"<angle>", ""}); + } + default -> throw new IllegalStateException( + "no calibration pins for workload '" + entry.workload + "'"); + } + return pins; + } + + private static String deleteFirst(String text, String segment) { + int at = text.indexOf(segment); + if (at < 0) { + throw new IllegalStateException("calibration pin not found in golden: \"" + + segment.substring(0, Math.min(48, segment.length())) + "\""); + } + return text.substring(0, at) + text.substring(at + segment.length()); + } + + private static String replaceFirst(String text, String from, String to) { + int at = text.indexOf(from); + if (at < 0) { + throw new IllegalStateException("calibration pin not found in golden: \"" + + from + "\""); + } + return text.substring(0, at) + to + text.substring(at + from.length()); + } + + /** Swaps the first occurrence of {@code a} with the first occurrence of {@code b} after it. */ + private static String swapFirst(String text, String a, String b) { + int posA = text.indexOf(a); + if (posA < 0) { + throw new IllegalStateException("calibration pin not found in golden: \"" + + a.substring(0, Math.min(48, a.length())) + "\""); + } + int posB = text.indexOf(b, posA + a.length()); + if (posB < 0) { + throw new IllegalStateException("calibration pin not found after its pair: \"" + + b.substring(0, Math.min(48, b.length())) + "\""); + } + return text.substring(0, posA) + b + text.substring(posA + a.length(), posB) + + a + text.substring(posB + b.length()); + } +} diff --git a/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/gate/Gates.java b/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/gate/Gates.java new file mode 100644 index 00000000..ba22a858 --- /dev/null +++ b/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/gate/Gates.java @@ -0,0 +1,51 @@ +package heddle.benchmarks.jvm.gate; + +import java.util.function.Supplier; + +/** + * Benchmark-time gate assertions. Called from every {@code *Bench} class's + * {@code @Setup(Level.Trial)} so each JMH fork re-asserts its cells' gates in the same + * process that produces its numbers. A failed gate throws {@link IllegalStateException} + * carrying the gate's failure description; JMH aborts the fork and it produces no numbers. + * + * The gate logic itself lives once, in {@link GateCli} (DRY: the same code serves the CLI + * and every fork); this class only adds corpus caching and the throw-on-failure adapter. + */ +public final class Gates { + + private static volatile Corpus corpus; + + private Gates() { + } + + private static Corpus corpus() { + Corpus c = corpus; + if (c == null) { + synchronized (Gates.class) { + c = corpus; + if (c == null) { + corpus = c = Corpus.load(); + } + } + } + return c; + } + + /** Controlled byte gate (+ encoded security floor) for one cell; throws on failure. */ + public static void assertControlled(String workload, String engine, + Supplier render) { + String failure = GateCli.controlledGate(corpus().entry(workload), engine, render.get()); + if (failure != null) { + throw new IllegalStateException(failure); + } + } + + /** Idiomatic verifier gate for one cell; throws on failure. */ + public static void assertIdiomatic(String workload, String engine, + Supplier render) { + String failure = GateCli.idiomaticGate(corpus().entry(workload), engine, render.get()); + if (failure != null) { + throw new IllegalStateException(failure); + } + } +} diff --git a/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/gate/Normalizer.java b/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/gate/Normalizer.java new file mode 100644 index 00000000..35eeb182 --- /dev/null +++ b/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/gate/Normalizer.java @@ -0,0 +1,215 @@ +package heddle.benchmarks.jvm.gate; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; +import java.nio.charset.StandardCharsets; + +/** + * Contract-literal implementation of the parity contract's normalization pipeline + * (N1-N5 plus the N3b comparison-time whitespace strip). Nothing outside the closed list + * is applied; the whitespace set is the explicit six-character set + * {TAB, LF, VT, FF, CR, SPACE} - never a language {@code \s} class. + */ +public final class Normalizer { + + private Normalizer() { + } + + /** The six-character whitespace set. Deliberately not {@code Character.isWhitespace}. */ + static boolean isWs(char c) { + return c == '\t' || c == '\n' || c == 0x0B || c == '\f' || c == '\r' || c == ' '; + } + + /** + * N1: strict UTF-8 decode; invalid UTF-8 is a gate failure. A leading U+FEFF (BOM) is + * kept - it survives to the comparison and fails it. + */ + public static String decodeUtf8Strict(byte[] bytes) { + CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + try { + CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes)); + return decoded.toString(); + } catch (CharacterCodingException e) { + throw new IllegalStateException("N1: invalid UTF-8 in candidate/corpus bytes", e); + } + } + + /** + * Applies N2, N3, N4 and (encoded suite only) N5 in contract order. N1 is applied at + * byte-decode time ({@link #decodeUtf8Strict}); N3b is a comparison-time projection + * applied separately via {@link #strip}. + */ + public static String normalize(String text, boolean encodedSuite) { + String s = n2(text); + s = n3(s); + s = n4(s); + if (encodedSuite) { + s = n5(s); + } + return s; + } + + /** N2: replace every CRLF with LF, then every remaining CR with LF. */ + static String n2(String s) { + return s.replace("\r\n", "\n").replace('\r', '\n'); + } + + /** + * N3: single left-to-right scan collapsing every run of six-set whitespace between + * {@code >} and {@code <} to nothing. Replacements cannot create new matches + * (the replacement {@code ><} contains no whitespace), so one pass suffices. + */ + static String n3(String s) { + StringBuilder sb = new StringBuilder(s.length()); + int i = 0; + int n = s.length(); + while (i < n) { + char c = s.charAt(i); + sb.append(c); + if (c == '>') { + int j = i + 1; + while (j < n && isWs(s.charAt(j))) { + j++; + } + if (j > i + 1 && j < n && s.charAt(j) == '<') { + i = j; // skip the whitespace run; '<' appended on the next iteration + continue; + } + } + i++; + } + return sb.toString(); + } + + /** N4: trim leading/trailing characters from the six-character whitespace set. */ + static String n4(String s) { + int start = 0; + int end = s.length(); + while (start < end && isWs(s.charAt(start))) { + start++; + } + while (end > start && isWs(s.charAt(end - 1))) { + end--; + } + return s.substring(start, end); + } + + /** + * N3b: remove every run of six-set whitespace anywhere, + * to nothing (not to a space). Applied symmetrically at comparison time to both the + * normalized candidate and the loaded golden, and to every verifier needle - never + * baked into the stored oracle. + */ + public static String strip(String s) { + StringBuilder sb = new StringBuilder(s.length()); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (!isWs(c)) { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * N5, encoded suite only: the contract's closed entity-canonicalization table. Named + * entities match case-sensitively; numeric references match with any number of leading + * zeros, case-insensitive hex digits and {@code x}. Single left-to-right scan; + * replacements are non-overlapping and never rescanned. Only spellings of the five + * markup-significant characters are canonicalized. + */ + static String n5(String s) { + StringBuilder sb = new StringBuilder(s.length()); + int i = 0; + int n = s.length(); + while (i < n) { + char c = s.charAt(i); + if (c == '&') { + int consumed = tryEntity(s, i, sb); + if (consumed > 0) { + i += consumed; + continue; + } + } + sb.append(c); + i++; + } + return sb.toString(); + } + + /** + * Attempts to match one recognized spelling starting at {@code s.charAt(at) == '&'}. + * On a match appends the canonical spelling to {@code out} and returns the number of + * input chars consumed; returns 0 otherwise. + */ + private static int tryEntity(String s, int at, StringBuilder out) { + // Named entities - case-sensitive. + String[][] named = { + {"&", "&"}, + {"<", "<"}, + {">", ">"}, + {""", """}, + {"'", "'"}, + }; + for (String[] e : named) { + if (s.startsWith(e[0], at)) { + out.append(e[1]); + return e[0].length(); + } + } + // Numeric references: { or { - any leading zeros, case-insensitive hex/x. + if (at + 2 >= s.length() || s.charAt(at + 1) != '#') { + return 0; + } + int p = at + 2; + boolean hex = false; + if (p < s.length() && (s.charAt(p) == 'x' || s.charAt(p) == 'X')) { + hex = true; + p++; + } + int digitsStart = p; + long value = 0; + boolean overflow = false; + while (p < s.length()) { + char d = s.charAt(p); + int dv; + if (d >= '0' && d <= '9') { + dv = d - '0'; + } else if (hex && d >= 'a' && d <= 'f') { + dv = d - 'a' + 10; + } else if (hex && d >= 'A' && d <= 'F') { + dv = d - 'A' + 10; + } else { + break; + } + if (!overflow) { + value = value * (hex ? 16 : 10) + dv; + if (value > 0x10FFFF) { + overflow = true; + } + } + p++; + } + if (p == digitsStart || p >= s.length() || s.charAt(p) != ';' || overflow) { + return 0; + } + String canonical = switch ((int) value) { + case 0x26 -> "&"; + case 0x3C -> "<"; + case 0x3E -> ">"; + case 0x22 -> """; + case 0x27 -> "'"; + default -> null; + }; + if (canonical == null) { + return 0; + } + out.append(canonical); + return p + 1 - at; + } +} diff --git a/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/gate/Verifier.java b/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/gate/Verifier.java new file mode 100644 index 00000000..f2186712 --- /dev/null +++ b/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/gate/Verifier.java @@ -0,0 +1,143 @@ +package heddle.benchmarks.jvm.gate; + +import com.fasterxml.jackson.databind.JsonNode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Java implementation of the idiomatic-track verifier, consuming the exported + * {@code .verify.json} definitions. Matching semantics mirror the intra-.NET + * {@code IdiomaticChecks.Verify}: the candidate is normalized N1-N4 (+N5 encoded), then + * the N3b whitespace strip is applied to the output AND to every needle before matching; + * {@code values} are exact non-overlapping counts, {@code markers} are strictly ordered, + * {@code forbidden} must be absent from both raw and normalized output, {@code required} + * is a minimum count. Failure messages start with {@code "verifier : "}. + */ +public final class Verifier { + + public record ValueCheck(String text, int count) { + } + + public record RequiredCheck(String text, int minCount) { + } + + public static final class Definition { + public final String workload; + public final String suite; + public final List values; + public final List markers; + public final List forbidden; + public final List required; + + Definition(String workload, String suite, List values, + List markers, List forbidden, List required) { + this.workload = workload; + this.suite = suite; + this.values = values; + this.markers = markers; + this.forbidden = forbidden; + this.required = required; + } + + public boolean isEncoded() { + return "encoded".equals(suite); + } + } + + private Verifier() { + } + + /** Parses one {@code .verify.json} document (already Jackson-parsed). */ + public static Definition parse(JsonNode root) { + List values = new ArrayList<>(); + for (JsonNode v : root.path("values")) { + values.add(new ValueCheck(v.path("text").asText(), v.path("count").asInt())); + } + List markers = new ArrayList<>(); + for (JsonNode m : root.path("markers")) { + markers.add(m.asText()); + } + List forbidden = new ArrayList<>(); + for (JsonNode f : root.path("forbidden")) { + forbidden.add(f.asText()); + } + List required = new ArrayList<>(); + for (JsonNode r : root.path("required")) { + required.add(new RequiredCheck(r.path("text").asText(), r.path("minCount").asInt())); + } + return new Definition(root.path("workload").asText(), root.path("suite").asText(), + values, markers, forbidden, required); + } + + /** + * Runs the verifier against a candidate's raw output. Returns an empty list when + * accepted; otherwise one message per failed check. + */ + public static List verify(Definition def, String rawOutput) { + List failures = new ArrayList<>(); + String normalized = Normalizer.normalize(rawOutput, def.isEncoded()); + String stripped = Normalizer.strip(normalized); + String strippedRaw = Normalizer.strip(rawOutput); + + for (ValueCheck v : def.values) { + int found = countOccurrences(stripped, Normalizer.strip(v.text())); + if (found != v.count()) { + failures.add("verifier value: expected " + v.count() + " of \"" + + excerpt(v.text()) + "\", found " + found); + } + } + + int pos = 0; + for (String marker : def.markers) { + String needle = Normalizer.strip(marker); + int at = stripped.indexOf(needle, pos); + if (at < 0) { + failures.add("verifier marker: expected 1 of \"" + excerpt(marker) + + "\" in order after index " + pos + ", found 0"); + // Keep scanning subsequent markers from the current position so every + // out-of-order/missing marker is reported. + continue; + } + pos = at + needle.length(); + } + + for (String f : def.forbidden) { + String needle = Normalizer.strip(f); + int found = Math.max(countOccurrences(strippedRaw, needle), + countOccurrences(stripped, needle)); + if (found != 0) { + failures.add("verifier forbidden: expected 0 of \"" + excerpt(f) + + "\", found " + found); + } + } + + for (RequiredCheck r : def.required) { + int found = countOccurrences(stripped, Normalizer.strip(r.text())); + if (found < r.minCount()) { + failures.add("verifier required: expected " + r.minCount() + " of \"" + + excerpt(r.text()) + "\", found " + found); + } + } + + return failures; + } + + static int countOccurrences(String haystack, String needle) { + if (needle.isEmpty()) { + return 0; + } + int count = 0; + int index = 0; + while ((index = haystack.indexOf(needle, index)) >= 0) { + count++; + index += needle.length(); + } + return count; + } + + private static String excerpt(String s) { + String cut = s.length() <= 48 ? s : s.substring(0, 48) + "…"; + return cut.replace("\n", "\\n"); + } +} diff --git a/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/jte/FiveEntityHtmlOutput.java b/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/jte/FiveEntityHtmlOutput.java new file mode 100644 index 00000000..5aa7d5fc --- /dev/null +++ b/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/jte/FiveEntityHtmlOutput.java @@ -0,0 +1,81 @@ +package heddle.benchmarks.jvm.jte; + +import gg.jte.html.HtmlTemplateOutput; +import gg.jte.output.StringOutput; + +import java.util.Locale; + +/** + * The JTE controlled encoded suite renders through this custom + * {@link gg.jte.html.HtmlTemplateOutput} instead of the stock OWASP output. + * {@code writeUserContent(String)} escapes exactly the five markup-significant characters + * to the corpus's canonical spellings ({@code & < > " '}) in both + * tag-body and attribute contexts; all {@code writeContent} overloads (inherited from + * {@link StringOutput}) append verbatim; primitive {@code writeUserContent} overloads + * append their {@code String.valueOf} (never escapable). {@code setContext} records the + * context and throws {@link IllegalStateException} on a {@code script}-tag or + * {@code on*}-attribute JavaScript context - a tripwire, not a path: no such context + * exists in the corpus templates. + * {@code TemplateEngine.checkOutput} uses a caller-supplied {@code HtmlTemplateOutput} + * as-is (verified at source), so this is a supported engine seam. + */ +public final class FiveEntityHtmlOutput extends StringOutput implements HtmlTemplateOutput { + + private String tagName; + private String attributeName; + + @Override + public void setContext(String tagName, String attributeName) { + if (tagName != null && "script".equals(tagName.toLowerCase(Locale.ROOT))) { + throw new IllegalStateException("Unexpected JavaScript escaping context " + + tagName + "/" + attributeName + + " — controlled templates must not create one"); + } + if (attributeName != null + && attributeName.toLowerCase(Locale.ROOT).startsWith("on")) { + throw new IllegalStateException("Unexpected JavaScript escaping context " + + tagName + "/" + attributeName + + " — controlled templates must not create one"); + } + this.tagName = tagName; + this.attributeName = attributeName; + } + + @Override + public void writeUserContent(String value) { + if (value != null) { + writeContent(escape(value)); + } + } + + /** + * Escapes exactly {@code & < > " '} to {@code & < > " '}; + * every other character (including BMP >= U+0100) passes through untouched. + */ + public static String escape(String value) { + StringBuilder sb = null; + for (int i = 0; i < value.length(); i++) { + char c = value.charAt(i); + String replacement = switch (c) { + case '&' -> "&"; + case '<' -> "<"; + case '>' -> ">"; + case '"' -> """; + case '\'' -> "'"; + default -> null; + }; + if (replacement == null) { + if (sb != null) { + sb.append(c); + } + } else { + if (sb == null) { + sb = new StringBuilder(value.length() + 16); + sb.append(value, 0, i); + } + sb.append(replacement); + } + } + return sb == null ? value : sb.toString(); + } +} diff --git a/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/model/Models.java b/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/model/Models.java new file mode 100644 index 00000000..80da01a2 --- /dev/null +++ b/benchmarks/jvm/src/main/java/heddle/benchmarks/jvm/model/Models.java @@ -0,0 +1,652 @@ +package heddle.benchmarks.jvm.model; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import heddle.benchmarks.jvm.gate.Corpus; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +/** + * All pinned workload models. + * Static final instances materialized once (the {@code LoopContent.Shared} discipline); + * JavaBean-style POJOs because Thymeleaf's OGNL resolves {@code ${p.name}} through getters + * and JTE templates call the same getters explicitly. All string assembly is + * {@code String.format(Locale.ROOT, ...)} or plain ASCII/int concatenation - no locale, + * time, or randomness anywhere. Pinned data must match the golden corpus byte-for-byte. + * + * One rule governs every shape here: the model tier carries DATA only - derived + * display strings ({@code row-}, {@code MX-}, {@code note }, blurb sentences, + * media captions, display prices) are composed by the TEMPLATES as + * literal-plus-substitution, never pre-formatted model-side. Zero-padded identity names + * ({@code unit-%03d}, {@code item-%02d}, {@code Product %02d}) and the encoded-suite + * payloads stay model-side by design (row identity / untrusted input). + * + * This source file is saved UTF-8 without BOM (rows 4/8 carry em dash U+2014; row 12 and + * the encoded-loop comments carry Japanese text). + */ +public final class Models { + + private Models() { + } + + // ---- workload 2: trivial-substitution ---------------------------------------------- + + public static final class SubstitutionModel { + private final String title; + private final String sku; + private final int price; + private final String brand; + private final String category; + private final String availability; + private final String url; + private final String imageUrl; + private final String summary; + private final String rating; + + public SubstitutionModel(String title, String sku, int price, String brand, + String category, String availability, String url, + String imageUrl, String summary, String rating) { + this.title = title; + this.sku = sku; + this.price = price; + this.brand = brand; + this.category = category; + this.availability = availability; + this.url = url; + this.imageUrl = imageUrl; + this.summary = summary; + this.rating = rating; + } + + public String getTitle() { return title; } + public String getSku() { return sku; } + public int getPrice() { return price; } + public String getBrand() { return brand; } + public String getCategory() { return category; } + public String getAvailability() { return availability; } + public String getUrl() { return url; } + public String getImageUrl() { return imageUrl; } + public String getSummary() { return summary; } + public String getRating() { return rating; } + } + + public static final SubstitutionModel SUBSTITUTION = new SubstitutionModel( + "Heddle Handbook", "HB-2001", 4200, "Heddle Press", "Reference", "In stock", + "/catalog/handbook", "/img/handbook.png", + "A concise field guide to the engine.", "4.8"); + + // ---- workload 3: large-loop -------------------------------------------------------- + + /** + * The row carries ONLY the ordinal - the display name {@code row-} is composed + * by the templates as {@code row-} + the value substitution. + */ + public static final class LoopRow { + private final int value; + + public LoopRow(int value) { + this.value = value; + } + + public int getValue() { return value; } + } + + public static final List LOOP_ROWS = buildLoopRows(); + + private static List buildLoopRows() { + List rows = new ArrayList<>(5000); + for (int i = 0; i <= 4999; i++) { + rows.add(new LoopRow(i)); + } + return Collections.unmodifiableList(rows); + } + + // ---- workload 4: mixed-page -------------------------------------------------------- + + public static final class MixedProduct { + private final String name; + private final int skuNumber; + private final int price; + private final boolean onSale; + private final int batch; + + public MixedProduct(String name, int skuNumber, int price, boolean onSale, int batch) { + this.name = name; + this.skuNumber = skuNumber; + this.price = price; + this.onSale = onSale; + this.batch = batch; + } + + public String getName() { return name; } + /** Numeric SKU - the templates compose the display SKU {@code MX-}. */ + public int getSkuNumber() { return skuNumber; } + public int getPrice() { return price; } + public boolean isOnSale() { return onSale; } + /** Batch ordinal - the templates compose the blurb sentence around it. */ + public int getBatch() { return batch; } + } + + public static final class MixedModel { + private final String pageTitle; + private final String storeName; + private final String heroHeading; + private final String heroTagline; + private final boolean showBanner; + private final String bannerText; + private final boolean showDebugPanel; + private final String footerNote; + private final int year; + private final String supportEmail; + private final List products; + + public MixedModel(String pageTitle, String storeName, String heroHeading, + String heroTagline, boolean showBanner, String bannerText, + boolean showDebugPanel, String footerNote, int year, + String supportEmail, List products) { + this.pageTitle = pageTitle; + this.storeName = storeName; + this.heroHeading = heroHeading; + this.heroTagline = heroTagline; + this.showBanner = showBanner; + this.bannerText = bannerText; + this.showDebugPanel = showDebugPanel; + this.footerNote = footerNote; + this.year = year; + this.supportEmail = supportEmail; + this.products = products; + } + + public String getPageTitle() { return pageTitle; } + public String getStoreName() { return storeName; } + public String getHeroHeading() { return heroHeading; } + public String getHeroTagline() { return heroTagline; } + public boolean isShowBanner() { return showBanner; } + public String getBannerText() { return bannerText; } + public boolean isShowDebugPanel() { return showDebugPanel; } + public String getFooterNote() { return footerNote; } + public int getYear() { return year; } + public String getSupportEmail() { return supportEmail; } + public List getProducts() { return products; } + } + + public static final MixedModel MIXED = buildMixed(); + + private static MixedModel buildMixed() { + List products = new ArrayList<>(36); + for (int i = 1; i <= 36; i++) { + products.add(new MixedProduct( + String.format(Locale.ROOT, "Product %02d", i), + 1000 + i, + 950 + i * 7, + i % 3 == 0, + i)); + } + return new MixedModel( + "Mercantile - Catalog", "Mercantile", "Autumn hardware sale", + "Hand-picked tools, fair prices, shipped tomorrow.", true, + "Free shipping on orders over 60.", false, + "Prices include VAT where applicable.", 2026, + "support at mercantile.example", + Collections.unmodifiableList(products)); + } + + // ---- workload 5: conditional-heavy ------------------------------------------------- + + public static final class ConditionalRow { + private final String name; + private final int seq; + private final boolean bronze; + private final boolean silver; + private final boolean gold; + private final boolean hasNote; + private final boolean active; + + public ConditionalRow(String name, int seq, boolean bronze, boolean silver, + boolean gold, boolean hasNote, boolean active) { + this.name = name; + this.seq = seq; + this.bronze = bronze; + this.silver = silver; + this.gold = gold; + this.hasNote = hasNote; + this.active = active; + } + + public String getName() { return name; } + /** Row ordinal - the templates compose the note text {@code note }. */ + public int getSeq() { return seq; } + public boolean isBronze() { return bronze; } + public boolean isSilver() { return silver; } + public boolean isGold() { return gold; } + public boolean isHasNote() { return hasNote; } + public boolean isActive() { return active; } + } + + public static final List CONDITIONAL_ROWS = buildConditionalRows(); + + private static List buildConditionalRows() { + List rows = new ArrayList<>(200); + for (int i = 0; i <= 199; i++) { + rows.add(new ConditionalRow( + String.format(Locale.ROOT, "unit-%03d", i), + i, + i % 4 == 0, i % 4 == 1, i % 4 == 2, + i % 2 == 0, i % 5 != 0)); + } + return Collections.unmodifiableList(rows); + } + + // ---- workload 6: fragment-heavy ---------------------------------------------------- + + /** + * 48 rows of four dispatched fragment kinds (12 each) with one level of + * nesting (the card fragment renders badge + price from {@link FragmentPromo}). The + * model carries DATA only - the media caption ({@code Caption for } + name), image src + * ({@code /img/} + name + {@code .jpg}) and display price (price + {@code .99}) are + * composed by the templates. + */ + public static final class FragmentRow { + private final String kind; + private final boolean tile; + private final boolean card; + private final boolean media; + private final boolean stat; + private final String name; + private final int value; + private final String badge; + private final int delta; + private final FragmentPromo promo; + + public FragmentRow(String kind, boolean tile, boolean card, boolean media, + boolean stat, String name, int value, String badge, int delta, + FragmentPromo promo) { + this.kind = kind; + this.tile = tile; + this.card = card; + this.media = media; + this.stat = stat; + this.name = name; + this.value = value; + this.badge = badge; + this.delta = delta; + this.promo = promo; + } + + /** Informational; engines dispatch on the booleans below, never on this string. */ + public String getKind() { return kind; } + public boolean isTile() { return tile; } + public boolean isCard() { return card; } + public boolean isMedia() { return media; } + public boolean isStat() { return stat; } + public String getName() { return name; } + public int getValue() { return value; } + public String getBadge() { return badge; } + /** Stat rows render it. */ + public int getDelta() { return delta; } + /** The nesting level: the card fragment renders badge + price from it. Present on + * every row so no engine needs a null guard. */ + public FragmentPromo getPromo() { return promo; } + } + + public static final class FragmentPromo { + private final String label; + private final int price; + + public FragmentPromo(String label, int price) { + this.label = label; + this.price = price; + } + + public String getLabel() { return label; } + /** Whole-currency units only; the templates compose the display price + * ({@code .99}) - formatting is rendering work, not model work. */ + public int getPrice() { return price; } + } + + public static final List FRAGMENT_ROWS = buildFragmentRows(); + + private static List buildFragmentRows() { + String[] kinds = {"tile", "card", "media", "stat"}; + String[] badges = {"new", "hot", "sale", "std"}; + List rows = new ArrayList<>(48); + for (int i = 0; i <= 47; i++) { + String kind = kinds[i % 4]; + String badge = badges[i % 4]; + rows.add(new FragmentRow( + kind, + "tile".equals(kind), "card".equals(kind), + "media".equals(kind), "stat".equals(kind), + String.format(Locale.ROOT, "item-%02d", i), + i * 11, + badge, + i % 7 - 3, + new FragmentPromo(badge, 9 + i))); + } + return Collections.unmodifiableList(rows); + } + + // ---- workload 7: fortunes-encoded -------------------------------------------------- + + public static final class FortuneRow { + private final int id; + private final String message; + + public FortuneRow(int id, String message) { + this.id = id; + this.message = message; + } + + public int getId() { return id; } + public String getMessage() { return message; } + } + + /** + * The 12 pinned fortune rows, byte-for-byte across every ecosystem: row 1 writes + * {@code 4.33e67} (no {@code +}); rows 4/8 carry em dash U+2014; row 11 is the exact + * TechEmpower XSS payload; row 12 the Japanese string. + */ + public static final List FORTUNE_ROWS = List.of( + new FortuneRow(1, "A bad random number generator: 1, 1, 1, 1, 1, 4.33e67, 1, 1, 1"), + new FortuneRow(2, "A computer program does what you tell it to do, not what you want it to do."), + new FortuneRow(3, "A computer scientist is someone who fixes things that aren't broken."), + new FortuneRow(4, "A list is only as strong as its weakest link. — Donald Knuth"), + new FortuneRow(5, "After enough decimal places, nobody gives a damn."), + new FortuneRow(6, "Any program that runs right is obsolete."), + new FortuneRow(7, "Computers make very fast, very accurate mistakes."), + new FortuneRow(8, "Emacs is a nice operating system, but I prefer UNIX. — Tom Christiansen"), + new FortuneRow(9, "Feature: A bug with seniority."), + new FortuneRow(10, "fortune: No such file or directory"), + new FortuneRow(11, ""), + new FortuneRow(12, "フレームワークのベンチマーク")); + + // ---- workload 8: encoded-loop ------------------------------------------------------ + + public static final class EncodedLoopRow { + private final String tag; + private final String name; + private final String comment; + + public EncodedLoopRow(String tag, String name, String comment) { + this.tag = tag; + this.name = name; + this.comment = comment; + } + + public String getTag() { return tag; } + public String getName() { return name; } + public String getComment() { return comment; } + } + + public static final List ENCODED_ITEMS = buildEncodedItems(); + + private static List buildEncodedItems() { + List rows = new ArrayList<>(5000); + for (int i = 0; i <= 4999; i++) { + rows.add(new EncodedLoopRow( + "tag-" + i + "&'" + (i % 7) + "'", + "item <" + i + "> & \"co\"", + "'q' & \"d\" こんにちは " + i)); + } + return Collections.unmodifiableList(rows); + } + + // ---- workload 1: composed-page ----------------------------------------------------- + + /** + * Composed-page model: pure structured navigation and NOTHING else - every fragment + * of literal page text lives in the templates. {@code ComposedModel} stays exactly + * {@code { nav }}, mirroring the model shape every other ecosystem pins. + */ + public static final class ComposedModel { + private final NavModel nav; + + public ComposedModel(NavModel nav) { + this.nav = nav; + } + + public NavModel getNav() { return nav; } + } + + /** Two mega menus (wholesale, retail) and four footer columns. */ + public static final class NavModel { + private final List menus; + private final List footerColumns; + + public NavModel(List menus, List footerColumns) { + this.menus = menus; + this.footerColumns = footerColumns; + } + + public List getMenus() { return menus; } + public List getFooterColumns() { return footerColumns; } + } + + public static final class MegaMenu { + private final List tabs; + + public MegaMenu(List tabs) { + this.tabs = tabs; + } + + public List getTabs() { return tabs; } + } + + public static final class MenuTab { + private final String label; + private final String href; + private final String css; + private final boolean hasDropdown; + private final String dropdownCss; + private final List columns; + + public MenuTab(String label, String href, String css, boolean hasDropdown, + String dropdownCss, List columns) { + this.label = label; + this.href = href; + this.css = css; + this.hasDropdown = hasDropdown; + this.dropdownCss = dropdownCss; + this.columns = columns; + } + + public String getLabel() { return label; } + public String getHref() { return href; } + public String getCss() { return css; } + /** Precomputed boolean - no engine evaluates a collection test. */ + public boolean isHasDropdown() { return hasDropdown; } + public String getDropdownCss() { return dropdownCss; } + public List getColumns() { return columns; } + } + + public static final class NavColumn { + private final List sections; + + public NavColumn(List sections) { + this.sections = sections; + } + + public List getSections() { return sections; } + } + + public static final class NavSection { + private final String title; + private final String href; + private final boolean titleLinked; + private final List links; + + public NavSection(String title, String href, boolean titleLinked, List links) { + this.title = title; + this.href = href; + this.titleLinked = titleLinked; + this.links = links; + } + + public String getTitle() { return title; } + public String getHref() { return href; } + /** Precomputed: the title renders as a link exactly when the fixture linked it. */ + public boolean isTitleLinked() { return titleLinked; } + public List getLinks() { return links; } + } + + public static final class NavLink { + private final String label; + private final String href; + + public NavLink(String label, String href) { + this.label = label; + this.href = href; + } + + public String getLabel() { return label; } + public String getHref() { return href; } + } + + /** + * Loaded once at class initialization (lazy holder = static init on first touch) from + * {@code GoldenCorpus/fixtures/composed-page/nav.json} - the single source of truth + * every non-.NET ecosystem loads from - resolved through the SAME corpus-dir + * resolution the gate uses ({@link Corpus#resolveRoot()}, honoring + * {@code -Dheddle.corpus}). Parsed with the already-pinned Jackson dependency (the + * manifest reader's mapper); a load or schema failure fails fast. + */ + public static ComposedModel composed() { + return ComposedHolder.MODEL; + } + + private static final class ComposedHolder { + static final ComposedModel MODEL = loadComposed(); + } + + private static ComposedModel loadComposed() { + Path path = Corpus.resolveRoot() + .resolve("fixtures").resolve("composed-page").resolve("nav.json"); + JsonNode root; + try { + root = new ObjectMapper().readTree(Files.readAllBytes(path)); + } catch (IOException e) { + throw new Corpus.CorpusException( + "Cannot read composed-page nav fixture " + path + + " (set -Dheddle.corpus=...)", e); + } + List menus = new ArrayList<>(); + for (JsonNode menu : array(root, "menus")) { + List tabs = new ArrayList<>(); + for (JsonNode tab : array(menu, "tabs")) { + tabs.add(new MenuTab( + text(tab, "label"), + text(tab, "href"), + text(tab, "css"), + bool(tab, "has_dropdown"), + text(tab, "dropdown_css"), + columns(array(tab, "columns")))); + } + menus.add(new MegaMenu(Collections.unmodifiableList(tabs))); + } + NavModel nav = new NavModel( + Collections.unmodifiableList(menus), + columns(array(root, "footer_columns"))); + assertRule4(nav); + return new ComposedModel(nav); + } + + private static List columns(JsonNode columnsNode) { + List columns = new ArrayList<>(); + for (JsonNode column : columnsNode) { + List sections = new ArrayList<>(); + for (JsonNode section : array(column, "sections")) { + List links = new ArrayList<>(); + for (JsonNode link : array(section, "links")) { + links.add(new NavLink(text(link, "label"), text(link, "href"))); + } + sections.add(new NavSection( + text(section, "title"), + text(section, "href"), + bool(section, "title_linked"), + Collections.unmodifiableList(links))); + } + columns.add(new NavColumn(Collections.unmodifiableList(sections))); + } + return Collections.unmodifiableList(columns); + } + + private static JsonNode field(JsonNode node, String name) { + JsonNode value = node.get(name); + if (value == null || value.isNull()) { + throw new IllegalStateException("nav.json: missing field '" + name + "'"); + } + return value; + } + + private static JsonNode array(JsonNode node, String name) { + JsonNode value = field(node, name); + if (!value.isArray()) { + throw new IllegalStateException("nav.json: field '" + name + "' is not an array"); + } + return value; + } + + private static String text(JsonNode node, String name) { + JsonNode value = field(node, name); + if (!value.isTextual()) { + throw new IllegalStateException("nav.json: field '" + name + "' is not a string"); + } + return value.asText(); + } + + private static boolean bool(JsonNode node, String name) { + JsonNode value = field(node, name); + if (!value.isBoolean()) { + throw new IllegalStateException("nav.json: field '" + name + "' is not a boolean"); + } + return value.asBoolean(); + } + + /** + * The nav-data character rule, asserted the way {@code NavData}'s static constructor + * asserts it: every nav text value is printable ASCII with none of {@code & < > " '}, + * so raw and would-be-escaped renderings coincide and no default-escaping engine can + * double-escape. + */ + private static void assertRule4(NavModel nav) { + for (MegaMenu menu : nav.getMenus()) { + for (MenuTab tab : menu.getTabs()) { + rule4(tab.getLabel()); + rule4(tab.getHref()); + rule4(tab.getCss()); + rule4(tab.getDropdownCss()); + rule4Columns(tab.getColumns()); + } + } + rule4Columns(nav.getFooterColumns()); + } + + private static void rule4Columns(List columns) { + for (NavColumn column : columns) { + for (NavSection section : column.getSections()) { + rule4(section.getTitle()); + rule4(section.getHref()); + for (NavLink link : section.getLinks()) { + rule4(link.getLabel()); + rule4(link.getHref()); + } + } + } + } + + private static void rule4(String value) { + for (int i = 0; i < value.length(); i++) { + char c = value.charAt(i); + if (c < 0x20 || c > 0x7E || c == '&' || c == '<' || c == '>' || c == '"' || c == '\'') { + throw new IllegalStateException("nav.json: value violates the nav-data" + + " character rule (printable ASCII, none of &<>\"'): \"" + value + "\""); + } + } + } +} diff --git a/benchmarks/jvm/src/main/jte-html/.gitkeep b/benchmarks/jvm/src/main/jte-html/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/jvm/src/main/jte-html/controlled/encoded-loop.jte b/benchmarks/jvm/src/main/jte-html/controlled/encoded-loop.jte new file mode 100644 index 00000000..4b0c8492 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-html/controlled/encoded-loop.jte @@ -0,0 +1,2 @@ +@param java.util.List items +@for(var item : items)@endfor
      ${item.getName()}${item.getComment()}
      diff --git a/benchmarks/jvm/src/main/jte-html/controlled/fortunes-encoded.jte b/benchmarks/jvm/src/main/jte-html/controlled/fortunes-encoded.jte new file mode 100644 index 00000000..c197eccf --- /dev/null +++ b/benchmarks/jvm/src/main/jte-html/controlled/fortunes-encoded.jte @@ -0,0 +1,2 @@ +@param java.util.List rows +Fortunes@for(var r : rows)@endfor
      idmessage
      ${r.getId()}${r.getMessage()}
      diff --git a/benchmarks/jvm/src/main/jte-html/idiomatic/encoded-loop.jte b/benchmarks/jvm/src/main/jte-html/idiomatic/encoded-loop.jte new file mode 100644 index 00000000..3ba2d3f2 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-html/idiomatic/encoded-loop.jte @@ -0,0 +1,16 @@ +@param java.util.List items +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (loops: @for, output expressions) + https://jte.gg/html-rendering/ (ContentType.Html, stock OWASP-compliant output escaping, + context-aware attribute escaping) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> + + @for(var item : items) + + + + + @endfor +
      ${item.getName()}${item.getComment()}
      diff --git a/benchmarks/jvm/src/main/jte-html/idiomatic/fortunes-encoded.jte b/benchmarks/jvm/src/main/jte-html/idiomatic/fortunes-encoded.jte new file mode 100644 index 00000000..bd91cf94 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-html/idiomatic/fortunes-encoded.jte @@ -0,0 +1,27 @@ +@param java.util.List rows +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (loops: @for, output expressions) + https://jte.gg/html-rendering/ (ContentType.Html, stock OWASP-compliant output escaping) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> + + + +Fortunes + + + + + + + + @for(var r : rows) + + + + + @endfor +
      idmessage
      ${r.getId()}${r.getMessage()}
      + + diff --git a/benchmarks/jvm/src/main/jte-plain/.gitkeep b/benchmarks/jvm/src/main/jte-plain/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/composed-page.jte b/benchmarks/jvm/src/main/jte-plain/controlled/composed-page.jte new file mode 100644 index 00000000..b850c527 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/composed-page.jte @@ -0,0 +1,12 @@ +@param heddle.benchmarks.jvm.model.Models.ComposedModel m +@template.controlled.shared.layout(m, bodySlot = @`
      +
      +
      +
      +
      + + + +
      +
      +
      `) diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/conditional-heavy.jte b/benchmarks/jvm/src/main/jte-plain/controlled/conditional-heavy.jte new file mode 100644 index 00000000..65dbb022 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/conditional-heavy.jte @@ -0,0 +1,2 @@ +@param java.util.List rows +
        @for(var r : rows)
      • @if(r.isBronze())bronze@elseif(r.isSilver())silver@elseif(r.isGold())gold@elseplatinum@endif${r.getName()}@if(r.isHasNote())note ${r.getSeq()}@endif@if(r.isActive())active@endif
      • @endfor
      diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/fragment-heavy.jte b/benchmarks/jvm/src/main/jte-plain/controlled/fragment-heavy.jte new file mode 100644 index 00000000..786a7bec --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/fragment-heavy.jte @@ -0,0 +1,2 @@ +@param java.util.List items +
      @for(var item : items)@if(item.isTile())@template.controlled.shared.tile(item)@elseif(item.isCard())@template.controlled.shared.card(item)@elseif(item.isMedia())@template.controlled.shared.mediarow(item)@else@template.controlled.shared.stat(item)@endif@endfor
      diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/large-loop.jte b/benchmarks/jvm/src/main/jte-plain/controlled/large-loop.jte new file mode 100644 index 00000000..78d5fef4 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/large-loop.jte @@ -0,0 +1,2 @@ +@param java.util.List items +@for(var r : items)row-${r.getValue()}${r.getValue()}@endfor diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/mixed-page.jte b/benchmarks/jvm/src/main/jte-plain/controlled/mixed-page.jte new file mode 100644 index 00000000..cc4b81bc --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/mixed-page.jte @@ -0,0 +1,30 @@ +@param heddle.benchmarks.jvm.model.Models.MixedModel m + + + + +${m.getPageTitle()} + + + +
      +

      ${m.getStoreName()}

      + +
      +
      +@if(m.isShowBanner())@endif +
      +

      ${m.getHeroHeading()}

      +

      ${m.getHeroTagline()}

      +
      +
      +@for(var p : m.getProducts())

      ${p.getName()}

      MX-${p.getSkuNumber()}

      ${p.getPrice()}

      @if(p.isOnSale())

      On sale

      @endif

      A dependable workshop staple from batch ${p.getBatch()}, checked for daily use and backed by our lifetime guarantee.

      @endfor +
      +@if(m.isShowDebugPanel())
      debug
      @endif +
      +
      +

      ${m.getFooterNote()}

      +

      ${m.getStoreName()} ${m.getYear()} ${m.getSupportEmail()}

      +
      + + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/alertbelow.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/alertbelow.jte new file mode 100644 index 00000000..0eb9cc84 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/alertbelow.jte @@ -0,0 +1 @@ +<%-- pinned-empty chrome fragment (alert_below) --%> diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/alerttop.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/alerttop.jte new file mode 100644 index 00000000..d889f879 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/alerttop.jte @@ -0,0 +1 @@ +
      holiday shipping
      diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/assetsscripts.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/assetsscripts.jte new file mode 100644 index 00000000..bf801bb9 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/assetsscripts.jte @@ -0,0 +1 @@ + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/assetsstyles.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/assetsstyles.jte new file mode 100644 index 00000000..28df0356 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/assetsstyles.jte @@ -0,0 +1 @@ + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/badge.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/badge.jte new file mode 100644 index 00000000..c9dd8673 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/badge.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentPromo promo +${promo.getLabel()} diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/bodyendscripts.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/bodyendscripts.jte new file mode 100644 index 00000000..51c5f27e --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/bodyendscripts.jte @@ -0,0 +1 @@ + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/bodyscripts.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/bodyscripts.jte new file mode 100644 index 00000000..7bcf90f9 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/bodyscripts.jte @@ -0,0 +1 @@ + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/card.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/card.jte new file mode 100644 index 00000000..edb343dc --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/card.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentRow row +

      ${row.getName()}

      @template.controlled.shared.badge(row.getPromo())@template.controlled.shared.price(row.getPromo())

      ${row.getValue()}

      diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/customstyles.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/customstyles.jte new file mode 100644 index 00000000..c03f73c5 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/customstyles.jte @@ -0,0 +1 @@ +/* CSS Comment Test */ diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/headscripts.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/headscripts.jte new file mode 100644 index 00000000..35f0ac9a --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/headscripts.jte @@ -0,0 +1 @@ + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/layout.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/layout.jte new file mode 100644 index 00000000..3b476065 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/layout.jte @@ -0,0 +1,130 @@ +@param heddle.benchmarks.jvm.model.Models.ComposedModel m +@param gg.jte.Content bodySlot + + + + + + + + + + Title + + + + + + + + + @template.controlled.shared.assetsstyles() + + @template.controlled.shared.headscripts() + + + @template.controlled.shared.bodyscripts() +
      +
      + +
      +
      +
      +
      + @template.controlled.shared.alerttop() +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + @for(var menu : m.getNav().getMenus())@template.controlled.shared.megamenu(menu)@endfor +
      +
      +
      + @template.controlled.shared.alertbelow() +
      +
      + ${bodySlot} +
      +
      +
      +
      +
      + +
      +
      + @template.controlled.shared.assetsscripts() + + + + @template.controlled.shared.bodyendscripts() + + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/mediarow.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/mediarow.jte new file mode 100644 index 00000000..6a05a6a6 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/mediarow.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentRow row +
      ${row.getName()}

      ${row.getName()}

      Caption for ${row.getName()}

      diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/megamenu.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/megamenu.jte new file mode 100644 index 00000000..703a93fa --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/megamenu.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.MegaMenu menu +
        @for(var tab : menu.getTabs())
      • ${tab.getLabel()}@if(tab.isHasDropdown())
        @for(var col : tab.getColumns())@template.controlled.shared.navcolumn(col)@endfor
        @endif
      • @endfor
      diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/navcolumn.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/navcolumn.jte new file mode 100644 index 00000000..a03c6f96 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/navcolumn.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.NavColumn col + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/navlink.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/navlink.jte new file mode 100644 index 00000000..e4f536b9 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/navlink.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.NavLink link + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/navsection.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/navsection.jte new file mode 100644 index 00000000..4ffe947e --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/navsection.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.NavSection section + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/price.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/price.jte new file mode 100644 index 00000000..2adc5015 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/price.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentPromo promo +

      ${promo.getPrice()}.99

      diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/secondaryretailmenu.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/secondaryretailmenu.jte new file mode 100644 index 00000000..6c6147b8 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/secondaryretailmenu.jte @@ -0,0 +1,116 @@ + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/secondarywholesalemenu.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/secondarywholesalemenu.jte new file mode 100644 index 00000000..b80f8830 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/secondarywholesalemenu.jte @@ -0,0 +1,138 @@ + diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/stat.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/stat.jte new file mode 100644 index 00000000..3ed42a9e --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/stat.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentRow row +
      ${row.getName()}${row.getValue()}${row.getDelta()}
      diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/shared/tile.jte b/benchmarks/jvm/src/main/jte-plain/controlled/shared/tile.jte new file mode 100644 index 00000000..91570940 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/shared/tile.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentRow row +

      ${row.getName()}

      ${row.getValue()}

      ${row.getBadge()}
      diff --git a/benchmarks/jvm/src/main/jte-plain/controlled/trivial-substitution.jte b/benchmarks/jvm/src/main/jte-plain/controlled/trivial-substitution.jte new file mode 100644 index 00000000..acaab2c4 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/controlled/trivial-substitution.jte @@ -0,0 +1,2 @@ +@param heddle.benchmarks.jvm.model.Models.SubstitutionModel m +

      ${m.getTitle()}

      ${m.getSku()}

      ${m.getPrice()}

      ${m.getBrand()}

      ${m.getCategory()}

      ${m.getAvailability()}

      ${m.getSummary()}

      ${m.getRating()}

      diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/composed-page.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/composed-page.jte new file mode 100644 index 00000000..06bb8b26 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/composed-page.jte @@ -0,0 +1,26 @@ +@param heddle.benchmarks.jvm.model.Models.ComposedModel m +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/#content (content blocks: `bodySlot = @`...`` passes the page + body as a gg.jte.Content parameter — the native jte layout mechanism) + https://jte.gg/syntax/ (template calls: @template.idiomatic.shared.layout) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Native full-page layout composition: the page + calls the layout template with the slider body as a live content slot. Both tracks + carry the SAME slider body — the verifier's removed-segment calibration pin is the + slider, so an empty body fails. +--%> +@template.idiomatic.shared.layout(m, bodySlot = @` +
      +
      +
      +
      +
      + + + +
      +
      +
      +`) diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/conditional-heavy.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/conditional-heavy.jte new file mode 100644 index 00000000..284084b1 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/conditional-heavy.jte @@ -0,0 +1,28 @@ +@param java.util.List rows +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (conditions: @if/@elseif/@else/@endif, loops: @for) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> +
        + @for(var r : rows) +
      • + @if(r.isBronze()) + bronze + @elseif(r.isSilver()) + silver + @elseif(r.isGold()) + gold + @else + platinum + @endif + ${r.getName()} + @if(r.isHasNote()) + note ${r.getSeq()} + @endif + @if(r.isActive()) + active + @endif +
      • + @endfor +
      diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/fragment-heavy.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/fragment-heavy.jte new file mode 100644 index 00000000..95d4af65 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/fragment-heavy.jte @@ -0,0 +1,23 @@ +@param java.util.List items +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (conditions: @if/@elseif/@else — jte's dispatch construct; + template calls: @template.idiomatic.shared.tile etc.; loops: @for) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Four dispatched fragment kinds selected by a + boolean @if/@elseif chain per row; the card fragment nests badge + price (one level). +--%> +
      + @for(var item : items) + @if(item.isTile()) + @template.idiomatic.shared.tile(item) + @elseif(item.isCard()) + @template.idiomatic.shared.card(item) + @elseif(item.isMedia()) + @template.idiomatic.shared.mediarow(item) + @else + @template.idiomatic.shared.stat(item) + @endif + @endfor +
      diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/large-loop.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/large-loop.jte new file mode 100644 index 00000000..21cddcff --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/large-loop.jte @@ -0,0 +1,12 @@ +@param java.util.List items +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (loops: @for/@endfor, output expressions) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> +@for(var r : items) + + row-${r.getValue()} + ${r.getValue()} + +@endfor diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/mixed-page.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/mixed-page.jte new file mode 100644 index 00000000..7bab8c39 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/mixed-page.jte @@ -0,0 +1,49 @@ +@param heddle.benchmarks.jvm.model.Models.MixedModel m +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (conditions: @if/@endif, loops: @for, output expressions) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> + + + + +${m.getPageTitle()} + + + +
      +

      ${m.getStoreName()}

      + +
      +
      + @if(m.isShowBanner()) + + @endif +
      +

      ${m.getHeroHeading()}

      +

      ${m.getHeroTagline()}

      +
      +
      + @for(var p : m.getProducts()) +
      +

      ${p.getName()}

      +

      MX-${p.getSkuNumber()}

      +

      ${p.getPrice()}

      + @if(p.isOnSale()) +

      On sale

      + @endif +

      A dependable workshop staple from batch ${p.getBatch()}, checked for daily use and backed by our lifetime guarantee.

      +
      + @endfor +
      + @if(m.isShowDebugPanel()) +
      debug
      + @endif +
      +
      +

      ${m.getFooterNote()}

      +

      ${m.getStoreName()} ${m.getYear()} ${m.getSupportEmail()}

      +
      + + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/alertbelow.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/alertbelow.jte new file mode 100644 index 00000000..53f66468 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/alertbelow.jte @@ -0,0 +1,10 @@ +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (plain text templates, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Chrome fragment 'alert_below' transcribed from the Heddle reference + chrome-fragment library: inert literal page text lives in the template tier, + one sub-template per named fragment. +--%> +<%-- pinned empty --%> diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/alerttop.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/alerttop.jte new file mode 100644 index 00000000..18e70928 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/alerttop.jte @@ -0,0 +1,10 @@ +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (plain text templates, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Chrome fragment 'alert_top' transcribed from the Heddle reference + chrome-fragment library: inert literal page text lives in the template tier, + one sub-template per named fragment. +--%> +
      holiday shipping
      diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/assetsscripts.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/assetsscripts.jte new file mode 100644 index 00000000..8bf80468 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/assetsscripts.jte @@ -0,0 +1,10 @@ +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (plain text templates, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Chrome fragment 'assets_scripts' transcribed from the Heddle reference + chrome-fragment library: inert literal page text lives in the template tier, + one sub-template per named fragment. +--%> + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/assetsstyles.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/assetsstyles.jte new file mode 100644 index 00000000..05cd670e --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/assetsstyles.jte @@ -0,0 +1,10 @@ +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (plain text templates, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Chrome fragment 'assets_styles' transcribed from the Heddle reference + chrome-fragment library: inert literal page text lives in the template tier, + one sub-template per named fragment. +--%> + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/badge.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/badge.jte new file mode 100644 index 00000000..af70c99f --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/badge.jte @@ -0,0 +1,7 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentPromo promo +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (params, output expressions) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> +${promo.getLabel()} diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/bodyendscripts.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/bodyendscripts.jte new file mode 100644 index 00000000..ef0dd976 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/bodyendscripts.jte @@ -0,0 +1,10 @@ +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (plain text templates, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Chrome fragment 'body_end_scripts' transcribed from the Heddle reference + chrome-fragment library: inert literal page text lives in the template tier, + one sub-template per named fragment. +--%> + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/bodyscripts.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/bodyscripts.jte new file mode 100644 index 00000000..89f43234 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/bodyscripts.jte @@ -0,0 +1,10 @@ +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (plain text templates, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Chrome fragment 'body_scripts' transcribed from the Heddle reference + chrome-fragment library: inert literal page text lives in the template tier, + one sub-template per named fragment. +--%> + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/card.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/card.jte new file mode 100644 index 00000000..43c0901d --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/card.jte @@ -0,0 +1,13 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentRow row +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (template calls: @template.idiomatic.shared.badge / .price — the one + nesting level, passing the row's promo down) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> +
      +

      ${row.getName()}

      + @template.idiomatic.shared.badge(row.getPromo()) + @template.idiomatic.shared.price(row.getPromo()) +

      ${row.getValue()}

      +
      diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/customstyles.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/customstyles.jte new file mode 100644 index 00000000..2eb05900 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/customstyles.jte @@ -0,0 +1,10 @@ +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (plain text templates, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Chrome fragment 'custom_styles' transcribed from the Heddle reference + chrome-fragment library: inert literal page text lives in the template tier, + one sub-template per named fragment. +--%> +/* CSS Comment Test */ diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/headscripts.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/headscripts.jte new file mode 100644 index 00000000..0453f7ab --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/headscripts.jte @@ -0,0 +1,10 @@ +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (plain text templates, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Chrome fragment 'head_scripts' transcribed from the Heddle reference + chrome-fragment library: inert literal page text lives in the template tier, + one sub-template per named fragment. +--%> + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/layout.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/layout.jte new file mode 100644 index 00000000..f334f4c2 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/layout.jte @@ -0,0 +1,143 @@ +@param heddle.benchmarks.jvm.model.Models.ComposedModel m +@param gg.jte.Content bodySlot +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/#content (gg.jte.Content parameters — the native jte layout + mechanism: the page passes its body as a content block, rendered at ${bodySlot}) + https://jte.gg/syntax/ (template calls: @template, loops: @for, conditions: @if) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Native full-page layout: the chrome is + literal template text transcribed from the Heddle reference layout; inert chrome + fragments are per-fragment sub-templates; the two mega menus and the footer columns + render from the structured nav model through nested sub-templates + (megamenu -> navcolumn -> navsection -> navlink); the live body slot is ${bodySlot}. +--%> + + + + + + + + + + Title + + + + + + + + + @template.idiomatic.shared.assetsstyles() + + @template.idiomatic.shared.headscripts() + + + @template.idiomatic.shared.bodyscripts() +
      +
      + +
      +
      +
      +
      + @template.idiomatic.shared.alerttop() +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + @for(var menu : m.getNav().getMenus())@template.idiomatic.shared.megamenu(menu)@endfor +
      +
      +
      + @template.idiomatic.shared.alertbelow() +
      +
      + ${bodySlot} +
      +
      +
      +
      +
      + +
      +
      + @template.idiomatic.shared.assetsscripts() + + + + @template.idiomatic.shared.bodyendscripts() + + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/mediarow.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/mediarow.jte new file mode 100644 index 00000000..17f64a01 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/mediarow.jte @@ -0,0 +1,16 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentRow row +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (params, output expressions) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Image src (`/img/` + name + `.jpg`) and caption (`Caption for ` + name) are + composed by the template as literal-plus-substitution. +--%> +
      + ${row.getName()} +
      +

      ${row.getName()}

      +

      Caption for ${row.getName()}

      +
      +
      diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/megamenu.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/megamenu.jte new file mode 100644 index 00000000..51af341e --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/megamenu.jte @@ -0,0 +1,22 @@ +@param heddle.benchmarks.jvm.model.Models.MegaMenu menu +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (loops: @for, conditions: @if, template calls, output expressions) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> +
      +
        + @for(var tab : menu.getTabs()) +
      • + ${tab.getLabel()} + @if(tab.isHasDropdown()) +
        + @for(var col : tab.getColumns()) + @template.idiomatic.shared.navcolumn(col) + @endfor +
        + @endif +
      • + @endfor +
      +
      diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/navcolumn.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/navcolumn.jte new file mode 100644 index 00000000..8c5e8860 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/navcolumn.jte @@ -0,0 +1,11 @@ +@param heddle.benchmarks.jvm.model.Models.NavColumn col +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (loops: @for, template calls: @template.idiomatic.shared.navsection) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/navlink.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/navlink.jte new file mode 100644 index 00000000..87e2e070 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/navlink.jte @@ -0,0 +1,7 @@ +@param heddle.benchmarks.jvm.model.Models.NavLink link +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (params, output expressions) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/navsection.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/navsection.jte new file mode 100644 index 00000000..9d2f5910 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/navsection.jte @@ -0,0 +1,18 @@ +@param heddle.benchmarks.jvm.model.Models.NavSection section +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (conditions: @if/@else/@endif, loops: @for, template calls) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/price.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/price.jte new file mode 100644 index 00000000..1f06d986 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/price.jte @@ -0,0 +1,10 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentPromo promo +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (params, output expressions) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + The display price is composed by the template — the int price plus the literal + `.99` — never pre-formatted model-side. +--%> +

      ${promo.getPrice()}.99

      diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/secondaryretailmenu.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/secondaryretailmenu.jte new file mode 100644 index 00000000..3ac97901 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/secondaryretailmenu.jte @@ -0,0 +1,125 @@ +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (plain text templates, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Chrome fragment 'secondary_retail_menu' transcribed from the Heddle reference + chrome-fragment library: inert literal page text lives in the template tier, + one sub-template per named fragment. +--%> + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/secondarywholesalemenu.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/secondarywholesalemenu.jte new file mode 100644 index 00000000..a7f57bf7 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/secondarywholesalemenu.jte @@ -0,0 +1,147 @@ +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (plain text templates, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) + + Chrome fragment 'secondary_wholesale_menu' transcribed from the Heddle reference + chrome-fragment library: inert literal page text lives in the template tier, + one sub-template per named fragment. +--%> + diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/stat.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/stat.jte new file mode 100644 index 00000000..65b72084 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/stat.jte @@ -0,0 +1,11 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentRow row +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (params, output expressions) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> +
      + ${row.getName()} + ${row.getValue()} + ${row.getDelta()} +
      diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/tile.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/tile.jte new file mode 100644 index 00000000..d544b602 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/shared/tile.jte @@ -0,0 +1,11 @@ +@param heddle.benchmarks.jvm.model.Models.FragmentRow row +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (template calls: @template, params, output expressions) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> +
      +

      ${row.getName()}

      +

      ${row.getValue()}

      + ${row.getBadge()} +
      diff --git a/benchmarks/jvm/src/main/jte-plain/idiomatic/trivial-substitution.jte b/benchmarks/jvm/src/main/jte-plain/idiomatic/trivial-substitution.jte new file mode 100644 index 00000000..a03ce5e9 --- /dev/null +++ b/benchmarks/jvm/src/main/jte-plain/idiomatic/trivial-substitution.jte @@ -0,0 +1,19 @@ +@param heddle.benchmarks.jvm.model.Models.SubstitutionModel m +<%-- + Idiomatic jte authoring — official doc citations: + https://jte.gg/syntax/ (params, output expressions, comments) + https://jte.gg/pre-compiling/ (precompiled engine setup) +--%> +
      +

      ${m.getTitle()}

      +

      ${m.getSku()}

      +

      ${m.getPrice()}

      +

      ${m.getBrand()}

      +

      ${m.getCategory()}

      +

      ${m.getAvailability()}

      + + + +

      ${m.getSummary()}

      +

      ${m.getRating()}

      +
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/composed-page.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/composed-page.html new file mode 100644 index 00000000..039ecf3d --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/composed-page.html @@ -0,0 +1,15 @@ + + +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/conditional-heavy.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/conditional-heavy.html new file mode 100644 index 00000000..3af511e8 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/conditional-heavy.html @@ -0,0 +1 @@ +
      • bronzesilvergoldplatinum[(${r.name})]note [(${r.seq})]active
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/encoded-loop.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/encoded-loop.html new file mode 100644 index 00000000..0e822a8c --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/encoded-loop.html @@ -0,0 +1 @@ +
      [[${item.name}]][[${item.comment}]]
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/fortunes-encoded.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/fortunes-encoded.html new file mode 100644 index 00000000..bf536202 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/fortunes-encoded.html @@ -0,0 +1 @@ +Fortunes
      idmessage
      [[${r.id}]][[${r.message}]]
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/fragment-heavy.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/fragment-heavy.html new file mode 100644 index 00000000..b0769b5a --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/fragment-heavy.html @@ -0,0 +1 @@ +
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/large-loop.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/large-loop.html new file mode 100644 index 00000000..8ba29c61 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/large-loop.html @@ -0,0 +1 @@ +row-[(${r.value})][(${r.value})] diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/mixed-page.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/mixed-page.html new file mode 100644 index 00000000..3e66b969 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/mixed-page.html @@ -0,0 +1,29 @@ + + + + +[(${m.pageTitle})] + + + +
      +

      [(${m.storeName})]

      + +
      +
      + +
      +

      [(${m.heroHeading})]

      +

      [(${m.heroTagline})]

      +
      +
      +

      [(${p.name})]

      MX-[(${p.skuNumber})]

      [(${p.price})]

      On sale

      A dependable workshop staple from batch [(${p.batch})], checked for daily use and backed by our lifetime guarantee.

      +
      +
      debug
      +
      +
      +

      [(${m.footerNote})]

      +

      [(${m.storeName})] [(${m.year})] [(${m.supportEmail})]

      +
      + + diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/badge.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/badge.html new file mode 100644 index 00000000..56e23cc7 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/badge.html @@ -0,0 +1 @@ +[(${promo.label})] diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/card.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/card.html new file mode 100644 index 00000000..71dd2cef --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/card.html @@ -0,0 +1 @@ +

      [(${item.name})]

      [(${item.value})]

      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/chrome-fragments.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/chrome-fragments.html new file mode 100644 index 00000000..b7b4e155 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/chrome-fragments.html @@ -0,0 +1,266 @@ +
      holiday shipping
      + + + + + + + + + + + diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/layout.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/layout.html new file mode 100644 index 00000000..42c65d0a --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/layout.html @@ -0,0 +1,138 @@ + + Title + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + +
      +
      +
      +
      + +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + +
      +
      +
      + +
      +
      + +
      +
      +
      +
      +
      + +
      +
      + + + + + + + diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/media-row.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/media-row.html new file mode 100644 index 00000000..5b9cd221 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/media-row.html @@ -0,0 +1 @@ +

      [(${item.name})]

      Caption for [(${item.name})]

      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/price.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/price.html new file mode 100644 index 00000000..486748af --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/price.html @@ -0,0 +1 @@ +

      [(${promo.price})].99

      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/stat.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/stat.html new file mode 100644 index 00000000..38798305 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/stat.html @@ -0,0 +1 @@ +
      [(${item.name})][(${item.value})][(${item.delta})]
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/tile.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/tile.html new file mode 100644 index 00000000..f35100fb --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/shared/tile.html @@ -0,0 +1 @@ +

      [(${item.name})]

      [(${item.value})]

      [(${item.badge})]
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/controlled/trivial-substitution.html b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/trivial-substitution.html new file mode 100644 index 00000000..c624422c --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/controlled/trivial-substitution.html @@ -0,0 +1 @@ +

      [(${m.title})]

      [(${m.sku})]

      [(${m.price})]

      [(${m.brand})]

      [(${m.category})]

      [(${m.availability})]

      [(${m.summary})]

      [(${m.rating})]

      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/composed-page.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/composed-page.html new file mode 100644 index 00000000..e1aca417 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/composed-page.html @@ -0,0 +1,27 @@ + + + +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/conditional-heavy.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/conditional-heavy.html new file mode 100644 index 00000000..9f0559c2 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/conditional-heavy.html @@ -0,0 +1,20 @@ + +
        +
      • + bronze + silver + gold + platinum + unit name + note 0 + active +
      • +
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/encoded-loop.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/encoded-loop.html new file mode 100644 index 00000000..cd07eeda --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/encoded-loop.html @@ -0,0 +1,12 @@ + + + + + + +
      item namecomment
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/fortunes-encoded.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/fortunes-encoded.html new file mode 100644 index 00000000..8991dc8c --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/fortunes-encoded.html @@ -0,0 +1,24 @@ + + + + +Fortunes + + + + + + + + + + + +
      idmessage
      1fortune message
      + + diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/fragment-heavy.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/fragment-heavy.html new file mode 100644 index 00000000..8a6758d9 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/fragment-heavy.html @@ -0,0 +1,27 @@ + +
      + + +
      tile
      +
      + +
      card
      +
      + +
      media row
      +
      + +
      stat
      +
      +
      +
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/large-loop.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/large-loop.html new file mode 100644 index 00000000..ede2a729 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/large-loop.html @@ -0,0 +1,11 @@ + + + row-0 + 0 + diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/mixed-page.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/mixed-page.html new file mode 100644 index 00000000..cd2891d0 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/mixed-page.html @@ -0,0 +1,42 @@ + + + + + +Store - Catalog + + + +
      +

      Store

      + +
      +
      + +
      +

      Hero heading

      +

      Hero tagline

      +
      +
      +
      +

      Product name

      +

      MX-1000

      +

      0

      +

      On sale

      +

      Blurb

      +
      +
      +
      debug
      +
      +
      +

      Footer note

      +

      Store 2000 support

      +
      + + diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/badge.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/badge.html new file mode 100644 index 00000000..04f1aa2f --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/badge.html @@ -0,0 +1,7 @@ + +badge label diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/card.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/card.html new file mode 100644 index 00000000..820ad5e4 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/card.html @@ -0,0 +1,13 @@ + +
      +

      card name

      + promo badge +

      promo price

      +

      0

      +
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/chrome-fragments.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/chrome-fragments.html new file mode 100644 index 00000000..03b2e89a --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/chrome-fragments.html @@ -0,0 +1,275 @@ + +
      holiday shipping
      + + + + + + + + + diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/layout.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/layout.html new file mode 100644 index 00000000..9880120a --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/layout.html @@ -0,0 +1,188 @@ + + + Title + + + + + + + + + + + + + + + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + +
      +
      + +
      +
      +
      +
      +
      alert banner
      +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + +
      mega menu
      +
      +
      +
      +
      + +
      +
      + +
      +
      +
      +
      +
      + +
      +
      + + + + + + + diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/media-row.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/media-row.html new file mode 100644 index 00000000..3e08300a --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/media-row.html @@ -0,0 +1,15 @@ + +
      + placeholder +
      +

      media name

      +

      Caption for media name

      +
      +
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/price.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/price.html new file mode 100644 index 00000000..e275ee2e --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/price.html @@ -0,0 +1,8 @@ + +

      9.99

      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/stat.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/stat.html new file mode 100644 index 00000000..f137cc31 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/stat.html @@ -0,0 +1,11 @@ + +
      + stat name + 0 + 0 +
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/tile.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/tile.html new file mode 100644 index 00000000..24c6937b --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/shared/tile.html @@ -0,0 +1,11 @@ + +
      +

      tile name

      +

      0

      + badge +
      diff --git a/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/trivial-substitution.html b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/trivial-substitution.html new file mode 100644 index 00000000..255c5804 --- /dev/null +++ b/benchmarks/jvm/src/main/resources/thymeleaf/idiomatic/trivial-substitution.html @@ -0,0 +1,19 @@ + +
      +

      Product title

      +

      SKU-0000

      +

      0

      +

      Brand

      +

      Category

      +

      Availability

      + + + +

      Summary

      +

      0.0

      +
      diff --git a/benchmarks/linux-crosscheck/README.md b/benchmarks/linux-crosscheck/README.md new file mode 100644 index 00000000..4486a8fb --- /dev/null +++ b/benchmarks/linux-crosscheck/README.md @@ -0,0 +1,113 @@ +# Phase 8 — Linux cross-check tooling (reproduce book) + +Tooling for the Phase 8 — linux-crosscheck spec +(supplements: [linux-environment-and-toolchains.md](../docs/linux-environment-and-toolchains.md), +[linux-harness-settings-and-validation.md](../docs/linux-harness-settings-and-validation.md)). + +This directory is the reproduce path the published Linux cross-check report points at (spec D18). +It was authored **before any bare-metal Ubuntu session exists**, under two standing rulings: + +- **SR-1 — no benchmark results this pass.** No Windows protocol run for phases 1–6 is published + yet, so `windows-source.json` is *not* transcribed here (only its schema and structural checks + ship — see below), and no Linux number is produced by this pass. +- **SR-2 — Linux validation happens on WSL2 (Ubuntu 24.04 default instance), not bare metal.** + The scripts that only make sense on bare metal (`tune.sh`, `untune.sh`, the GRUB isolation + entry) are committed and **designed to fail cleanly under WSL** with an explicit + `bare-metal-only` message — that failure is their correct WSL behavior, not a defect. + `capture-environment.sh` runs everywhere and records every bare-metal-only item as + `unavailable under WSL (deferred to bare metal)`. + +## What runs where + +| Script | Bare-metal Ubuntu Server 24.04 (measurement box) | WSL2 Ubuntu 24.04 (functional posture, SR-2) | +|---|---|---| +| `setup-toolchains.sh` | installs the pinned toolchains (spec D4/D5) | installs identically (Ubuntu 24.04 userland) — functional validation only | +| `capture-environment.sh` | full D3 record (M1–M5, K1–K8, F1–F7, toolchain table, repo state) | completes; bare-metal-only items recorded as unavailable-under-WSL | +| `tune.sh` / `untune.sh` | enter/exit the one D2 session state | **designed clean failure** (`bare-metal-only`) | +| `grub-isolation.cfg.example` | template for the isolation boot entry | not applicable (no GRUB) | +| `run-*.sh` | tuned-state pre-flight + ecosystem commands | `--smoke --no-tune-check` functional runs only (bypass recorded in output) | +| `validate.py` / `test_validate.py` | part 2 verdicts | fully OS-independent; runs anywhere (stdlib-only Python ≥ 3.10) | + +## Deferred to bare metal (SR-2 list — deferred, not faked) + +None of the following was executed or simulated in this pass; each is a bare-metal work item on +the Q1.6 protocol box (Ryzen 9 9950X) after the D1 sequencing gate opens: + +1. **D1 install** — Ubuntu Server 24.04.x dual-boot (disjoint partition/disk, HWE kernel + `linux-generic-hwe-24.04`, firmware untouched, Windows-preservation checks, quiesce list). +2. **GRUB isolation entry** — instantiating `grub-isolation.cfg.example` with the **actual** + SMT sibling pair read from `/sys/devices/system/cpu/cpu4/topology/thread_siblings_list` + on the installed system (never an assumed enumeration). +3. **pyperf system tune** — `tune.sh` steps 2–4 of D2 (machine-wide tune, `amd-pstate` boost + off, `pyperf system show` capture). +4. **Firmware capture** — `dmidecode` items M1/M3 and the M4 firmware-invariance attestation. +5. **tune/untune post-condition asserts** — governor/boost/sample-rate/isolated-set read-backs + passing (on WSL they fail by design), and `untune.sh` + `pyperf system show` restore proof. + +Also deferred under SR-1: the transcription of `windows-source.json` (no published Windows +protocol reports exist to transcribe), the D12 gate sweep as a publication gate, all D13 +measurement runs, and the report itself. + +## Order of operations (bare-metal session) + +1. `PRECONDITION` line in the run log: all Windows protocol runs published; shipped subset listed + (D1 sequencing gate — hard stop until true). +2. D1 install + `grub-isolation.cfg.example` instantiated; Windows-preservation checks recorded. +3. `./setup-toolchains.sh` — pinned toolchains; emits the `version-deltas.md` draft. +4. Boot the "Ubuntu — benchmark isolation" GRUB entry. +5. `sudo ./tune.sh` — enters the D2 state, asserts post-conditions, records + `pyperf system show` to `out/session-state.txt` (the pre-flight baseline). +6. `./capture-environment.sh` — full D3 closed checklist into `out/environment/`. +7. Gate sweep (D12): each ecosystem's own gate commands, red-first, triage on failure. +8. `./run-all.sh` — anchor-first order (dotnet → rust → jvm → js → python → go), + stop-on-red-gate; each launcher asserts the tuned state before timing. +9. `python3 validate.py --windows-source windows-source.json --linux-results ` — + part 2 tables and verdicts. +10. `sudo ./untune.sh`; reboot to the default entry; assemble the `docs/benchmarks//` + report; run the D17 checklist. + +## WSL functional posture (what this pass validated, SR-2) + +- `bash -n` on every shell script (syntax). +- `capture-environment.sh` dry-run completes under WSL, recording each unavailable item. +- `tune.sh` fails with its designed `bare-metal-only` message under WSL. +- `python3 test_validate.py` green (all D15/D16/D17.4 threshold-straddling fixtures). +- `setup-toolchains.sh --dry-run` prints its plan without installing (installs are the next + work item). + +## Files + +| File | Role | +|---|---| +| `README.md` | this reproduce book | +| `grub-isolation.cfg.example` | isolation boot-entry template (D1.6) | +| `tune.sh` / `untune.sh` | D2 session-state enter/exit with post-condition asserts | +| `capture-environment.sh` | D3 closed environment checklist capture | +| `setup-toolchains.sh` | D4/D5 pinned toolchain installs + `version-deltas.md` draft | +| `run-dotnet.sh` … `run-go.sh`, `run-all.sh` | per-harness launchers (D6–D11), tuned-state pre-flight, `--smoke` | +| `windows-source.schema.json` | schema for the (SR-1-deferred) `windows-source.json` transcription; D17.4 structural rules | +| `validate.py` / `test_validate.py` | D15 d-forms, D16 thresholds, D17 structural checks + fixtures | +| `common.sh` | shared helpers (WSL detection, tuned-state pre-flight, output paths) | + +Script outputs land under `benchmarks/linux-crosscheck/out/` (git-ignored via `out/.gitignore`; +publication copies artifacts into `docs/benchmarks//` at WI8, never the other way). + +## Parameterizations recorded (SR-1/SR-2/SR-3) + +- **.NET SDK version** (`setup-toolchains.sh`): the spec pins "the exact Windows-run SDK + version", but under SR-1 no Windows protocol report is published yet. The script is + parameterized (`DOTNET_SDK_VERSION`, default `10.0.302` — the current 10.x line observed on + the Windows machine). **SR-1 note:** before the bare-metal run, this default MUST be replaced + with the value from the published Windows protocol report's environment block. +- **Temurin fallback** (`--allow-jdk-fallback`, SR-3 mirror): if no Temurin 25 GA build is + downloadable, the flag permits a Temurin/JDK 23 fallback; use is recorded as a + `version-deltas.md` row with a caveat obligation (D4.3). Default: hard-fail on pin + unavailability. +- **CPython fallback** (`--allow-python-fallback`, SR-3): primary path is deadsnakes + `python3.14`; documented fallback is a source build of 3.14.6 (`--enable-optimizations + --with-lto`, D5). Under SR-3 a deadsnakes `python3.13` fallback is additionally acceptable + behind this flag; use is recorded as a delta row. Default: hard-fail. +- **Tuned-state pre-flight bypass** (`--no-tune-check`, SR-2): launchers implement the D2/WI5 + `pyperf system show` pre-flight; under WSL it cannot pass, so the bypass flag exists for + functional (`--smoke`) runs only. Every bypass is printed and written into the launcher's + output header — a bare-metal measurement run must never use it. diff --git a/benchmarks/linux-crosscheck/__pycache__/validate.cpython-312.pyc b/benchmarks/linux-crosscheck/__pycache__/validate.cpython-312.pyc new file mode 100644 index 00000000..071ebb68 Binary files /dev/null and b/benchmarks/linux-crosscheck/__pycache__/validate.cpython-312.pyc differ diff --git a/benchmarks/linux-crosscheck/__pycache__/validate.cpython-313.pyc b/benchmarks/linux-crosscheck/__pycache__/validate.cpython-313.pyc new file mode 100644 index 00000000..dd53d780 Binary files /dev/null and b/benchmarks/linux-crosscheck/__pycache__/validate.cpython-313.pyc differ diff --git a/benchmarks/linux-crosscheck/capture-environment.sh b/benchmarks/linux-crosscheck/capture-environment.sh new file mode 100644 index 00000000..30b31ee7 --- /dev/null +++ b/benchmarks/linux-crosscheck/capture-environment.sh @@ -0,0 +1,220 @@ +#!/usr/bin/env bash +# capture-environment.sh — the CLOSED environment-record checklist. +# +# Collects exactly M1-M5, K1-K8, F1-F7, the per-engine toolchain/libc/allocator +# identity table, and the repo/corpus state. Runs on bare metal AND under WSL2: +# under WSL every bare-metal-only item is RECORDED as +# "unavailable under WSL (deferred to bare metal)" instead of crashing — the +# checklist stays closed; nothing is silently skipped. +# +# usage: ./capture-environment.sh [--out DIR] + +set -uo pipefail +. "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/common.sh" + +OUT="" +while [ $# -gt 0 ]; do + case "$1" in + --out) OUT="${2:?--out requires a directory}"; shift ;; + -h|--help) echo "usage: capture-environment.sh [--out DIR]"; exit 0 ;; + *) lcx_die "unknown argument: $1" ;; + esac + shift +done + +if [ -z "$OUT" ]; then + lcx_mkout + OUT="$LCX_OUT_DIR/environment" +fi +mkdir -p "$OUT" +RECORD="$OUT/environment-record.md" + +IS_WSL=0 +if lcx_is_wsl; then IS_WSL=1; fi +UNAVAILABLE_WSL="unavailable under WSL (deferred to bare metal)" + +{ + echo "# Environment record (closed checklist)" + echo + echo "- Captured: $(date -u +%Y-%m-%dT%H:%M:%SZ)" + if [ "$IS_WSL" = "1" ]; then + echo "- Host class: **WSL2** (functional posture — bare-metal-only items below are" + echo " recorded as deferred, not faked; this record is NOT a measurement-session record)" + else + echo "- Host class: non-WSL Linux" + fi + echo +} > "$RECORD" + +# capture <slug> <cmd...> +# Runs cmd, stores raw output in $OUT/<slug>.txt, and appends a section to the record. +# Any failure (missing file, missing tool, permission) records the unavailable note. +capture() { + local id="$1" title="$2" slug="$3" + shift 3 + local raw="$OUT/$slug.txt" + local status=0 + local output shown + output="$("$@" 2>&1)" || status=$? + shown="${*/#sudo_n/sudo -n}" + { + echo "## $id — $title" + echo + echo '```' + echo "\$ $shown" + echo '```' + echo + } >> "$RECORD" + if [ $status -ne 0 ] || [ -z "$output" ]; then + local note="unavailable ($* exited $status)" + if [ "$IS_WSL" = "1" ]; then note="$UNAVAILABLE_WSL"; fi + printf '%s\n' "$note" > "$raw" + { + echo "> $note" + echo + } >> "$RECORD" + lcx_note "$id: $note" + else + printf '%s\n' "$output" > "$raw" + { + echo '```' + printf '%s\n' "$output" | head -n 60 + if [ "$(printf '%s\n' "$output" | wc -l)" -gt 60 ]; then + echo "... (full output: environment/$slug.txt)" + fi + echo '```' + echo + } >> "$RECORD" + lcx_note "$id: captured -> $slug.txt" + fi +} + +# sudo wrapper that never prompts (non-interactive capture); failure => unavailable note. +sudo_n() { sudo -n "$@"; } + +echo "### Machine and firmware (M1–M5)" >> "$RECORD"; echo >> "$RECORD" +capture M1 "System/board/BIOS identity" "m1-dmidecode-system" sudo_n dmidecode -t system -t baseboard -t bios +capture M2 "CPU identity + topology" "m2-lscpu" lscpu +capture M2e "CPU topology (extended)" "m2-lscpu-e" lscpu -e +capture M3 "Memory modules + speed" "m3-dmidecode-memory" sudo_n dmidecode -t memory +# M4 is a dated human attestation, never script-fabricated. +{ + echo "## M4 — Firmware-invariance statement" + echo + if [ "$IS_WSL" = "1" ]; then + echo "> $UNAVAILABLE_WSL — M4 is a run-log human attestation made on the bare-metal box" + echo "> (\"no UEFI setting changed since the Windows protocol runs\" + any recorded install-time exceptions, dated)." + else + echo "> PENDING HUMAN ATTESTATION: record in the run log, dated:" + echo "> \"no UEFI setting changed since the Windows protocol runs\" (+ any recorded install-time exceptions)." + fi + echo +} >> "$RECORD" +capture M5 "SMT state (must read enabled on bare metal)" "m5-smt" cat /sys/devices/system/cpu/smt/control + +echo "### Kernel, mitigations, isolation (K1–K8)" >> "$RECORD"; echo >> "$RECORD" +capture K1a "OS release" "k1-os-release" cat /etc/os-release +capture K1b "Kernel" "k1-uname" uname -a +capture K2 "Kernel cmdline (verbatim; isolation parameters on the measurement boot)" "k2-cmdline" cat /proc/cmdline +capture K3 "CPU-mitigation state (every file, kernel defaults)" "k3-mitigations" grep -r . /sys/devices/system/cpu/vulnerabilities/ +capture K4a "Isolated CPUs" "k4-isolated" cat /sys/devices/system/cpu/isolated +capture K4b "Thread-sibling proof (cpu${LCX_ISOLATION_CPU})" "k4-siblings" cat "/sys/devices/system/cpu/cpu${LCX_ISOLATION_CPU}/topology/thread_siblings_list" +capture K5 "ASLR state" "k5-aslr" cat /proc/sys/kernel/randomize_va_space +capture K6 "Transparent hugepages mode" "k6-thp" cat /sys/kernel/mm/transparent_hugepage/enabled +capture K7 "perf event sample rate (post-tune, expect 1)" "k7-perf-sample-rate" sysctl kernel.perf_event_max_sample_rate +capture K8 "Running services (post-quiesce)" "k8-services" systemctl list-units --type=service --state=running + +echo "### Frequency policy (F1–F7)" >> "$RECORD"; echo >> "$RECORD" +capture F1a "Scaling driver" "f1-scaling-driver" cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver +capture F1b "amd-pstate status" "f1-amd-pstate" cat /sys/devices/system/cpu/amd_pstate/status +capture F2 "Governor (all policies, unique)" "f2-governors" bash -c 'cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor | sort -u' +capture F3 "Boost state (expect 0 in-session; tune.sh turns it off)" "f3-boost" cat /sys/devices/system/cpu/cpufreq/boost +capture F4 "Min/max scaling frequencies" "f4-scaling-freq" bash -c 'cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq' +capture F5 "Energy-performance preference (if exposed)" "f5-epp" cat /sys/devices/system/cpu/cpu0/cpufreq/energy_performance_preference +capture F6 "pyperf system show (full)" "f6-pyperf-show" python3 -m pyperf system show +capture F7 "Power source (AC; desktop box AC by construction)" "f7-power" bash -c 'cat /sys/class/power_supply/*/online' + +# --- Per-engine toolchain / runtime / libc / allocator identity table --------- +lcx_note "building per-engine toolchain identity table" +TOOLCHAINS="$OUT/toolchain-identity.md" + +# tool_version <cmd...> -> first line of output, or a not-installed note. +tool_version() { + local out + if out="$("$@" 2>&1)"; then + printf '%s' "$out" | head -n 1 + else + printf 'not installed (setup-toolchains.sh not yet run, or unavailable on this host)' + fi +} + +GLIBC="$(tool_version ldd --version)" +DOTNET_V="$(tool_version dotnet --version)" +RUSTC_V="$(tool_version rustc -vV)" +JAVA_V="$(java -version 2>&1 | head -n 1 || echo 'not installed (setup-toolchains.sh not yet run, or unavailable on this host)')" +NODE_V="$(tool_version node --version)" +PY_BIN="" +for c in python3.14 python3.13 python3; do + if command -v "$c" >/dev/null 2>&1; then PY_BIN="$c"; break; fi +done +if [ -n "$PY_BIN" ]; then + PY_V="$("$PY_BIN" -VV 2>&1 | head -n 1)" + PY_CFG="$("$PY_BIN" -c 'import sysconfig; print(sysconfig.get_config_var("CONFIG_ARGS"))' 2>/dev/null || echo 'CONFIG_ARGS unavailable')" +else + PY_V='not installed (setup-toolchains.sh not yet run)' + PY_CFG='n/a' +fi +GO_V="$(tool_version go version)" + +{ + echo "# Per-engine toolchain / runtime / libc / allocator identity" + echo + echo "glibc (captured once, referenced by every row): \`$GLIBC\`" + echo + echo "| Ecosystem | Version string | Install channel | Target triple/arch | libc | Allocator note |" + echo "|---|---|---|---|---|---|" + echo "| .NET | \`$DOTNET_V\` | dotnet-install.sh --version (parameterized until a Windows protocol report publishes its SDK version) | linux-x64 (RID) | glibc | .NET GC (Server GC off — BenchmarkDotNet defaults, as on Windows) |" + echo "| Rust | \`$RUSTC_V\` | rustup toolchain install 1.97.1 | x86_64-unknown-linux-gnu | glibc | System allocator (std), same as Windows build |" + echo "| JVM | \`$JAVA_V\` | Temurin 25 linux-x64 tar.gz (JMH '# VM version' line is the runtime identity of record) | linux-x64 | glibc | JVM heap; GC as reported by the JMH VM line (defaults, no jvmArgs) |" + echo "| JS/Node | \`$NODE_V\` | nodejs.org official linux-x64 tarball, v24.x major pin | linux-x64 | glibc | V8 heap; npm ci against the committed lockfile |" + echo "| Python | \`$PY_V\` | deadsnakes PPA python3.14 (fallback recorded if used) | x86_64-linux-gnu | glibc | pymalloc (default); CONFIG_ARGS: \`$PY_CFG\` |" + echo "| Go | \`$GO_V\` | go.dev/dl official linux-amd64 tarball 1.26.5 | linux/amd64 | glibc (cgo-linked stdlib parts) | Go runtime allocator + Green Tea GC (1.26 default), GOGC=100; GOMAXPROCS recorded as the runtime reports it |" + echo + echo "process.versions.v8: \`$(node -e 'console.log(process.versions.v8)' 2>/dev/null || echo 'n/a — node not installed')\`" +} > "$TOOLCHAINS" +lcx_note "toolchain table -> $TOOLCHAINS" + +# --- Repo state --------------------------------------------------------------- +lcx_note "capturing repo state" +REPO="$OUT/repo-state.md" +{ + echo "# Repo state" + echo + cd "$LCX_REPO_ROOT" || exit 1 + echo "- HEAD: \`$(git rev-parse HEAD 2>/dev/null || echo 'unavailable')\`" + if [ -z "$(git status --porcelain 2>/dev/null)" ]; then + echo "- Working tree: clean" + else + echo "- Working tree: **DIRTY** (a measurement session requires a clean tree — same discipline as export-corpus)" + fi + echo "- Corpus generatingCommit values (from benchmarks/dotnet/GoldenCorpus/manifest.json):" + if [ -f "benchmarks/dotnet/GoldenCorpus/manifest.json" ]; then + grep -o '"generatingCommit"[^,}]*' benchmarks/dotnet/GoldenCorpus/manifest.json | sort -u | sed 's/^/ - `/;s/$/`/' + else + echo " - manifest.json not found" + fi +} > "$REPO" + +{ + echo "## Companion files" + echo + echo "- Per-engine toolchain identity: \`toolchain-identity.md\`" + echo "- Repo state: \`repo-state.md\`" + echo "- Raw command outputs: \`*.txt\` alongside this record" +} >> "$RECORD" + +lcx_note "environment record complete -> $RECORD" +if [ "$IS_WSL" = "1" ]; then + lcx_note "WSL run: bare-metal-only items were recorded as deferred, not captured." +fi +exit 0 diff --git a/benchmarks/linux-crosscheck/common.sh b/benchmarks/linux-crosscheck/common.sh new file mode 100644 index 00000000..29364fdd --- /dev/null +++ b/benchmarks/linux-crosscheck/common.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +# common.sh — shared helpers for the linux-crosscheck tooling. +# Sourced by every script in this directory; not executable on its own. + +set -u + +# Directory this file lives in (repo path: benchmarks/linux-crosscheck). +LCX_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +LCX_REPO_ROOT="$(cd -- "$LCX_DIR/../.." >/dev/null 2>&1 && pwd)" +LCX_OUT_DIR="${LCX_OUT_DIR:-$LCX_DIR/out}" +LCX_STATE_FILE="$LCX_OUT_DIR/session-state.txt" + +lcx_mkout() { + mkdir -p "$LCX_OUT_DIR" + # Keep script outputs out of git (no stray files outside the dated report dir). + if [ ! -f "$LCX_OUT_DIR/.gitignore" ]; then + printf '*\n' > "$LCX_OUT_DIR/.gitignore" + fi +} + +# --- WSL detection ------------------------------------------------------------- +# WSL2 kernels self-identify in /proc/version and /proc/sys/kernel/osrelease +# ("microsoft-standard-WSL2"). Bare-metal Ubuntu does not. +lcx_is_wsl() { + grep -qiE 'microsoft|wsl' /proc/version 2>/dev/null || \ + grep -qiE 'microsoft|wsl' /proc/sys/kernel/osrelease 2>/dev/null +} + +lcx_die() { + echo "ERROR: $*" >&2 + exit 1 +} + +lcx_note() { + echo "== $*" +} + +# --- SMT sibling pair (read from the topology, never assumed) ------------------ +# Reads the thread-sibling list of the configured physical core (default: CPU 4's +# core). Fails if the topology file is absent — which it is under WSL2 (no real +# per-CPU topology is exposed). +LCX_ISOLATION_CPU="${LCX_ISOLATION_CPU:-4}" + +lcx_smt_pair() { + local f="/sys/devices/system/cpu/cpu${LCX_ISOLATION_CPU}/topology/thread_siblings_list" + if [ ! -r "$f" ]; then + return 1 + fi + cat "$f" +} + +# --- Tuned-state pre-flight (launchers assert the tuned state before timing) ---- +# Compares `pyperf system show` against the state recorded by tune.sh. +# Callers pass "$1" = 1 to bypass (--no-tune-check); the bypass is RECORDED +# on stdout so it lands in every captured launcher log. +lcx_preflight_tuned_state() { + local bypass="${1:-0}" + if [ "$bypass" = "1" ]; then + echo "TUNE-CHECK: BYPASSED via --no-tune-check (recorded)." + echo "TUNE-CHECK: this is acceptable only for functional/--smoke runs (WSL posture);" + echo "TUNE-CHECK: a bare-metal measurement run MUST NOT bypass the pre-flight." + return 0 + fi + if [ ! -f "$LCX_STATE_FILE" ]; then + lcx_die "state drift: no recorded session state at $LCX_STATE_FILE — run tune.sh first (or pass --no-tune-check for a functional run; the bypass is recorded)" + fi + local current + if ! current="$(python3 -m pyperf system show 2>&1)"; then + lcx_die "state drift: 'pyperf system show' failed: $(printf '%s' "$current" | head -n 3)" + fi + local diff_out + if ! diff_out="$(printf '%s\n' "$current" | diff -u "$LCX_STATE_FILE" - 2>&1)"; then + echo "state drift: <diff excerpt>" >&2 + printf '%s\n' "$diff_out" | head -n 20 >&2 + exit 1 + fi + echo "TUNE-CHECK: pyperf system show matches recorded session state ($LCX_STATE_FILE)." +} + +# --- Launcher arg parsing (shared shape: [--smoke] [--no-tune-check]) ---------- +LCX_SMOKE=0 +LCX_NO_TUNE_CHECK=0 + +lcx_parse_launcher_args() { + while [ $# -gt 0 ]; do + case "$1" in + --smoke) LCX_SMOKE=1 ;; + --no-tune-check) LCX_NO_TUNE_CHECK=1 ;; + -h|--help) + echo "usage: $(basename -- "$0") [--smoke] [--no-tune-check]" + echo " --smoke short functional pass (no measurement validity)" + echo " --no-tune-check bypass the tuned-state pre-flight (bypass is recorded; WSL functional runs only)" + exit 0 ;; + *) lcx_die "unknown argument: $1" ;; + esac + shift + done +} + +lcx_launcher_header() { + local name="$1" + echo "== linux-crosscheck launcher: $name ==" + echo "date: $(date -u +%Y-%m-%dT%H:%M:%SZ)" + if lcx_is_wsl; then echo "environment: WSL2 (functional posture — no measurement validity)"; else echo "environment: non-WSL Linux"; fi + if [ "$LCX_SMOKE" = "1" ]; then + echo "mode: SMOKE (short functional flags — results carry NO measurement validity)" + else + echo "mode: MEASUREMENT (full per-harness settings, as on Windows)" + fi + lcx_preflight_tuned_state "$LCX_NO_TUNE_CHECK" +} diff --git a/benchmarks/linux-crosscheck/grub-isolation.cfg.example b/benchmarks/linux-crosscheck/grub-isolation.cfg.example new file mode 100644 index 00000000..08ad8012 --- /dev/null +++ b/benchmarks/linux-crosscheck/grub-isolation.cfg.example @@ -0,0 +1,49 @@ +# grub-isolation.cfg.example — "Ubuntu — benchmark isolation" boot entry template. +# +# BARE-METAL ONLY. WSL2 has no GRUB and no isolable topology; this file +# is committed as a template and instantiated only during the bare-metal install. +# +# HOW TO INSTANTIATE (do NOT copy this file verbatim): +# +# 1. On the installed bare-metal system, read the actual SMT thread-sibling pair of +# CPU 4's physical core — NEVER assume an enumeration scheme; verify on the +# installed system: +# +# cat /sys/devices/system/cpu/cpu4/topology/thread_siblings_list +# +# Example outputs: "4,20" (Linux often enumerates the 9950X's siblings core-major) +# or "8-9" — whatever it prints IS the pair; record it in the run log. +# +# 2. Replace every <PAIR> below with that exact list (kernel cpu-list syntax, e.g. 4,20). +# +# 3. Append the menuentry to /etc/grub.d/40_custom (below the exec tail line), or +# equivalently add the three parameters to a dedicated entry via your preferred +# mechanism. Do NOT put them in GRUB_CMDLINE_LINUX_DEFAULT — the default entry +# must stay un-isolated; the isolation entry is selected only for measurement +# sessions. +# +# 4. sudo update-grub +# +# 5. Boot the entry and verify (recorded in the run log): +# cat /proc/cmdline # contains all three parameters, verbatim +# cat /sys/devices/system/cpu/isolated # prints exactly <PAIR> +# +# The parameter set is pyperf's documented isolation recommendation +# (https://pyperf.readthedocs.io/en/latest/system.html): +# isolcpus=<PAIR> remove the pair from the general scheduler affinity mask +# nohz_full=<PAIR> omit scheduler ticks on the pair while single-task +# rcu_nocbs=<PAIR> move RCU callbacks off the pair +# +# ---- template (replace <PAIR>; adjust root/UUID lines to match the installed +# ---- default entry — copy them from /boot/grub/grub.cfg's primary Ubuntu entry) ---- + +menuentry 'Ubuntu — benchmark isolation' { + # Copy the following from the installed default Ubuntu menuentry: + # insmod / search lines, root UUID, kernel and initrd paths. + insmod gzio + insmod part_gpt + insmod ext2 + search --no-floppy --fs-uuid --set=root <ROOT-FS-UUID> + linux /boot/vmlinuz ro quiet isolcpus=<PAIR> nohz_full=<PAIR> rcu_nocbs=<PAIR> + initrd /boot/initrd.img +} diff --git a/benchmarks/linux-crosscheck/run-all.sh b/benchmarks/linux-crosscheck/run-all.sh new file mode 100644 index 00000000..8d9272bc --- /dev/null +++ b/benchmarks/linux-crosscheck/run-all.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# run-all.sh — the full measurement matrix in order, stop-on-red-gate. +# Anchor-first: the intra-.NET suite produces the Linux Heddle anchor rows every +# ratio column needs; then the program's priority order Rust -> JVM -> JS -> Python -> Go. +# An ecosystem absent from the shipped subset is skipped by the operator and +# manifest-recorded — this script stops on the first failure +# (a red gate must be triaged before anything later runs). +# +# For the JS ecosystem the five-run stability procedure (5x controlled) runs +# BEFORE the timed suites, as the measurement order requires. +# +# usage: ./run-all.sh [--smoke] [--no-tune-check] + +set -euo pipefail +HERE="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +. "$HERE/common.sh" +lcx_parse_launcher_args "$@" + +PASS=() +[ "$LCX_SMOKE" = "1" ] && PASS+=(--smoke) +[ "$LCX_NO_TUNE_CHECK" = "1" ] && PASS+=(--no-tune-check) + +echo "== run-all: measurement order, stop-on-red-gate ==" + +# 1. Intra-.NET (Linux Heddle anchor rows first). +"$HERE/run-dotnet.sh" ${PASS[@]+"${PASS[@]}"} + +# 2. Rust +"$HERE/run-rust.sh" ${PASS[@]+"${PASS[@]}"} + +# 3. JVM +"$HERE/run-jvm.sh" ${PASS[@]+"${PASS[@]}"} + +# 4. JS — stability procedure first (publication-gating), then the timed suites. +if [ "$LCX_SMOKE" = "1" ]; then + # Smoke: the launcher's single-pass smoke covers the functional check. + "$HERE/run-js.sh" ${PASS[@]+"${PASS[@]}"} +else + "$HERE/run-js.sh" --repeat 5 --suite controlled ${PASS[@]+"${PASS[@]}"} + echo "== run-all: compute the five-run RSD verdict before continuing (all RSD <= 5% -> verified;" + echo "== (5%,10%] after one re-run cycle -> verified-with-disclosure; > 10% persisting" + echo "== -> failed, and JS publishes no Linux numbers, manifest-recorded)." + "$HERE/run-js.sh" ${PASS[@]+"${PASS[@]}"} +fi + +# 5. Python +"$HERE/run-python.sh" ${PASS[@]+"${PASS[@]}"} + +# 6. Go +"$HERE/run-go.sh" ${PASS[@]+"${PASS[@]}"} + +echo "== run-all: complete. Next: validate.py (part 2 tables), then untune.sh, then report assembly. ==" diff --git a/benchmarks/linux-crosscheck/run-dotnet.sh b/benchmarks/linux-crosscheck/run-dotnet.sh new file mode 100644 index 00000000..3da8e40d --- /dev/null +++ b/benchmarks/linux-crosscheck/run-dotnet.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# run-dotnet.sh — .NET protocol suite launcher (anchor rows first: every ratio +# column needs the Linux Heddle rows this suite produces). +# Same invocation as the Windows protocol run: Release, net10.0, the harness's own ShortRun +# default, MemoryDiagnoser via the suite attributes, no affinity, no custom job. +# BenchmarkDotNet's own priority behavior is left unmodified; its warning lines are part of the +# captured log. +# +# usage: ./run-dotnet.sh [--smoke] [--no-tune-check] + +set -euo pipefail +. "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/common.sh" +lcx_parse_launcher_args "$@" +lcx_mkout +lcx_launcher_header "dotnet (cross-stack .NET leg)" 2>&1 | tee "$LCX_OUT_DIR/run-dotnet.log" + +# cwd MUST be the harness directory: BenchmarkDotNet writes its artifacts relative to the current +# directory, and that is where report assembly copies them from. (Template and corpus paths resolve by walking +# up from the assembly location, so those work from anywhere; the artifacts do not.) +cd "$LCX_REPO_ROOT/benchmarks/dotnet" + +# Gates first: the ecosystem's own commands, unmodified. +lcx_note "gate: cell registry" 2>&1 | tee -a "$LCX_OUT_DIR/run-dotnet.log" +dotnet run -c Release --project . -- gate 2>&1 | tee -a "$LCX_OUT_DIR/run-dotnet.log" +lcx_note "gate: selftest" 2>&1 | tee -a "$LCX_OUT_DIR/run-dotnet.log" +dotnet run -c Release --project . -- selftest 2>&1 | tee -a "$LCX_OUT_DIR/run-dotnet.log" +lcx_note "gate: verify-corpus" 2>&1 | tee -a "$LCX_OUT_DIR/run-dotnet.log" +dotnet run -c Release --project . -- verify-corpus 2>&1 | tee -a "$LCX_OUT_DIR/run-dotnet.log" + +# The cross-stack sweep, then the three sidebars. Verbs rather than one bare `--filter '*'`: the +# sweep's row set is normative and must not silently acquire whatever else carries a [Benchmark]. +LCX_DOTNET_VERBS=(bench-crossstack bench-techniques bench-cold bench-internal) + +if [ "$LCX_SMOKE" = "1" ]; then + # Functional pass only: BenchmarkDotNet Dry job (1 launch, 1 iteration, no validity). + lcx_note "SMOKE: BenchmarkDotNet --job Dry across every suite (no measurement validity)" 2>&1 | tee -a "$LCX_OUT_DIR/run-dotnet.log" + for verb in "${LCX_DOTNET_VERBS[@]}"; do + dotnet run -c Release --project . -- "$verb" --job Dry 2>&1 | tee -a "$LCX_OUT_DIR/run-dotnet.log" + done +else + # Measurement: every suite at the harness defaults, matching the Windows runs. + for verb in "${LCX_DOTNET_VERBS[@]}"; do + dotnet run -c Release --project . -- "$verb" 2>&1 | tee -a "$LCX_OUT_DIR/run-dotnet.log" + done +fi +lcx_note "dotnet launcher done; artifacts under benchmarks/dotnet/BenchmarkDotNet.Artifacts (copied to the report dir at assembly)" diff --git a/benchmarks/linux-crosscheck/run-go.sh b/benchmarks/linux-crosscheck/run-go.sh new file mode 100644 index 00000000..4a515424 --- /dev/null +++ b/benchmarks/linux-crosscheck/run-go.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# run-go.sh — Go testing/benchstat launcher. +# Replicates the Windows run-benchmarks steps: version asserts, templ regeneration +# freshness, vet, gates, prebuild, timed invocation(s), benchstat. Prebuilt binary +# launched PLAIN — no nice, no taskset, no start /high counterpart (the +# tuned system is the isolation). GOMAXPROCS/GOGC runtime defaults, values recorded +# as found (isolcpus-reduced mask disclosed, not overridden). The instability trigger +# (benchstat > ±5% -> taskset re-run on CCD0 non-isolated CPUs) is an operator step, +# recorded as one environment change. +# +# usage: ./run-go.sh [--smoke] [--no-tune-check] +# --smoke: -count=1 -benchtime=100ms (functional only) + +set -euo pipefail +. "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/common.sh" +lcx_parse_launcher_args "$@" +lcx_mkout +lcx_launcher_header "go (testing/benchstat)" 2>&1 | tee "$LCX_OUT_DIR/run-go.log" + +cd "$LCX_REPO_ROOT/benchmarks/go" + +# Version assert (expected pin go1.26.5 linux/amd64). +GO_V="$(go version)" +lcx_note "go version: $GO_V" 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" +case "$GO_V" in + *"go1.26.5 linux/amd64"*) : ;; + *) + if [ "$LCX_SMOKE" = "1" ]; then + lcx_note "RECORDED: go version differs from the pin (go1.26.5 linux/amd64) — acceptable in --smoke only" 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" + else + lcx_die "go version assert failed: want go1.26.5 linux/amd64, got: $GO_V" + fi ;; +esac + +# templ regeneration freshness: generated files must match their sources. +lcx_note "templ freshness: git diff --exit-code -- '*_templ.go'" 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" +git diff --exit-code -- '*_templ.go' 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" + +# Vet + gates (TestMain runs all gates in `go test ./suites`). +lcx_note "go vet ./..." 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" +go vet ./... 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" +lcx_note "gate: go test ./suites" 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" +go test ./suites 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" + +# Prebuild, then launch the binary plain. +BENCH_BIN="$LCX_OUT_DIR/go-bench" +lcx_note "prebuild: go test -c -o $BENCH_BIN ./suites" 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" +go test -c -o "$BENCH_BIN" ./suites 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" + +if [ "$LCX_SMOKE" = "1" ]; then + COUNT=1; BENCHTIME=100ms + lcx_note "SMOKE: -count=1 -benchtime=100ms (no measurement validity)" 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" +else + COUNT=20; BENCHTIME=1s +fi + +RESULTS="$LCX_OUT_DIR/go-results" +mkdir -p "$RESULTS" +lcx_note "bench: -run '^$' -bench '^BenchmarkRender$' -count=$COUNT -benchtime=$BENCHTIME (GOMAXPROCS recorded as found)" 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" +"$BENCH_BIN" -test.run '^$' -test.bench '^BenchmarkRender$' -test.count="$COUNT" -test.benchtime="$BENCHTIME" 2>&1 | tee "$RESULTS/bench.txt" + +# Cold-parse sidebar runs separately (operator step; same flags). + +if command -v benchstat >/dev/null 2>&1; then + benchstat "$RESULTS/bench.txt" 2>&1 | tee "$RESULTS/benchstat.txt" +else + lcx_note "RECORDED: benchstat not on PATH — run 'benchstat $RESULTS/bench.txt' before publication (sec/op + ±% are the published pair)" 2>&1 | tee -a "$LCX_OUT_DIR/run-go.log" +fi +lcx_note "go launcher done; outputs under $RESULTS" diff --git a/benchmarks/linux-crosscheck/run-js.sh b/benchmarks/linux-crosscheck/run-js.sh new file mode 100644 index 00000000..e0f672ab --- /dev/null +++ b/benchmarks/linux-crosscheck/run-js.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +# run-js.sh — mitata launcher. +# Replicates run.ps1's capture and -Repeat behavior WITHOUT the High priority class +# (no-priority rule: the tuned system is the isolation): starts +# `node --expose-gc --allow-natives-syntax <script>`, +# tees stdout to an artifacts file, propagates the exit code, supports --repeat N +# for the five-run stability procedure (re-executed on Linux, publication- +# gating: all RSD <= 5% -> verified; (5%,10%] after one re-run cycle -> verified-with- +# disclosure; > 10% persisting -> failed, no JS Linux numbers). run.ps1 is NOT modified. +# +# usage: ./run-js.sh [--smoke] [--no-tune-check] [--repeat N] [--suite controlled|idiomatic|cold|all] +# --smoke: single mitata pass of the controlled suite only (mitata defaults; the +# "single pass" is the smoke shape — mitata has no shorter sampling knob +# that would keep defaults untouched) +# stability procedure: ./run-js.sh --repeat 5 --suite controlled + +set -euo pipefail +. "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/common.sh" + +REPEAT=1 +SUITE="all" +ARGS=() +while [ $# -gt 0 ]; do + case "$1" in + --repeat) REPEAT="${2:?--repeat requires N}"; shift ;; + --suite) SUITE="${2:?--suite requires a name}"; shift ;; + -h|--help) + echo "usage: run-js.sh [--smoke] [--no-tune-check] [--repeat N] [--suite controlled|idiomatic|cold|all]" + echo " --smoke single mitata pass, controlled suite (functional only)" + echo " --no-tune-check bypass the tuned-state pre-flight (bypass is recorded; WSL functional runs only)" + echo " --repeat N run the suite N times (stability procedure: --repeat 5 --suite controlled)" + echo " --suite NAME controlled | idiomatic | cold | all (default all)" + exit 0 ;; + *) ARGS+=("$1") ;; + esac + shift +done +lcx_parse_launcher_args ${ARGS[@]+"${ARGS[@]}"} +lcx_mkout +ART="$LCX_OUT_DIR/js-artifacts" +mkdir -p "$ART" +lcx_launcher_header "js (mitata)" 2>&1 | tee "$LCX_OUT_DIR/run-js.log" + +cd "$LCX_REPO_ROOT/benchmarks/js" + +# Gates first: the ecosystem's own commands, unmodified. +lcx_note "gate: npm run selftest" 2>&1 | tee -a "$LCX_OUT_DIR/run-js.log" +npm run selftest 2>&1 | tee -a "$LCX_OUT_DIR/run-js.log" +lcx_note "gate: npm run gate" 2>&1 | tee -a "$LCX_OUT_DIR/run-js.log" +npm run gate 2>&1 | tee -a "$LCX_OUT_DIR/run-js.log" + +# suite name -> script path (same bench scripts and Node flags as Windows, mitata defaults). +suite_script() { + case "$1" in + controlled) echo "bench/controlled.mjs" ;; + idiomatic) echo "bench/idiomatic.mjs" ;; + cold) echo "bench/cold-compile.mjs" ;; + *) lcx_die "unknown suite: $1" ;; + esac +} + +run_suite() { # name + local name="$1" script rc + script="$(suite_script "$name")" + local i=1 + while [ "$i" -le "$REPEAT" ]; do + local out="$ART/${name}.txt" + if [ "$REPEAT" -gt 1 ]; then out="$ART/${name}-run${i}.txt"; fi + lcx_note "node --expose-gc --allow-natives-syntax $script -> $out (run $i/$REPEAT)" + set +e + node --expose-gc --allow-natives-syntax "$script" | tee "$out" + rc=${PIPESTATUS[0]} + set -e + if [ "$rc" -ne 0 ]; then + echo "run-js.sh: $script exited $rc (exit code propagated — run.ps1 parity)" >&2 + exit "$rc" + fi + i=$((i + 1)) + done +} + +if [ "$LCX_SMOKE" = "1" ]; then + lcx_note "SMOKE: single mitata pass, controlled suite only (no measurement validity)" 2>&1 | tee -a "$LCX_OUT_DIR/run-js.log" + REPEAT=1 + run_suite controlled +elif [ "$SUITE" = "all" ]; then + # Measurement order: stability procedure is run FIRST by the operator + # (./run-js.sh --repeat 5 --suite controlled), then the three timed suites. + run_suite controlled + run_suite idiomatic + run_suite cold +else + run_suite "$SUITE" +fi +lcx_note "js launcher done; captures under $ART" diff --git a/benchmarks/linux-crosscheck/run-jvm.sh b/benchmarks/linux-crosscheck/run-jvm.sh new file mode 100644 index 00000000..c4f393bc --- /dev/null +++ b/benchmarks/linux-crosscheck/run-jvm.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# run-jvm.sh — JMH launcher. +# Annotation regime lives in the sources (Fork 3, 1x2s / 3x1s, Threads 1, no jvmArgs — +# the short budget; the 'baseline' budget adds -wi 2 -i 9) +# and carries verbatim; this launcher performs the identical invocation: +# ./mvnw -q clean verify (gates wired into verify) +# java -jar target/benchmarks.jar -prof gc -rf json -rff jmh-result.json | tee jmh-log.txt +# Temurin 25 linux-x64 per the toolchain table; the JMH '# VM version' line is the +# recorded runtime identity. The DCE plausibility pass runs on the results before +# publication (operator step). +# +# usage: ./run-jvm.sh [--smoke] [--no-tune-check] +# --smoke: JMH command-line override -f 1 -wi 1 -i 1 -w 1s -r 1s (functional only) + +set -euo pipefail +. "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/common.sh" +lcx_parse_launcher_args "$@" +lcx_mkout +lcx_launcher_header "jvm (JMH)" 2>&1 | tee "$LCX_OUT_DIR/run-jvm.log" + +cd "$LCX_REPO_ROOT/benchmarks/jvm" + +# Build + gates (GateCli calibrate/gate are wired into verify). +lcx_note "gate + build: ./mvnw -q clean verify" 2>&1 | tee -a "$LCX_OUT_DIR/run-jvm.log" +./mvnw -q clean verify 2>&1 | tee -a "$LCX_OUT_DIR/run-jvm.log" + +RESULT_JSON="$LCX_OUT_DIR/jmh-result.json" +LOG_TXT="$LCX_OUT_DIR/jmh-log.txt" + +if [ "$LCX_SMOKE" = "1" ]; then + lcx_note "SMOKE: JMH -f 1 -wi 1 -i 1 -w 1s -r 1s (no measurement validity)" 2>&1 | tee -a "$LCX_OUT_DIR/run-jvm.log" + java -jar target/benchmarks.jar -f 1 -wi 1 -i 1 -w 1s -r 1s -prof gc -rf json -rff "$RESULT_JSON" | tee "$LOG_TXT" +else + # Measurement: the sources' annotation regime governs the shape, identical to the + # Windows invocation. ~9 min at the short budget. + java -jar target/benchmarks.jar -prof gc -rf json -rff "$RESULT_JSON" | tee "$LOG_TXT" +fi +lcx_note "jvm launcher done; jmh-result.json + jmh-log.txt under $LCX_OUT_DIR" diff --git a/benchmarks/linux-crosscheck/run-python.sh b/benchmarks/linux-crosscheck/run-python.sh new file mode 100644 index 00000000..98c73422 --- /dev/null +++ b/benchmarks/linux-crosscheck/run-python.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# run-python.sh — pyperf launcher. +# Runner settings unchanged from Windows (pyperf defaults: +# 20 processes x 3 values x 1 warmup, loops auto-calibrated), same five bench scripts, +# same JSON outputs; --affinity=<isolated pair> passed EXPLICITLY (the pair is read from +# the topology at run time, never assumed — the affinity-target delta vs Windows +# --affinity=4 is disclosed in the environment notes). No elevated shell, no priority: +# the Linux counterpart of REALTIME_PRIORITY_CLASS is the tune + isolation itself. +# Memory pass (mem_tracemalloc.py) runs identically, separate from timing. +# +# usage: ./run-python.sh [--smoke] [--no-tune-check] +# --smoke: pyperf quick flags (--fast: fewer processes/values — functional only); +# under WSL with --no-tune-check, --affinity is omitted (no isolated pair +# exists) and the omission is recorded in the log. + +set -euo pipefail +. "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/common.sh" +lcx_parse_launcher_args "$@" +lcx_mkout +lcx_launcher_header "python (pyperf)" 2>&1 | tee "$LCX_OUT_DIR/run-python.log" + +cd "$LCX_REPO_ROOT/benchmarks/python" + +PYBIN="${LCX_PYTHON:-}" +if [ -z "$PYBIN" ]; then + for c in python3.14 python3.13 python3; do + if command -v "$c" >/dev/null 2>&1; then PYBIN="$c"; break; fi + done +fi +[ -n "$PYBIN" ] || lcx_die "no python3 found (run setup-toolchains.sh first)" +lcx_note "interpreter: $($PYBIN -VV 2>&1 | head -n 1)" 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" + +# Gates first: selftest + both gate tracks, the ecosystem's own commands. +lcx_note "gate: selftest + gate_all (controlled, idiomatic)" 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" +"$PYBIN" -m runner.selftest 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" +"$PYBIN" -m runner.gate_all --track controlled 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" +"$PYBIN" -m runner.gate_all --track idiomatic 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" + +# Affinity: the isolated SMT pair, read (never assumed) from the topology. +AFFINITY_ARGS=() +if PAIR="$(lcx_smt_pair)" && [ -n "$(cat /sys/devices/system/cpu/isolated 2>/dev/null)" ]; then + AFFINITY_ARGS=(--affinity="$PAIR") + lcx_note "pyperf affinity: --affinity=$PAIR (isolated pair, recorded flag)" 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" +else + if [ "$LCX_NO_TUNE_CHECK" = "1" ]; then + lcx_note "RECORDED: no isolated pair available (WSL) — --affinity omitted; functional run only" 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" + else + lcx_die "no isolated SMT pair detected and tune-check not bypassed — boot the isolation entry and run tune.sh (or pass --no-tune-check for a functional run)" + fi +fi + +SMOKE_ARGS=() +if [ "$LCX_SMOKE" = "1" ]; then + SMOKE_ARGS=(--fast) + lcx_note "SMOKE: pyperf --fast (no measurement validity)" 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" +fi + +RESULTS="$LCX_OUT_DIR/python-results" +mkdir -p "$RESULTS" + +# The five bench scripts, same JSON outputs + pyperf stats dumps as the Windows runs. +for script in bench_jinja2_controlled bench_jinja2_idiomatic bench_mako_controlled bench_mako_idiomatic bench_cold_compile; do + lcx_note "$script" 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" + "$PYBIN" "$script.py" ${AFFINITY_ARGS[@]+"${AFFINITY_ARGS[@]}"} ${SMOKE_ARGS[@]+"${SMOKE_ARGS[@]}"} -o "$RESULTS/$script.json" 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" + "$PYBIN" -m pyperf stats "$RESULTS/$script.json" > "$RESULTS/$script.stats.txt" 2>&1 || true +done + +# Memory pass — separate, never combined with timing. +lcx_note "memory pass: mem_tracemalloc.py (separate pass)" 2>&1 | tee -a "$LCX_OUT_DIR/run-python.log" +"$PYBIN" mem_tracemalloc.py 2>&1 | tee "$RESULTS/mem_tracemalloc.txt" + +lcx_note "python launcher done; JSON + stats under $RESULTS" diff --git a/benchmarks/linux-crosscheck/run-rust.sh b/benchmarks/linux-crosscheck/run-rust.sh new file mode 100644 index 00000000..1aaa5cb6 --- /dev/null +++ b/benchmarks/linux-crosscheck/run-rust.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# run-rust.sh — Criterion launcher. +# The Criterion builder config (3 s warm-up / 10 s measurement / 100 samples / 0.95 CI / +# configure_from_args) lives in the bench sources and carries byte-identical to Linux; +# this launcher only invokes `cargo bench -- --noplot`. No pinning, no priority +# (the tuned system is the isolation). +# The instability trigger (95% CI half-width > 5% of mean -> full-suite taskset re-run) +# is applied by the operator as one recorded environment change, never per-cell. +# +# usage: ./run-rust.sh [--smoke] [--no-tune-check] +# --smoke overrides the builder via configure_from_args: +# --warm-up-time 1 --measurement-time 1 --sample-size 10 (functional only) + +set -euo pipefail +. "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/common.sh" +lcx_parse_launcher_args "$@" +lcx_mkout +lcx_launcher_header "rust (Criterion)" 2>&1 | tee "$LCX_OUT_DIR/run-rust.log" + +cd "$LCX_REPO_ROOT/benchmarks/rust" + +# Gate first: the ecosystem's own gate binary, unmodified. +lcx_note "gate: cargo run --release --bin gate" 2>&1 | tee -a "$LCX_OUT_DIR/run-rust.log" +cargo run --release --bin gate 2>&1 | tee -a "$LCX_OUT_DIR/run-rust.log" + +# Explicit --bench target list: the crate's lib target does not set `bench = false`, +# so a bare `cargo bench -- --noplot` (and even `--benches`, which also selects the +# lib) runs the libtest bench harness over src/lib.rs unittests, which rejects +# Criterion's flags ("error: Unrecognized option: 'noplot'") — found in the WSL +# functional pass. The bench sources are untouched; the flags only select the +# three Criterion bench targets (harness = false) from Cargo.toml. +BENCH_TARGETS=(--bench controlled --bench idiomatic --bench cold) +if [ "$LCX_SMOKE" = "1" ]; then + lcx_note "SMOKE: short Criterion pass via configure_from_args (no measurement validity)" 2>&1 | tee -a "$LCX_OUT_DIR/run-rust.log" + cargo bench "${BENCH_TARGETS[@]}" -- --noplot --warm-up-time 1 --measurement-time 1 --sample-size 10 2>&1 | tee -a "$LCX_OUT_DIR/run-rust.log" +else + # Measurement: builder defaults from source, --noplot only — identical to the Windows invocation. + cargo bench "${BENCH_TARGETS[@]}" -- --noplot 2>&1 | tee -a "$LCX_OUT_DIR/run-rust.log" +fi +lcx_note "rust launcher done; estimates.json under target/criterion (copied to the report dir at assembly)" diff --git a/benchmarks/linux-crosscheck/setup-toolchains.sh b/benchmarks/linux-crosscheck/setup-toolchains.sh new file mode 100644 index 00000000..aabb2b64 --- /dev/null +++ b/benchmarks/linux-crosscheck/setup-toolchains.sh @@ -0,0 +1,212 @@ +#!/usr/bin/env bash +# setup-toolchains.sh — install the pinned per-engine toolchains on Ubuntu 24.04 +# userland. Same version NUMBERS as the Windows runs, linux-x64 platform builds; +# every unavoidable difference lands in the version-deltas.md draft this script +# emits. +# +# usage: ./setup-toolchains.sh [--dry-run] [--allow-jdk-fallback] [--allow-python-fallback] +# +# --dry-run print the install plan and emit the version-deltas.md +# draft without installing anything +# --allow-jdk-fallback permit Temurin/JDK 23 when no Temurin 25 GA +# build is downloadable (recorded as a delta row) +# --allow-python-fallback permit deadsnakes python3.13 when no 3.14 is +# available for noble (recorded as a delta row); the +# primary fallback (source build of 3.14.6 with +# --enable-optimizations --with-lto) remains primary +# and is printed as such +# +# Failure surface: exit 1 per component, "pin unavailable: <component> <version>". + +set -euo pipefail +. "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/common.sh" + +# --- Pins (platform artifacts; version NUMBERS mirror the Windows pins) -------- +RUST_TOOLCHAIN="1.97.1" # rustup toolchain, host x86_64-unknown-linux-gnu +NODE_VERSION="24.18.0" # nodejs.org official linux-x64 tarball; concrete instance of the v24.x major pin +GO_VERSION="1.26.5" # go.dev/dl official linux-amd64 tarball +TEMURIN_MAJOR="25" # Temurin 25 GA linux-x64 +TEMURIN_FALLBACK_MAJOR="23" # fallback (flag-gated, delta-recorded) +PYTHON_MINOR="3.14" # deadsnakes python3.14 +PYTHON_SOURCE_FALLBACK="3.14.6" # fallback source build; concrete instance of the 3.14.x minor pin +PYTHON_LAST_RESORT_MINOR="3.13" # last-resort fallback (flag-gated, delta-recorded) + +# .NET SDK: pinned to the exact Windows-run SDK version, read from the published +# Windows protocol report's environment block. No such report is published yet, +# so this is PARAMETERIZED with the current 10.x line observed on the Windows machine. +# Before the bare-metal run, replace/override with the published env-block value: +# DOTNET_SDK_VERSION=<published value> ./setup-toolchains.sh +DOTNET_SDK_VERSION="${DOTNET_SDK_VERSION:-10.0.302}" # placeholder — see note above + +INSTALL_ROOT="${LCX_TOOLCHAIN_ROOT:-$HOME/heddle-toolchains}" + +DRY_RUN=0 +ALLOW_JDK_FALLBACK=0 +ALLOW_PY_FALLBACK=0 +while [ $# -gt 0 ]; do + case "$1" in + --dry-run) DRY_RUN=1 ;; + --allow-jdk-fallback) ALLOW_JDK_FALLBACK=1 ;; + --allow-python-fallback) ALLOW_PY_FALLBACK=1 ;; + -h|--help) + awk 'NR > 1 { if ($0 !~ /^#/) exit; sub(/^# ?/, ""); print }' "${BASH_SOURCE[0]}" + exit 0 ;; + *) lcx_die "unknown argument: $1" ;; + esac + shift +done + +lcx_mkout +DELTAS="$LCX_OUT_DIR/version-deltas.md" + +pin_unavailable() { # component version + echo "pin unavailable: $1 $2" >&2 + exit 1 +} + +run() { + if [ "$DRY_RUN" = "1" ]; then + echo "DRY-RUN: $*" + else + "$@" + fi +} + +delta_rows=() +add_delta_row() { # component windows_value linux_value delta caveat + delta_rows+=("| $1 | $2 | $3 | $4 | $5 |") +} + +lcx_note "install root: $INSTALL_ROOT (tarball toolchains); dry-run=$DRY_RUN" +run mkdir -p "$INSTALL_ROOT" + +# --- Rust: rustup pin --------------------------------------------------------- +lcx_note "Rust: rustup toolchain install $RUST_TOOLCHAIN (host x86_64-unknown-linux-gnu)" +if [ "$DRY_RUN" = "1" ]; then + echo "DRY-RUN: rustup toolchain install $RUST_TOOLCHAIN --profile minimal" +else + command -v rustup >/dev/null 2>&1 || pin_unavailable "rustup" "(rustup itself missing — install via https://rustup.rs, then re-run)" + rustup toolchain install "$RUST_TOOLCHAIN" --profile minimal || pin_unavailable "rust" "$RUST_TOOLCHAIN" + rustup run "$RUST_TOOLCHAIN" rustc -vV +fi +add_delta_row "Rust toolchain" "$RUST_TOOLCHAIN (windows-msvc)" "$RUST_TOOLCHAIN (x86_64-unknown-linux-gnu)" "no (platform build only)" "—" + +# --- Node: official linux-x64 tarball ---------------------------------------- +NODE_TARBALL="node-v${NODE_VERSION}-linux-x64.tar.xz" +NODE_URL="https://nodejs.org/dist/v${NODE_VERSION}/${NODE_TARBALL}" +lcx_note "Node: $NODE_URL" +if [ "$DRY_RUN" = "1" ]; then + echo "DRY-RUN: curl -fLO $NODE_URL && tar -C $INSTALL_ROOT -xJf $NODE_TARBALL" +else + curl -fL -o "$INSTALL_ROOT/$NODE_TARBALL" "$NODE_URL" || pin_unavailable "node" "$NODE_VERSION" + tar -C "$INSTALL_ROOT" -xJf "$INSTALL_ROOT/$NODE_TARBALL" +fi +add_delta_row "Node.js" "$NODE_VERSION (win-x64)" "$NODE_VERSION (linux-x64)" "no (platform build only)" "—" + +# --- Go: official linux-amd64 tarball ---------------------------------------- +GO_TARBALL="go${GO_VERSION}.linux-amd64.tar.gz" +GO_URL="https://go.dev/dl/${GO_TARBALL}" +lcx_note "Go: $GO_URL" +if [ "$DRY_RUN" = "1" ]; then + echo "DRY-RUN: curl -fLO $GO_URL && tar -C $INSTALL_ROOT -xzf $GO_TARBALL" +else + curl -fL -o "$INSTALL_ROOT/$GO_TARBALL" "$GO_URL" || pin_unavailable "go" "$GO_VERSION" + rm -rf "$INSTALL_ROOT/go" + tar -C "$INSTALL_ROOT" -xzf "$INSTALL_ROOT/$GO_TARBALL" + "$INSTALL_ROOT/go/bin/go" version +fi +add_delta_row "Go" "$GO_VERSION (windows/amd64)" "$GO_VERSION (linux/amd64)" "no (platform build only)" "—" + +# --- .NET SDK: dotnet-install.sh at the Windows-run version (parameterized) ---- +lcx_note ".NET SDK: dotnet-install.sh --version $DOTNET_SDK_VERSION (placeholder until a Windows protocol report publishes the env-block value)" +if [ "$DRY_RUN" = "1" ]; then + echo "DRY-RUN: curl -fL https://dot.net/v1/dotnet-install.sh | bash -s -- --version $DOTNET_SDK_VERSION --install-dir $INSTALL_ROOT/dotnet" +else + curl -fL -o "$INSTALL_ROOT/dotnet-install.sh" https://dot.net/v1/dotnet-install.sh || pin_unavailable "dotnet-install.sh" "(download failed)" + bash "$INSTALL_ROOT/dotnet-install.sh" --version "$DOTNET_SDK_VERSION" --install-dir "$INSTALL_ROOT/dotnet" || pin_unavailable "dotnet-sdk" "$DOTNET_SDK_VERSION" + "$INSTALL_ROOT/dotnet/dotnet" --version +fi +add_delta_row ".NET SDK" "TBD — no published Windows protocol report yet" "$DOTNET_SDK_VERSION (linux-x64)" "**pending**" "re-baseline against the published Windows report's environment block before the bare-metal run" + +# --- Temurin: 25 GA linux-x64, fallback to 23 behind a flag -------------------- +temurin_install() { # major -> 0 on success + local major="$1" + local api="https://api.adoptium.net/v3/binary/latest/${major}/ga/linux/x64/jdk/hotspot/normal/eclipse" + lcx_note "Temurin: $api" + if [ "$DRY_RUN" = "1" ]; then + echo "DRY-RUN: curl -fL -o temurin-${major}.tar.gz '$api' && tar -C $INSTALL_ROOT -xzf temurin-${major}.tar.gz" + return 0 + fi + curl -fL -o "$INSTALL_ROOT/temurin-${major}.tar.gz" "$api" || return 1 + tar -C "$INSTALL_ROOT" -xzf "$INSTALL_ROOT/temurin-${major}.tar.gz" || return 1 +} +if temurin_install "$TEMURIN_MAJOR"; then + add_delta_row "Temurin JDK" "Temurin $TEMURIN_MAJOR (windows x64)" "Temurin $TEMURIN_MAJOR (linux x64; exact GA build recorded from 'java -version')" "no (platform build only; GA-build delta recorded if the Windows build is no longer published)" "—" +else + if [ "$ALLOW_JDK_FALLBACK" = "1" ]; then + lcx_note "Temurin $TEMURIN_MAJOR unavailable; fallback to Temurin $TEMURIN_FALLBACK_MAJOR (flag-enabled, delta recorded)" + temurin_install "$TEMURIN_FALLBACK_MAJOR" || pin_unavailable "temurin" "$TEMURIN_MAJOR (and fallback $TEMURIN_FALLBACK_MAJOR)" + add_delta_row "Temurin JDK" "Temurin $TEMURIN_MAJOR (windows x64)" "Temurin $TEMURIN_FALLBACK_MAJOR (linux x64) — flag-enabled fallback" "**yes**" "inline caveat obligation on every JVM findings-validation statement" + else + pin_unavailable "temurin" "$TEMURIN_MAJOR (pass --allow-jdk-fallback to permit the JDK-$TEMURIN_FALLBACK_MAJOR fallback, recorded as a delta)" + fi +fi + +# --- CPython: deadsnakes 3.14; source-build fallback; 3.13 behind a flag ------- +lcx_note "CPython: deadsnakes PPA python${PYTHON_MINOR}" +deadsnakes_install() { # minor + local minor="$1" + if [ "$DRY_RUN" = "1" ]; then + echo "DRY-RUN: sudo add-apt-repository -y ppa:deadsnakes/ppa && sudo apt-get update" + echo "DRY-RUN: sudo apt-get install -y python${minor} python${minor}-venv python${minor}-dev" + return 0 + fi + sudo add-apt-repository -y ppa:deadsnakes/ppa || return 1 + sudo apt-get update || return 1 + sudo apt-get install -y "python${minor}" "python${minor}-venv" "python${minor}-dev" || return 1 + "python${minor}" -VV +} +if deadsnakes_install "$PYTHON_MINOR"; then + add_delta_row "CPython" "3.14.x python.org PGO installer (Windows)" "deadsnakes python${PYTHON_MINOR} (micro + package version recorded post-install; build provenance from CONFIG_ARGS)" "micro delta recorded if PPA differs from the Windows run's micro" "provenance disclosed in the toolchain table" +else + echo "setup-toolchains.sh: deadsnakes python${PYTHON_MINOR} unavailable for noble." >&2 + echo " primary fallback: source-build CPython ${PYTHON_SOURCE_FALLBACK} with" >&2 + echo " ./configure --enable-optimizations --with-lto (record CONFIG_ARGS + compiler)" >&2 + if [ "$ALLOW_PY_FALLBACK" = "1" ]; then + lcx_note "last-resort fallback: deadsnakes python${PYTHON_LAST_RESORT_MINOR} (flag-enabled, delta recorded)" + deadsnakes_install "$PYTHON_LAST_RESORT_MINOR" || pin_unavailable "cpython" "$PYTHON_MINOR (and fallback $PYTHON_LAST_RESORT_MINOR)" + add_delta_row "CPython" "3.14.x python.org PGO installer (Windows)" "deadsnakes python${PYTHON_LAST_RESORT_MINOR} — last-resort fallback (the primary fallback is a ${PYTHON_SOURCE_FALLBACK} source build)" "**yes (minor)**" "inline caveat obligation on every Python findings-validation statement" + else + pin_unavailable "cpython" "$PYTHON_MINOR (use the ${PYTHON_SOURCE_FALLBACK} source-build fallback, or pass --allow-python-fallback for the ${PYTHON_LAST_RESORT_MINOR} fallback, recorded as a delta)" + fi +fi + +# --- version-deltas.md draft --------------------------------------------------- +{ + echo "# version-deltas.md — DRAFT (finalized at publication)" + echo + echo "Baseline rule: the delta is measured against **each published Windows report's" + echo "environment block**, not against planning tables. No Windows protocol report is" + echo "published yet, so the Windows-value column below is provisional and every row must be" + echo "re-baselined before the bare-metal run." + echo + echo "| component | Windows source run value (with report link) | Linux value | delta? | caveat obligation |" + echo "|---|---|---|---|---|" + for row in "${delta_rows[@]}"; do echo "$row"; done + echo + echo "Library pins (Cargo.lock, pom.xml, package-lock.json, requirements.txt, go.mod, csproj)" + echo "are platform-independent and verified by each harness's own reproduce path; they" + echo "appear here only if an install proves impossible at the pinned version." + echo + echo "Zero deltas is the target; this table is published even when empty." +} > "$DELTAS" +lcx_note "version-deltas.md draft -> $DELTAS" + +if [ "$DRY_RUN" = "1" ]; then + lcx_note "dry-run complete — nothing installed." +else + lcx_note "toolchain installs complete. Add to PATH for the session:" + echo " export PATH=\"$INSTALL_ROOT/node-v${NODE_VERSION}-linux-x64/bin:$INSTALL_ROOT/go/bin:$INSTALL_ROOT/dotnet:\$PATH\"" + echo " export DOTNET_ROOT=\"$INSTALL_ROOT/dotnet\"" + echo " export JAVA_HOME=\"\$(ls -d $INSTALL_ROOT/jdk-* 2>/dev/null | head -n 1)\"; export PATH=\"\$JAVA_HOME/bin:\$PATH\"" +fi diff --git a/benchmarks/linux-crosscheck/test_validate.py b/benchmarks/linux-crosscheck/test_validate.py new file mode 100644 index 00000000..27df3f13 --- /dev/null +++ b/benchmarks/linux-crosscheck/test_validate.py @@ -0,0 +1,270 @@ +#!/usr/bin/env python3 +"""test_validate.py — threshold-straddling fixtures for validate.py: +resolved/unresolved rank flips, gap movement on both sides of max(D, 0.05), +dispersion ratio and 1% floor boundaries, the min(d)=0 zero-dispersion guard, +and the structural rejection of absolute-time fields. +stdlib-only; run: python3 test_validate.py +""" + +import copy +import unittest + +import validate as v + + +def wcell(engine_r, engine_d, heddle_d, rank=2): + return { + "engines": { + "engineA": {"rank": rank, "r": engine_r, "d": engine_d, + "source": "docs/benchmarks/2099-01-01/example-report.md"}, + }, + "heddle": {"r": 1.0, "d": heddle_d, + "source": "docs/benchmarks/2099-01-01/example-report.md"}, + } + + +def lcell(engine_r, engine_d, heddle_d): + return { + "engines": {"engineA": {"r": engine_r, "d": engine_d}}, + "heddle": {"r": 1.0, "d": heddle_d}, + } + + +def windows_doc(cell): + return { + "schema": v.SCHEMA_ID, + "ecosystems": {"rust": {"tracks": {"controlled": {"cells": {"composed-page": cell}}}}}, + } + + +def linux_doc(cell): + return { + "ecosystems": {"rust": {"tracks": {"controlled": {"cells": {"composed-page": cell}}}}}, + } + + +class TestRankFlip(unittest.TestCase): + """A rank flip is material iff order differs AND resolved on BOTH OSes.""" + + def test_resolved_flip_is_material(self): + verdict = v.rank_flip_verdict( + 1.2, 0.01, 1.5, 0.01, # Windows: A < B, resolved (0.3 > 0.024) + 1.5, 0.01, 1.2, 0.01, # Linux: A > B, resolved + ) + self.assertEqual(verdict, "material flip") + + def test_flip_unresolved_on_one_os_is_not_material(self): + verdict = v.rank_flip_verdict( + 1.2, 0.01, 1.5, 0.01, # Windows resolved + 1.32, 0.05, 1.30, 0.05, # Linux flipped but 0.02 <= 0.1*1.30 + ) + self.assertEqual(verdict, "not resolved") + + def test_same_order_is_held(self): + verdict = v.rank_flip_verdict( + 1.2, 0.01, 1.5, 0.01, + 1.1, 0.01, 1.6, 0.01, + ) + self.assertEqual(verdict, "held") + + def test_resolution_boundary_exact_is_unresolved(self): + # |r_A - r_B| == (d_A + d_B) * min(r_A, r_B) exactly -> strict > fails. + # Binary-exact values: |1.0 - 1.5| = 0.5 == (0.25 + 0.25) * 1.0. + self.assertFalse(v.pair_resolved(1.0, 0.25, 1.5, 0.25)) # 0.5 == 0.5 + self.assertTrue(v.pair_resolved(1.0, 0.25, 1.53, 0.25)) # 0.53 > 0.5 + # A flip whose Windows side sits exactly on the boundary is not material. + verdict = v.rank_flip_verdict( + 1.0, 0.25, 1.5, 0.25, # Windows: exactly at threshold -> unresolved + 1.4, 0.01, 1.2, 0.01, # Linux: flipped and resolved + ) + self.assertEqual(verdict, "not resolved") + + +class TestGapMovement(unittest.TestCase): + """Gap movement |r_L/r_W − 1| is material above max(D, 0.05); D is a LINEAR sum.""" + + def test_linear_sum_not_quadrature(self): + self.assertAlmostEqual(v.combined_dispersion(0.01, 0.02, 0.03, 0.04), 0.10) + + def test_floor_active_just_above(self): + # D = 0.02 < floor 0.05 -> threshold is 0.05. + d_sum = v.combined_dispersion(0.005, 0.005, 0.005, 0.005) + self.assertAlmostEqual(d_sum, 0.02) + self.assertTrue(v.gap_material(v.gap_movement(1.0, 1.0501), d_sum)) + + def test_floor_active_just_below(self): + d_sum = v.combined_dispersion(0.005, 0.005, 0.005, 0.005) + self.assertFalse(v.gap_material(v.gap_movement(1.0, 1.0499), d_sum)) + + def test_floor_boundary_exact_is_not_material(self): + # movement == 0.05 exactly -> strict > fails. + self.assertFalse(v.gap_material(0.05, 0.02)) + + def test_dispersion_dominant_just_above(self): + # D = 0.08 > floor -> threshold is D. + d_sum = v.combined_dispersion(0.02, 0.02, 0.02, 0.02) + self.assertAlmostEqual(d_sum, 0.08) + self.assertTrue(v.gap_material(v.gap_movement(1.0, 1.081), d_sum)) + + def test_dispersion_dominant_just_below(self): + d_sum = v.combined_dispersion(0.02, 0.02, 0.02, 0.02) + self.assertFalse(v.gap_material(v.gap_movement(1.0, 1.079), d_sum)) + + def test_dispersion_boundary_exact_is_not_material(self): + self.assertFalse(v.gap_material(0.08, 0.08)) + + def test_movement_is_symmetric_ratio_form(self): + self.assertAlmostEqual(v.gap_movement(2.0, 1.0), 0.5) + self.assertAlmostEqual(v.gap_movement(1.0, 2.0), 1.0) + + +class TestDispersionCharacter(unittest.TestCase): + """Dispersion character: ratio ≥ 2 AND max ≥ 0.01, with the zero-dispersion guard.""" + + def test_ratio_exactly_two_with_max_at_floor_is_material(self): + self.assertTrue(v.dispersion_character_change(0.005, 0.01)) # ratio 2, max 0.01 + + def test_ratio_just_below_two_is_not_material(self): + self.assertFalse(v.dispersion_character_change(0.01, 0.0199)) + + def test_ratio_above_two_but_below_one_percent_floor_is_not_material(self): + self.assertFalse(v.dispersion_character_change(0.004, 0.009)) # ratio 2.25, max < 0.01 + + def test_order_symmetric(self): + self.assertTrue(v.dispersion_character_change(0.02, 0.005)) + self.assertTrue(v.dispersion_character_change(0.005, 0.02)) + + def test_zero_dispersion_guard_material_above_floor(self): + # min(d)=0: no division; material iff max >= 0.01. + self.assertTrue(v.dispersion_character_change(0.0, 0.012)) + + def test_zero_dispersion_guard_not_material_below_floor(self): + self.assertFalse(v.dispersion_character_change(0.0, 0.009)) + + def test_zero_vs_zero_is_not_material(self): + self.assertFalse(v.dispersion_character_change(0.0, 0.0)) + + def test_zero_dispersion_never_raises(self): + try: + v.dispersion_character_change(0.0, 0.5) + v.dispersion_character_change(0.5, 0.0) + except ZeroDivisionError: # pragma: no cover + self.fail("zero-dispersion guard divided by zero") + + +class TestStructuralRejection(unittest.TestCase): + """Any absolute-time field is rejected; Windows-side citations are mandatory.""" + + def test_valid_input_loads(self): + doc = windows_doc(wcell(1.2, 0.01, 0.008)) + v.load_side(doc, windows=True) # must not raise + + def test_absolute_time_field_rejected_top_level(self): + doc = windows_doc(wcell(1.2, 0.01, 0.008)) + doc["meanTimeNs"] = 123.4 + with self.assertRaises(v.ValidationError) as ctx: + v.load_side(doc, windows=True) + self.assertIn("absolute-time", str(ctx.exception)) + + def test_absolute_time_field_rejected_inside_cell(self): + doc = windows_doc(wcell(1.2, 0.01, 0.008)) + cell = doc["ecosystems"]["rust"]["tracks"]["controlled"]["cells"]["composed-page"] + cell["engines"]["engineA"]["point_estimate"] = 41.5 + with self.assertRaises(v.ValidationError) as ctx: + v.load_side(doc, windows=True) + self.assertIn("absolute-time", str(ctx.exception)) + + def test_absolute_time_field_rejected_on_linux_side_too(self): + doc = linux_doc(lcell(1.2, 0.01, 0.008)) + cell = doc["ecosystems"]["rust"]["tracks"]["controlled"]["cells"]["composed-page"] + cell["heddle"]["wall_time_ms"] = 0.9 + with self.assertRaises(v.ValidationError): + v.load_side(doc, windows=False) + + def test_unknown_key_on_value_object_rejected(self): + doc = windows_doc(wcell(1.2, 0.01, 0.008)) + cell = doc["ecosystems"]["rust"]["tracks"]["controlled"]["cells"]["composed-page"] + cell["engines"]["engineA"]["throughput"] = 9.9 + with self.assertRaises(v.ValidationError): + v.load_side(doc, windows=True) + + def test_citationless_windows_entry_rejected(self): + doc = windows_doc(wcell(1.2, 0.01, 0.008)) + cell = doc["ecosystems"]["rust"]["tracks"]["controlled"]["cells"]["composed-page"] + del cell["engines"]["engineA"]["source"] + with self.assertRaises(v.ValidationError) as ctx: + v.load_side(doc, windows=True) + self.assertIn("source", str(ctx.exception)) + + def test_linux_side_does_not_require_citations(self): + v.load_side(linux_doc(lcell(1.2, 0.01, 0.008)), windows=False) + + def test_wrong_schema_id_rejected(self): + doc = windows_doc(wcell(1.2, 0.01, 0.008)) + doc["schema"] = "something-else" + with self.assertRaises(v.ValidationError): + v.load_side(doc, windows=True) + + def test_missing_windows_rank_rejected(self): + doc = windows_doc(wcell(1.2, 0.01, 0.008)) + cell = doc["ecosystems"]["rust"]["tracks"]["controlled"]["cells"]["composed-page"] + del cell["engines"]["engineA"]["rank"] + with self.assertRaises(v.ValidationError): + v.load_side(doc, windows=True) + + def test_nonpositive_ratio_rejected(self): + doc = windows_doc(wcell(1.2, 0.01, 0.008)) + cell = doc["ecosystems"]["rust"]["tracks"]["controlled"]["cells"]["composed-page"] + cell["engines"]["engineA"]["r"] = 0.0 + with self.assertRaises(v.ValidationError): + v.load_side(doc, windows=True) + + +class TestEndToEnd(unittest.TestCase): + """Whole-pipeline checks: verdicts are data; everything is published.""" + + def test_tables_publish_every_cell_regardless_of_verdict(self): + w = v.load_side(windows_doc(wcell(1.2, 0.005, 0.005)), windows=True) + l = v.load_side(linux_doc(lcell(1.21, 0.005, 0.005)), windows=False) + results = v.validate_all(w, l) + cell = results["rust"]["controlled"]["composed-page"] + row = cell["engines"]["engineA"] + self.assertFalse(row["gap_material"]) # 0.83% movement, under floor + self.assertFalse(row["dispersion_change"]) + md = v.render_markdown(results) + for token in ("r_W", "r_L", "movement %", "engineA", "Heddle (anchor)"): + self.assertIn(token, md) + + def test_material_gap_end_to_end(self): + w = v.load_side(windows_doc(wcell(1.0, 0.005, 0.005)), windows=True) + l = v.load_side(linux_doc(lcell(1.10, 0.005, 0.005)), windows=False) + cell = v.validate_all(w, l)["rust"]["controlled"]["composed-page"] + self.assertTrue(cell["engines"]["engineA"]["gap_material"]) # 10% > max(0.02, 0.05) + + def test_zero_dispersion_cell_end_to_end(self): + # A min(d)=0 cell flows through validate_all safely. + w = v.load_side(windows_doc(wcell(1.2, 0.0, 0.0)), windows=True) + l = v.load_side(linux_doc(lcell(1.2, 0.012, 0.0)), windows=False) + cell = v.validate_all(w, l)["rust"]["controlled"]["composed-page"] + self.assertTrue(cell["engines"]["engineA"]["dispersion_change"]) # 0 -> 1.2% + self.assertFalse(cell["heddle"]["dispersion_change"]) # 0 vs 0 + + def test_absent_linux_ecosystem_reported_not_crashed(self): + w = v.load_side(windows_doc(wcell(1.2, 0.01, 0.008)), windows=True) + l = copy.deepcopy(linux_doc(lcell(1.2, 0.01, 0.008))) + l["ecosystems"]["go"] = l["ecosystems"].pop("rust") + l = v.load_side(l, windows=False) + results = v.validate_all(w, l) + self.assertIn("absent on Linux", results["rust"]["status"]) + + def test_heddle_anchor_participates_in_rank_pairs(self): + # Engine crosses the anchor between OSes, resolved on both -> material flip. + w = v.load_side(windows_doc(wcell(0.8, 0.01, 0.01)), windows=True) + l = v.load_side(linux_doc(lcell(1.3, 0.01, 0.01)), windows=False) + cell = v.validate_all(w, l)["rust"]["controlled"]["composed-page"] + pair_verdicts = {tuple(p["pair"]): p["verdict"] for p in cell["pairs"]} + self.assertEqual(pair_verdicts[("engineA", "Heddle")], "material flip") + + +if __name__ == "__main__": + unittest.main(verbosity=2) diff --git a/benchmarks/linux-crosscheck/tune.sh b/benchmarks/linux-crosscheck/tune.sh new file mode 100755 index 00000000..787dd5b4 --- /dev/null +++ b/benchmarks/linux-crosscheck/tune.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash +# tune.sh — enter the one measurement-session state (isolation precondition, +# machine-wide pyperf tune, boost off, state capture) and assert every +# post-condition (governor, boost=0, sample rate, isolated set). +# +# BARE-METAL ONLY. Under WSL2 this script fails cleanly by design — WSL +# exposes no cpufreq policy, no boost control, no isolcpus boot and no real tune +# surface; the failure below IS the designed WSL outcome, not a defect. +# +# Run as: sudo ./tune.sh (pyperf system tune and the boost write need root) + +set -euo pipefail +. "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/common.sh" + +lcx_mkout + +fail_bare_metal_only() { + echo "tune.sh: BARE-METAL-ONLY OPERATION — $1" >&2 + echo "tune.sh: the tuned session state (pyperf system tune, amd-pstate boost-off, isolcpus pair)" >&2 + echo "tune.sh: exists only on the bare-metal Ubuntu Server 24.04 boot of the protocol box." >&2 + echo "tune.sh: Under WSL2 this failure is the designed outcome; the tune/untune work" >&2 + echo "tune.sh: is deferred to bare metal, not faked here." >&2 + exit 1 +} + +# --- Step 0: refuse WSL up front (designed failure) ---------------------------- +if lcx_is_wsl; then + fail_bare_metal_only "WSL2 detected via /proc/version" +fi + +# --- Step 1 precondition: isolation boot entry active ------------------------- +# The SMT pair is READ from the topology, never assumed. +if ! PAIR="$(lcx_smt_pair)"; then + fail_bare_metal_only "cannot read /sys/devices/system/cpu/cpu${LCX_ISOLATION_CPU}/topology/thread_siblings_list (no per-CPU topology on this kernel)" +fi +lcx_note "SMT sibling pair of cpu${LCX_ISOLATION_CPU}'s physical core (read, not assumed): ${PAIR}" + +ISOLATED_FILE="/sys/devices/system/cpu/isolated" +if [ ! -r "$ISOLATED_FILE" ]; then + fail_bare_metal_only "cannot read $ISOLATED_FILE" +fi +ISOLATED="$(cat "$ISOLATED_FILE")" +if [ -z "$ISOLATED" ]; then + echo "tune.sh: ASSERT FAILED (isolated set): /sys/devices/system/cpu/isolated is empty —" >&2 + echo "tune.sh: the 'Ubuntu — benchmark isolation' GRUB entry is not booted (bare-metal-only" >&2 + echo "tune.sh: precondition; see grub-isolation.cfg.example)." >&2 + exit 1 +fi +lcx_note "isolated set: ${ISOLATED} (expected: ${PAIR})" +if [ "$ISOLATED" != "$PAIR" ]; then + echo "tune.sh: ASSERT FAILED (isolated set): isolated='${ISOLATED}' does not equal the read" >&2 + echo "tune.sh: sibling pair '${PAIR}' — re-check the instantiated GRUB entry (bare-metal-only item)." >&2 + exit 1 +fi + +# --- Step 2: machine-wide pyperf system tune ---------------------------------- +lcx_note "running: python3 -m pyperf system tune (machine-wide)" +python3 -m pyperf system tune + +# --- Step 3: boost explicitly off via the amd-pstate cpufreq control ---------- +BOOST_FILE="/sys/devices/system/cpu/cpufreq/boost" +if [ ! -e "$BOOST_FILE" ]; then + fail_bare_metal_only "no $BOOST_FILE (amd-pstate boost control absent on this kernel/platform)" +fi +# Record prior state for untune.sh. +cat "$BOOST_FILE" > "$LCX_OUT_DIR/boost-prior.txt" +echo 0 > "$BOOST_FILE" + +# --- Post-condition asserts (fail if any item does not read back) -------------- +assert_eq() { # label expected actual + if [ "$2" != "$3" ]; then + echo "tune.sh: ASSERT FAILED ($1): expected '$2', read back '$3'." >&2 + echo "tune.sh: a post-condition that cannot be satisfied here means this is not the tuned" >&2 + echo "tune.sh: bare-metal measurement boot (bare-metal-only operation, deferred under WSL)." >&2 + exit 1 + fi + lcx_note "post-condition OK ($1): $3" +} + +# Governor: every policy must read 'performance'. +GOVS="$(cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 2>/dev/null | sort -u || true)" +if [ -z "$GOVS" ]; then + fail_bare_metal_only "no cpufreq scaling_governor files exposed" +fi +assert_eq "governor (all policies)" "performance" "$GOVS" + +# Boost: must read back 0. +assert_eq "boost" "0" "$(cat "$BOOST_FILE")" + +# perf sample rate: pyperf system tune sets 1. +SAMPLE_RATE="$(sysctl -n kernel.perf_event_max_sample_rate)" +assert_eq "perf_event_max_sample_rate" "1" "$SAMPLE_RATE" + +# Isolated set unchanged post-tune. +assert_eq "isolated set" "$PAIR" "$(cat "$ISOLATED_FILE")" + +# --- Step 4: capture the authoritative post-tune state ------------------------ +lcx_note "capturing 'pyperf system show' -> $LCX_STATE_FILE (authoritative session-state record)" +python3 -m pyperf system show | tee "$LCX_STATE_FILE" + +lcx_note "Session state entered. Isolated pair: ${PAIR}. Run capture-environment.sh next." +lcx_note "Every run-*.sh will pre-flight against $LCX_STATE_FILE before timing." diff --git a/benchmarks/linux-crosscheck/untune.sh b/benchmarks/linux-crosscheck/untune.sh new file mode 100755 index 00000000..ca8188f5 --- /dev/null +++ b/benchmarks/linux-crosscheck/untune.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# untune.sh — exit the measurement-session state: +# pyperf system reset, boost restored, session state file retired. +# +# BARE-METAL ONLY. Under WSL2 this fails cleanly by design — there is no +# tuned state to undo; that failure is the designed outcome, not a defect. +# +# Run as: sudo ./untune.sh + +set -euo pipefail +. "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)/common.sh" + +fail_bare_metal_only() { + echo "untune.sh: BARE-METAL-ONLY OPERATION — $1" >&2 + echo "untune.sh: there is no tuned state to undo except on the bare-metal measurement" >&2 + echo "untune.sh: boot; under WSL2 this failure is the designed outcome (deferred to bare metal)." >&2 + exit 1 +} + +if lcx_is_wsl; then + fail_bare_metal_only "WSL2 detected via /proc/version" +fi + +# --- pyperf system reset (documented: governor, frequency, irqbalance, sample rate restored) +lcx_note "running: python3 -m pyperf system reset" +python3 -m pyperf system reset + +# --- Restore boost to its pre-tune value (recorded by tune.sh) ---------------- +BOOST_FILE="/sys/devices/system/cpu/cpufreq/boost" +if [ ! -e "$BOOST_FILE" ]; then + fail_bare_metal_only "no $BOOST_FILE (amd-pstate boost control absent)" +fi +PRIOR="1" +if [ -f "$LCX_OUT_DIR/boost-prior.txt" ]; then + PRIOR="$(cat "$LCX_OUT_DIR/boost-prior.txt")" +else + lcx_note "no recorded prior boost state ($LCX_OUT_DIR/boost-prior.txt) — restoring default 1" +fi +echo "$PRIOR" > "$BOOST_FILE" +lcx_note "boost restored to: $(cat "$BOOST_FILE")" + +# --- Confirm via pyperf system show, then retire the session-state baseline --- +lcx_note "post-reset 'pyperf system show' (confirmation record):" +python3 -m pyperf system show || true + +if [ -f "$LCX_STATE_FILE" ]; then + mv "$LCX_STATE_FILE" "$LCX_STATE_FILE.retired.$(date -u +%Y%m%dT%H%M%SZ)" + lcx_note "session state file retired — run-*.sh pre-flights will now refuse to run." +fi + +lcx_note "Tuned state exited. Reboot to the DEFAULT GRUB entry before any non-measurement use" +lcx_note "(the isolation entry must not remain the running boot outside a session)." diff --git a/benchmarks/linux-crosscheck/validate.py b/benchmarks/linux-crosscheck/validate.py new file mode 100644 index 00000000..7b8ef86c --- /dev/null +++ b/benchmarks/linux-crosscheck/validate.py @@ -0,0 +1,354 @@ +#!/usr/bin/env python3 +"""validate.py — findings-validation tooling for the Linux cross-check (stdlib-only). + +Computes every part-2 validation table and verdict from exactly two inputs: + + (a) ``windows-source.json`` — hand-transcribed Windows ranks, ratios-to-Heddle + (``r``, quoted from each report's own ratio column) and dimensionless + dispersions (``d``) with per-value source citations. NEVER absolute times + (structurally enforced below). + (b) ``linux-results.json`` — the same shape for this Linux run (part 1 data). + +Material-divergence verdicts: + 1. material rank flip — order differs across OSes AND the pair is resolved on + BOTH OSes: |r_A − r_B| > (d_A + d_B) · min(r_A, r_B), + evaluated on each OS's own ratios (ratio form — no + absolute time needed). + 2. material gap movement — |r_L / r_W − 1| > max(D, 0.05) with + D = (d_eng,W + d_Heddle,W) + (d_eng,L + d_Heddle,L) + (LINEAR sums — interval arithmetic, not quadrature). + 3. dispersion character — max(d_W, d_L) / min(d_W, d_L) ≥ 2 AND max ≥ 0.01; + zero-dispersion guard: when min = 0 the ratio is + undefined and the cell is material iff max ≥ 0.01 + (never divides by zero). + +Everything is published; "material" only controls prominence. Exit 1 on malformed +input (missing citation, absolute-time field, schema violation); verdicts are data, +not errors (exit 0). + +Usage: + python3 validate.py --windows-source windows-source.json \ + --linux-results linux-results.json [--out tables.md] +""" + +from __future__ import annotations + +import argparse +import json +import sys + +SCHEMA_ID = "heddle-linux-crosscheck/windows-source@1" + +GAP_FLOOR = 0.05 # the program's own established 5% stability line +DISPERSION_RATIO = 2.0 +DISPERSION_FLOOR = 0.01 # 1% relative-dispersion floor + +# No absolute-time / point-estimate field may appear ANYWHERE in either +# input. Closed list of forbidden key tokens (case-insensitive, matched on whole +# underscore/dash/camel-separated words so e.g. "meanTimeNs" and "wall_time" are +# both caught, while "rank"/"track" are not). +FORBIDDEN_KEY_TOKENS = frozenset({ + "time", "times", "ns", "us", "usec", "ms", "msec", "sec", "secs", "seconds", + "nanoseconds", "microseconds", "milliseconds", + "mean", "median", "min", "max", "avg", "average", "stddev", "stdev", "error", + "score", "point", "estimate", "wall", "elapsed", "duration", "p50", "p75", + "p99", "p999", "ci", "lower", "upper", "absolute", "bytes", "allocated", +}) + +# The only keys allowed on a value-carrying (engine / heddle) object. +ALLOWED_VALUE_KEYS = frozenset({"rank", "r", "d", "source", "note"}) + + +class ValidationError(Exception): + """Malformed input (exit 1).""" + + +def _split_key_tokens(key: str) -> list[str]: + out, word = [], [] + for ch in key: + if ch in "_- .": + if word: + out.append("".join(word).lower()) + word = [] + elif ch.isupper() and word and not word[-1].isupper(): + out.append("".join(word).lower()) + word = [ch] + else: + word.append(ch) + if word: + out.append("".join(word).lower()) + return out + + +def reject_absolute_time_fields(obj, path="$"): + """Structural check: reject ANY absolute-time-shaped field, recursively.""" + if isinstance(obj, dict): + for key, value in obj.items(): + if isinstance(key, str): + bad = [t for t in _split_key_tokens(key) if t in FORBIDDEN_KEY_TOKENS] + if bad: + raise ValidationError( + f"forbidden absolute-time/point-estimate field " + f"'{key}' at {path} (forbidden token(s): {', '.join(bad)}). " + f"windows-source.json stores only ranks, ratios (r) and " + f"dimensionless dispersions (d) — never absolute times." + ) + reject_absolute_time_fields(value, f"{path}.{key}") + elif isinstance(obj, list): + for i, value in enumerate(obj): + reject_absolute_time_fields(value, f"{path}[{i}]") + + +def _check_value_obj(obj, path, *, require_source, require_rank): + if not isinstance(obj, dict): + raise ValidationError(f"{path}: expected an object") + extra = set(obj) - ALLOWED_VALUE_KEYS + if extra: + raise ValidationError( + f"{path}: unexpected key(s) {sorted(extra)} — only " + f"{sorted(ALLOWED_VALUE_KEYS)} are allowed (structural rule: no " + f"absolute-time or other extra field may exist on a value object)" + ) + for field in ("r", "d"): + if field not in obj or not isinstance(obj[field], (int, float)) or isinstance(obj[field], bool): + raise ValidationError(f"{path}: missing or non-numeric '{field}'") + if obj[field] < 0: + raise ValidationError(f"{path}: '{field}' must be >= 0") + if obj["r"] <= 0: + raise ValidationError(f"{path}: 'r' must be > 0 (a wall-time ratio)") + if require_rank and ("rank" not in obj or not isinstance(obj["rank"], int) or isinstance(obj["rank"], bool)): + raise ValidationError(f"{path}: missing integer 'rank'") + if require_source and not (isinstance(obj.get("source"), str) and obj["source"].strip()): + raise ValidationError( + f"{path}: missing 'source' citation — every transcribed Windows value " + f"must cite its source file within the published Windows directory" + ) + + +def load_side(path_or_obj, *, windows: bool): + """Load + structurally validate one side (dict or file path).""" + if isinstance(path_or_obj, (str, bytes)): + with open(path_or_obj, "r", encoding="utf-8") as fh: + doc = json.load(fh) + else: + doc = path_or_obj + if not isinstance(doc, dict): + raise ValidationError("input root must be a JSON object") + reject_absolute_time_fields(doc) + if windows and doc.get("schema") != SCHEMA_ID: + raise ValidationError(f"windows-source: 'schema' must be '{SCHEMA_ID}'") + ecosystems = doc.get("ecosystems") + if not isinstance(ecosystems, dict) or not ecosystems: + raise ValidationError("input must carry a non-empty 'ecosystems' object") + for eco, eco_obj in ecosystems.items(): + tracks = eco_obj.get("tracks") + if not isinstance(tracks, dict) or not tracks: + raise ValidationError(f"ecosystems.{eco}: missing 'tracks'") + for track, track_obj in tracks.items(): + cells = track_obj.get("cells") + if not isinstance(cells, dict) or not cells: + raise ValidationError(f"ecosystems.{eco}.tracks.{track}: missing 'cells'") + for workload, cell in cells.items(): + base = f"ecosystems.{eco}.tracks.{track}.cells.{workload}" + engines = cell.get("engines") + if not isinstance(engines, dict) or not engines: + raise ValidationError(f"{base}: missing 'engines'") + for engine, vobj in engines.items(): + _check_value_obj(vobj, f"{base}.engines.{engine}", + require_source=windows, require_rank=windows) + heddle = cell.get("heddle") + _check_value_obj(heddle, f"{base}.heddle", + require_source=windows, require_rank=False) + return doc + + +# --- Material-divergence predicates (pure; unit-tested by test_validate.py) ---- + +def pair_resolved(r_a: float, d_a: float, r_b: float, d_b: float) -> bool: + """Order-resolution test in ratio form (strict >): the ratio gap must exceed + the summed dispersions scaled by the smaller ratio.""" + return abs(r_a - r_b) > (d_a + d_b) * min(r_a, r_b) + + +def rank_flip_verdict(r_a_w, d_a_w, r_b_w, d_b_w, r_a_l, d_a_l, r_b_l, d_b_l) -> str: + """Pairwise rank verdict: 'held' | 'not resolved' | 'material flip'. + A flip is material only when the pair is resolved on BOTH OSes.""" + order_w = (r_a_w > r_b_w) - (r_a_w < r_b_w) + order_l = (r_a_l > r_b_l) - (r_a_l < r_b_l) + if order_w == order_l: + return "held" + if pair_resolved(r_a_w, d_a_w, r_b_w, d_b_w) and pair_resolved(r_a_l, d_a_l, r_b_l, d_b_l): + return "material flip" + return "not resolved" + + +def gap_movement(r_w: float, r_l: float) -> float: + """Gap movement |r_L / r_W − 1| (r_w > 0 guaranteed by input validation).""" + return abs(r_l / r_w - 1.0) + + +def combined_dispersion(d_eng_w, d_heddle_w, d_eng_l, d_heddle_l) -> float: + """Combined dispersion D — LINEAR sums (interval arithmetic, not quadrature).""" + return (d_eng_w + d_heddle_w) + (d_eng_l + d_heddle_l) + + +def gap_material(movement: float, dispersion_sum: float) -> bool: + """Gap verdict: material iff movement > max(D, 0.05) (strict >).""" + return movement > max(dispersion_sum, GAP_FLOOR) + + +def dispersion_character_change(d_w: float, d_l: float) -> bool: + """Dispersion-character change: ratio ≥ 2 AND max ≥ 0.01, with the + zero-dispersion guard (min(d)=0 never divides by zero).""" + lo, hi = min(d_w, d_l), max(d_w, d_l) + if lo == 0.0: + # Appear-from-nothing dispersion above the 1% floor is material; + # a zero-vs-sub-1% pair is not. + return hi >= DISPERSION_FLOOR + return (hi / lo) >= DISPERSION_RATIO and hi >= DISPERSION_FLOOR + + +# --- Table computation --------------------------------------------------------- + +def validate_cell(win_cell: dict, lin_cell: dict) -> dict: + """All three material-divergence verdicts for one workload cell. Returns a plain dict.""" + result = {"engines": {}, "pairs": []} + win_h, lin_h = win_cell["heddle"], lin_cell["heddle"] + + common = [e for e in win_cell["engines"] if e in lin_cell["engines"]] + for engine in common: + w, l = win_cell["engines"][engine], lin_cell["engines"][engine] + movement = gap_movement(w["r"], l["r"]) + disp_sum = combined_dispersion(w["d"], win_h["d"], l["d"], lin_h["d"]) + result["engines"][engine] = { + "r_W": w["r"], "r_L": l["r"], + "d_W": w["d"], "d_L": l["d"], + "movement": movement, "D": disp_sum, + "gap_material": gap_material(movement, disp_sum), + "dispersion_change": dispersion_character_change(w["d"], l["d"]), + } + # Heddle anchor's own dispersion character (published like every cell value). + result["heddle"] = { + "d_W": win_h["d"], "d_L": lin_h["d"], + "dispersion_change": dispersion_character_change(win_h["d"], lin_h["d"]), + } + # Rank-flip verdicts pairwise over {engines + Heddle anchor} (r_Heddle from its own entry). + participants = [(e, win_cell["engines"][e], lin_cell["engines"][e]) for e in common] + participants.append(("Heddle", win_h, lin_h)) + for i in range(len(participants)): + for j in range(i + 1, len(participants)): + (name_a, wa, la), (name_b, wb, lb) = participants[i], participants[j] + verdict = rank_flip_verdict( + wa["r"], wa["d"], wb["r"], wb["d"], + la["r"], la["d"], lb["r"], lb["d"], + ) + result["pairs"].append({"pair": (name_a, name_b), "verdict": verdict}) + return result + + +def validate_all(windows_doc: dict, linux_doc: dict) -> dict: + out = {} + for eco, w_eco in windows_doc["ecosystems"].items(): + l_eco = linux_doc["ecosystems"].get(eco) + if l_eco is None: + out[eco] = {"status": "absent on Linux (manifest-recorded)"} + continue + eco_out = {} + for track, w_track in w_eco["tracks"].items(): + l_track = l_eco["tracks"].get(track) + if l_track is None: + eco_out[track] = {"status": "absent on Linux (manifest-recorded)"} + continue + track_out = {} + for workload, w_cell in w_track["cells"].items(): + l_cell = l_track["cells"].get(workload) + if l_cell is None: + track_out[workload] = {"status": "excluded/absent on Linux (manifest-recorded)"} + continue + track_out[workload] = validate_cell(w_cell, l_cell) + eco_out[track] = track_out + out[eco] = eco_out + return out + + +def render_markdown(results: dict) -> str: + """Part-2 validation tables. Every cell publishes r_W, r_L, movement %, D, d_W, + d_L and the verdicts — 'material' controls prominence, never visibility.""" + lines = ["# Findings validation — computed tables", ""] + for eco, eco_res in results.items(): + lines.append(f"## {eco}") + if "status" in eco_res: + lines += [f"> {eco_res['status']}", ""] + continue + for track, track_res in eco_res.items(): + lines.append(f"### track: {track}") + if "status" in track_res: + lines += [f"> {track_res['status']}", ""] + continue + lines.append("") + lines.append("| workload | engine | r_W | r_L | movement % | D | d_W | d_L | gap verdict | dispersion verdict |") + lines.append("|---|---|---|---|---|---|---|---|---|---|") + for workload, cell in track_res.items(): + if "status" in cell: + lines.append(f"| {workload} | — | — | — | — | — | — | — | {cell['status']} | — |") + continue + for engine, row in cell["engines"].items(): + gap = "**material**" if row["gap_material"] else "held" + disp = "**character change**" if row["dispersion_change"] else "held" + lines.append( + f"| {workload} | {engine} | {row['r_W']:.4g} | {row['r_L']:.4g} | " + f"{row['movement'] * 100:.2f}% | {row['D']:.4g} | {row['d_W']:.4g} | " + f"{row['d_L']:.4g} | {gap} | {disp} |" + ) + hd = cell["heddle"] + disp = "**character change**" if hd["dispersion_change"] else "held" + lines.append( + f"| {workload} | Heddle (anchor) | 1 | 1 | — | — | {hd['d_W']:.4g} | " + f"{hd['d_L']:.4g} | — | {disp} |" + ) + lines.append("") + lines.append("| workload | pair | rank verdict |") + lines.append("|---|---|---|") + for workload, cell in track_res.items(): + if "status" in cell: + continue + for pair in cell["pairs"]: + verdict = pair["verdict"] + if verdict == "material flip": + verdict = "**material flip**" + elif verdict == "not resolved": + verdict = "order not resolved within disclosed dispersion" + lines.append(f"| {workload} | {pair['pair'][0]} vs {pair['pair'][1]} | {verdict} |") + lines.append("") + return "\n".join(lines) + "\n" + + +def main(argv=None) -> int: + parser = argparse.ArgumentParser( + description="Findings validation: Windows-vs-Linux material-divergence tables and verdicts") + parser.add_argument("--windows-source", required=True, + help="windows-source.json (transcribed ranks/ratios/d — never absolute times)") + parser.add_argument("--linux-results", required=True, + help="this run's ratios/d in the same shape (part 1 data)") + parser.add_argument("--out", help="write the markdown tables here (default: stdout)") + args = parser.parse_args(argv) + + try: + windows_doc = load_side(args.windows_source, windows=True) + linux_doc = load_side(args.linux_results, windows=False) + except (ValidationError, OSError, json.JSONDecodeError) as exc: + print(f"validate.py: malformed input: {exc}", file=sys.stderr) + return 1 + + results = validate_all(windows_doc, linux_doc) + markdown = render_markdown(results) + if args.out: + with open(args.out, "w", encoding="utf-8", newline="\n") as fh: + fh.write(markdown) + else: + sys.stdout.write(markdown) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/benchmarks/linux-crosscheck/windows-source.schema.json b/benchmarks/linux-crosscheck/windows-source.schema.json new file mode 100644 index 00000000..ad0a6037 --- /dev/null +++ b/benchmarks/linux-crosscheck/windows-source.schema.json @@ -0,0 +1,117 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "urn:heddle:linux-crosscheck:windows-source:1", + "title": "windows-source.json — transcribed Windows ranks, ratios (r_W) and dimensionless dispersions (d)", + "description": "Schema for the hand transcription of the published Windows source runs. STRUCTURAL RULE: this file stores ONLY ranks, ratio-to-Heddle values quoted from each report's own ratio column, and dimensionless dispersions d — NEVER absolute times, point estimates, or any wall-time figure; validate.py additionally rejects any key containing an absolute-time token (time/ns/ms/mean/score/point/estimate/...). STANDING NOTE (as of 2026-07-25): the transcription remains deferred because there is no valid published Windows protocol report to transcribe from. One was published at docs/benchmarks/2026-07-22/ and then WITHDRAWN — its results were found invalid — so it is not a sourceRuns entry and has been removed from the tree. A Windows protocol re-test is TBD; until it is published this schema plus validate.py's structural checks are all that exist, and sourceRuns must stay empty. The Linux run at docs/benchmarks/2026-07-25/ is NOT a substitute: this file transcribes Windows source runs specifically, and that run is off-protocol (Linux, boost off, no CPU isolation). When the re-test lands, transcribe its rank and ratio columns only, never its ns/render column. Every transcribed value must carry a 'source' citation naming its file within the published Windows directory, and the transcription is spot-checked (>= 3 values per ecosystem) as a completion check.", + "type": "object", + "required": ["schema", "sourceRuns", "ecosystems"], + "additionalProperties": false, + "properties": { + "schema": { + "const": "heddle-linux-crosscheck/windows-source@1" + }, + "sourceRuns": { + "description": "The published Windows report directories this transcription draws from (links/dates only — never copied numbers).", + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["ecosystem", "date", "path"], + "additionalProperties": false, + "properties": { + "ecosystem": { "type": "string", "minLength": 1 }, + "date": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" }, + "path": { "type": "string", "pattern": "^docs/benchmarks/\\d{4}-\\d{2}-\\d{2}/$" }, + "note": { "type": "string" } + } + } + }, + "ecosystems": { + "description": "One entry per shipped ecosystem (absent ecosystems are simply absent).", + "type": "object", + "minProperties": 1, + "additionalProperties": { + "type": "object", + "required": ["harness", "tracks"], + "additionalProperties": false, + "properties": { + "harness": { + "description": "The harness whose native dispersion form the d values below carry.", + "enum": ["benchmarkdotnet", "criterion", "jmh", "mitata", "pyperf", "benchstat"] + }, + "dForm": { + "description": "The harness-native dispersion form as transcribed, for the reader (e.g. 'StdDev/Mean').", + "type": "string" + }, + "tracks": { + "type": "object", + "minProperties": 1, + "additionalProperties": { + "type": "object", + "required": ["cells"], + "additionalProperties": false, + "properties": { + "cells": { + "type": "object", + "minProperties": 1, + "additionalProperties": { + "type": "object", + "required": ["engines", "heddle"], + "additionalProperties": false, + "properties": { + "engines": { + "type": "object", + "minProperties": 1, + "additionalProperties": { "$ref": "#/$defs/windowsValue" } + }, + "heddle": { "$ref": "#/$defs/heddleValue" } + } + } + } + } + } + } + } + } + } + }, + "$defs": { + "windowsValue": { + "description": "One transcribed engine cell: rank + ratio + dimensionless dispersion + citation. additionalProperties:false IS the structural weld — no absolute-time field can exist here.", + "type": "object", + "required": ["rank", "r", "d", "source"], + "additionalProperties": false, + "properties": { + "rank": { "type": "integer", "minimum": 1 }, + "r": { + "description": "Wall-time ratio to the same OS's Heddle anchor, quoted from the report's own ratio column — never recomputed from absolute times.", + "type": "number", + "exclusiveMinimum": 0 + }, + "d": { + "description": "Dimensionless relative dispersion in the harness-native form.", + "type": "number", + "minimum": 0 + }, + "source": { + "description": "Per-value citation: the source file within the published Windows directory.", + "type": "string", + "minLength": 1 + }, + "note": { "type": "string" } + } + }, + "heddleValue": { + "description": "The Heddle anchor row for the cell (r is 1 by construction on its own OS).", + "type": "object", + "required": ["r", "d", "source"], + "additionalProperties": false, + "properties": { + "r": { "const": 1.0 }, + "d": { "type": "number", "minimum": 0 }, + "source": { "type": "string", "minLength": 1 }, + "note": { "type": "string" } + } + } + } +} diff --git a/benchmarks/python/README.md b/benchmarks/python/README.md new file mode 100644 index 00000000..6a60ad50 --- /dev/null +++ b/benchmarks/python/README.md @@ -0,0 +1,60 @@ +# Python benchmark harness (Phase 5) + +The Python leg of the cross-stack template-engine survey: **Jinja2 3.1.6** and +**Mako 1.3.12** rendering the eight Phase 1 workloads on both fairness tracks, measured +with **pyperf 2.10.0**, plus a separate tracemalloc memory pass. + +**The contract this harness implements:** + +- [python-templates.md](../docs/python-templates.md) + (normative template texts, both engines, both tracks) +- [python-harness.md](../docs/python-harness.md) + (directory layout, gate mechanics, run protocol, report instantiation) + +Gates run against the Phase 1 golden corpus at +[`benchmarks/dotnet/GoldenCorpus/`](../dotnet/GoldenCorpus/) +(read-only; every consumed file is SHA-256-verified against `manifest.json`). + +## Environment + +The measurement run is pinned to **CPython 3.14.6, 64-bit, python.org Windows installer** +(pinned toolchain). Package pins live in [`requirements.txt`](requirements.txt) (`==` only): +Jinja2 3.1.6, Mako 1.3.12, MarkupSafe 3.0.3, pyperf 2.10.0, psutil 7.2.2. + +> Development note: the harness was authored and self-tested under CPython 3.13.0 (the +> interpreter available on the authoring machine — an accepted delta); the dedicated +> protocol run must use a pinned 3.14.x per the recorded toolchain posture. + +## Setup + +```powershell +cd benchmarks\python + +py -3.14 -m venv .venv # protocol machine; the venv is git-ignored +.venv\Scripts\Activate.ps1 +pip install -r requirements.txt +``` + +## Conformance (all must exit 0 before any measurement) + +```powershell +python -m runner.selftest # N-step fixtures + verifier calibration +python -m runner.gate_all --track controlled # 16-cell byte-gate sweep +python -m runner.gate_all --track idiomatic # 16-cell verifier sweep +``` + +## Measurement (elevated PowerShell, machine idle, AC power — python-harness.md run protocol) + +```powershell +python bench_jinja2_controlled.py --affinity=4 -o results\jinja2-controlled.json +python bench_jinja2_idiomatic.py --affinity=4 -o results\jinja2-idiomatic.json +python bench_mako_controlled.py --affinity=4 -o results\mako-controlled.json +python bench_mako_idiomatic.py --affinity=4 -o results\mako-idiomatic.json +python bench_cold_compile.py --affinity=4 -o results\cold-compile.json + +python mem_tracemalloc.py -o results\memory.json # separate pass, never combined with timing + +python -m runner.report_table results +``` + +`results/` is git-ignored; published copies go to `docs/benchmarks/<date>/`. diff --git a/benchmarks/python/bench_cold_compile.py b/benchmarks/python/bench_cold_compile.py new file mode 100644 index 00000000..bba2c18a --- /dev/null +++ b/benchmarks/python/bench_cold_compile.py @@ -0,0 +1,69 @@ +"""pyperf cold parse/compile bench -- both engines, controlled sources. + +Measures, per workload x engine, the cold template-construction cost on the +controlled-track source text preloaded into a string: + +- Jinja2: ``Environment.from_string(source)`` -- parse + compile to Python bytecode, + no bytecode cache configured; +- Mako: ``Template(text=source)`` -- parse + compile to a Python module, in-memory, + no ``module_directory``. + +No parity gate applies to the timed operation (nothing is rendered); instead the +script asserts once per worker -- at module top level, before any registration -- that +compiling + rendering each controlled source still passes the byte gate, so the cold +pass can never time a non-conformant source. Results are per-ecosystem and never +compared across ecosystems; benchmark names are ``<engine>/cold-compile/<workload-id>``. + +Protocol invocation (elevated shell, from ``benchmarks/python/``): + + python bench_cold_compile.py --affinity=4 -o results\\cold-compile.json +""" + +import jinja2 +import mako.template +import pyperf + +from runner import data, engines, gates + +ENGINES = ["jinja2", "mako"] +WORKLOADS = gates.WORKLOADS + +# Controlled-track source texts preloaded into strings before any timing. +sources = { + (engine, w): ( + engines.TEMPLATES_DIR + / engine + / "controlled" + / engines.template_filename(engine, "controlled", w) + ).read_text(encoding="utf-8") + for engine in ENGINES + for w in WORKLOADS +} + +# Hard gate, every worker: compiling + rendering each controlled source (through the +# runner engine wiring, which compiles from the same files) must still pass the byte +# gate -- the cold pass can never time a non-conformant source. +for engine in ENGINES: + for w in WORKLOADS: + out = engines.render(engines.load(engine, "controlled", w), data.MODELS[w]) + gates.assert_parity(w, out, engine, "cold-compile") + del out + +# One long-lived plain Environment; ``from_string`` compiles fresh every call (no +# loader, hence no template cache; no bytecode cache configured). +_JINJA2_ENV = jinja2.Environment() + + +def jinja2_compile(source): + return _JINJA2_ENV.from_string(source) + + +def mako_compile(source): + return mako.template.Template(text=source) + + +runner = pyperf.Runner() +for w in WORKLOADS: + runner.bench_func(f"jinja2/cold-compile/{w}", jinja2_compile, sources[("jinja2", w)]) +for w in WORKLOADS: + runner.bench_func(f"mako/cold-compile/{w}", mako_compile, sources[("mako", w)]) diff --git a/benchmarks/python/bench_jinja2_controlled.py b/benchmarks/python/bench_jinja2_controlled.py new file mode 100644 index 00000000..eb4d7dee --- /dev/null +++ b/benchmarks/python/bench_jinja2_controlled.py @@ -0,0 +1,35 @@ +"""pyperf render bench -- Jinja2 x controlled track. + +The controlled byte gate runs at module top level, BEFORE any ``bench_func`` +registration; pyperf re-executes this module in every worker process, so the gate +provably runs in the same process that produces every timed value. A gate +failure raises ``SystemExit(1)`` before registration, so pyperf emits nothing for a +failed suite. + +Protocol invocation (elevated shell, from ``benchmarks/python/``): + + python bench_jinja2_controlled.py --affinity=4 -o results\\jinja2-controlled.json +""" + +import pyperf + +from runner import data, engines, gates + +ENGINE = "jinja2" +TRACK = "controlled" +WORKLOADS = gates.WORKLOADS + +templates = {w: engines.load(ENGINE, TRACK, w) for w in WORKLOADS} +contexts = {w: data.MODELS[w] for w in WORKLOADS} + +# Hard gate: every cell, every worker, before any registration. +for w in WORKLOADS: + out = engines.render(templates[w], contexts[w]) + gates.assert_parity(w, out, ENGINE, TRACK) + del out + +runner = pyperf.Runner() +for w in WORKLOADS: + # One render = one complete output string from the cached template; the callable + # takes positional args only (bench_func rejects kwargs -- executed evidence). + runner.bench_func(f"{ENGINE}/{TRACK}/{w}", engines.render, templates[w], contexts[w]) diff --git a/benchmarks/python/bench_jinja2_idiomatic.py b/benchmarks/python/bench_jinja2_idiomatic.py new file mode 100644 index 00000000..5aa3711d --- /dev/null +++ b/benchmarks/python/bench_jinja2_idiomatic.py @@ -0,0 +1,35 @@ +"""pyperf render bench -- Jinja2 x idiomatic track. + +The idiomatic functional verifier runs at module top level, BEFORE any ``bench_func`` +registration; pyperf re-executes this module in every worker process, so the gate +provably runs in the same process that produces every timed value. A verifier +failure raises ``SystemExit(1)`` before registration, so pyperf emits nothing for a +failed suite. + +Protocol invocation (elevated shell, from ``benchmarks/python/``): + + python bench_jinja2_idiomatic.py --affinity=4 -o results\\jinja2-idiomatic.json +""" + +import pyperf + +from runner import data, engines, gates, verify + +ENGINE = "jinja2" +TRACK = "idiomatic" +WORKLOADS = gates.WORKLOADS + +templates = {w: engines.load(ENGINE, TRACK, w) for w in WORKLOADS} +contexts = {w: data.MODELS[w] for w in WORKLOADS} + +# Hard gate: every cell, every worker, before any registration. +for w in WORKLOADS: + out = engines.render(templates[w], contexts[w]) + verify.assert_verified(w, out, ENGINE) + del out + +runner = pyperf.Runner() +for w in WORKLOADS: + # One render = one complete output string from the cached template; the callable + # takes positional args only (bench_func rejects kwargs -- executed evidence). + runner.bench_func(f"{ENGINE}/{TRACK}/{w}", engines.render, templates[w], contexts[w]) diff --git a/benchmarks/python/bench_mako_controlled.py b/benchmarks/python/bench_mako_controlled.py new file mode 100644 index 00000000..8c3912d8 --- /dev/null +++ b/benchmarks/python/bench_mako_controlled.py @@ -0,0 +1,35 @@ +"""pyperf render bench -- Mako x controlled track. + +The controlled byte gate runs at module top level, BEFORE any ``bench_func`` +registration; pyperf re-executes this module in every worker process, so the gate +provably runs in the same process that produces every timed value. A gate +failure raises ``SystemExit(1)`` before registration, so pyperf emits nothing for a +failed suite. + +Protocol invocation (elevated shell, from ``benchmarks/python/``): + + python bench_mako_controlled.py --affinity=4 -o results\\mako-controlled.json +""" + +import pyperf + +from runner import data, engines, gates + +ENGINE = "mako" +TRACK = "controlled" +WORKLOADS = gates.WORKLOADS + +templates = {w: engines.load(ENGINE, TRACK, w) for w in WORKLOADS} +contexts = {w: data.MODELS[w] for w in WORKLOADS} + +# Hard gate: every cell, every worker, before any registration. +for w in WORKLOADS: + out = engines.render(templates[w], contexts[w]) + gates.assert_parity(w, out, ENGINE, TRACK) + del out + +runner = pyperf.Runner() +for w in WORKLOADS: + # One render = one complete output string from the cached template; the callable + # takes positional args only (bench_func rejects kwargs -- executed evidence). + runner.bench_func(f"{ENGINE}/{TRACK}/{w}", engines.render, templates[w], contexts[w]) diff --git a/benchmarks/python/bench_mako_idiomatic.py b/benchmarks/python/bench_mako_idiomatic.py new file mode 100644 index 00000000..3692926f --- /dev/null +++ b/benchmarks/python/bench_mako_idiomatic.py @@ -0,0 +1,35 @@ +"""pyperf render bench -- Mako x idiomatic track. + +The idiomatic functional verifier runs at module top level, BEFORE any ``bench_func`` +registration; pyperf re-executes this module in every worker process, so the gate +provably runs in the same process that produces every timed value. A verifier +failure raises ``SystemExit(1)`` before registration, so pyperf emits nothing for a +failed suite. + +Protocol invocation (elevated shell, from ``benchmarks/python/``): + + python bench_mako_idiomatic.py --affinity=4 -o results\\mako-idiomatic.json +""" + +import pyperf + +from runner import data, engines, gates, verify + +ENGINE = "mako" +TRACK = "idiomatic" +WORKLOADS = gates.WORKLOADS + +templates = {w: engines.load(ENGINE, TRACK, w) for w in WORKLOADS} +contexts = {w: data.MODELS[w] for w in WORKLOADS} + +# Hard gate: every cell, every worker, before any registration. +for w in WORKLOADS: + out = engines.render(templates[w], contexts[w]) + verify.assert_verified(w, out, ENGINE) + del out + +runner = pyperf.Runner() +for w in WORKLOADS: + # One render = one complete output string from the cached template; the callable + # takes positional args only (bench_func rejects kwargs -- executed evidence). + runner.bench_func(f"{ENGINE}/{TRACK}/{w}", engines.render, templates[w], contexts[w]) diff --git a/benchmarks/python/mem_tracemalloc.py b/benchmarks/python/mem_tracemalloc.py new file mode 100644 index 00000000..e6e5ef1c --- /dev/null +++ b/benchmarks/python/mem_tracemalloc.py @@ -0,0 +1,177 @@ +"""Memory pass -- tracemalloc single-render boundaries, one fresh child per cell. +Never pyperf; no timing number is ever taken in this process, and no memory number +in a timing process. + +Per engine x track x workload cell the parent spawns one fresh child process (same +interpreter) which: builds the engine object, template, and model; performs one +untimed warm-up render gated exactly as the bench scripts' warm-up gate is +(``assert_parity`` on the controlled track, ``assert_verified`` on the idiomatic +track -- before any tracing starts); then, with tracemalloc active, runs R measured +repetitions with single-render boundaries: + + gc.collect() -> base = traced current -> reset_peak() -> render() + -> allocated_i = peak - base; retained_i = cur - base -> del out + +Output (``-o``, default ``results/memory.json``): per cell +``{"allocated": {"mean","median","std"}, "retained": {"mean","median","std"}, +"repetitions": R}`` -- statistics via the ``statistics`` stdlib module, ``std`` = +sample standard deviation. Any cell failure (including a warm-up gate failure) exits 1 +and writes no partial memory.json. + +Protocol invocation (from ``benchmarks/python/``): + + python mem_tracemalloc.py -o results\\memory.json + +``--reps`` (default 100 -- the protocol's R), ``--engine``/``--track``/``--workload`` +filters exist for smoke validation only; the protocol run uses the defaults (all 32 +cells, 100 repetitions). +""" + +from __future__ import annotations + +import argparse +import gc +import json +import statistics +import subprocess +import sys +import tracemalloc +from pathlib import Path + +HERE = Path(__file__).resolve().parent +ENGINES = ["jinja2", "mako"] +TRACKS = ["controlled", "idiomatic"] +DEFAULT_REPS = 100 # the protocol's R: measured repetitions per cell + + +def _stats(values: list[int]) -> dict: + return { + "mean": statistics.fmean(values), + "median": statistics.median(values), + "std": statistics.stdev(values) if len(values) > 1 else 0.0, + } + + +def run_cell(engine: str, track: str, workload: str, reps: int) -> dict: + """Executes one cell's memory measurement inside this (child) process.""" + from runner import data, engines, gates, verify + + template = engines.load(engine, track, workload) + ctx = data.MODELS[workload] + + # One untimed warm-up render (populates engine caches), gated exactly as the + # bench scripts' warm-up gate is -- BEFORE any tracing starts, so a + # non-conformant template can never enter the traced measurement loop. + out = engines.render(template, ctx) + if track == "controlled": + gates.assert_parity(workload, out, engine, track) + else: + verify.assert_verified(workload, out, engine) + del out + + gc.collect() + tracemalloc.start() + allocated = [0] * reps + retained = [0] * reps + for i in range(reps): + gc.collect() + base = tracemalloc.get_traced_memory()[0] + tracemalloc.reset_peak() + out = engines.render(template, ctx) + cur, peak = tracemalloc.get_traced_memory() + allocated[i] = peak - base + retained[i] = cur - base + del out + tracemalloc.stop() + + return { + "allocated": _stats(allocated), + "retained": _stats(retained), + "repetitions": reps, + } + + +def child_main(cell: str, reps: int) -> int: + engine, track, workload = cell.split("/") + try: + result = run_cell(engine, track, workload, reps) + except SystemExit: + # Gate/verifier failure: its own error-surface message is already on stderr. + raise + except Exception as e: # noqa: BLE001 -- the error surface reports any exception + print(f"MEM FAIL {cell}: {type(e).__name__}: {e}", file=sys.stderr) + return 1 + json.dump(result, sys.stdout) + return 0 + + +def parent_main(args: argparse.Namespace) -> int: + tracks = [args.track] if args.track else TRACKS + engines_sel = [args.engine] if args.engine else ENGINES + from runner import gates # workload id list only; no corpus read in the parent + + workloads = [args.workload] if args.workload else gates.WORKLOADS + + results: dict[str, dict] = {} + for track in tracks: + for engine in engines_sel: + for workload in workloads: + cell = f"{engine}/{track}/{workload}" + # One fresh child process per cell -- same venv interpreter. + proc = subprocess.run( + [sys.executable, str(HERE / "mem_tracemalloc.py"), + "--cell", cell, "--reps", str(args.reps)], + capture_output=True, text=True, cwd=str(HERE), + ) + if proc.stderr: + sys.stderr.write(proc.stderr) + if proc.returncode != 0: + print( + f"MEM FAIL {cell}: child process exited {proc.returncode}" + " -- no memory.json written", + file=sys.stderr, + ) + return 1 + try: + results[cell] = json.loads(proc.stdout) + except json.JSONDecodeError as e: + print(f"MEM FAIL {cell}: unreadable child output: {e}", file=sys.stderr) + return 1 + print( + f"[OK] {cell}: allocated mean {results[cell]['allocated']['mean']:.0f} B," + f" retained mean {results[cell]['retained']['mean']:.0f} B" + f" ({args.reps} reps)" + ) + + out_path = Path(args.output) + if not out_path.is_absolute(): + out_path = HERE / out_path + out_path.parent.mkdir(parents=True, exist_ok=True) + out_path.write_text(json.dumps(results, indent=2) + "\n", encoding="utf-8") + print(f"mem_tracemalloc: {len(results)} cells -> {out_path}") + return 0 + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser( + prog="python mem_tracemalloc.py", + description="Separate tracemalloc memory pass -- never pyperf.", + ) + parser.add_argument("-o", "--output", default="results/memory.json", + help="output JSON path (default: results/memory.json)") + parser.add_argument("--reps", type=int, default=DEFAULT_REPS, + help=f"measured repetitions per cell (default {DEFAULT_REPS};" + " lower values are for smoke validation only)") + parser.add_argument("--engine", choices=ENGINES, help="smoke filter: one engine only") + parser.add_argument("--track", choices=TRACKS, help="smoke filter: one track only") + parser.add_argument("--workload", help="smoke filter: one workload only") + parser.add_argument("--cell", help=argparse.SUPPRESS) # internal: child mode + args = parser.parse_args(argv) + + if args.cell: + return child_main(args.cell, args.reps) + return parent_main(args) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/benchmarks/python/requirements.txt b/benchmarks/python/requirements.txt new file mode 100644 index 00000000..6cb423e0 --- /dev/null +++ b/benchmarks/python/requirements.txt @@ -0,0 +1,5 @@ +Jinja2==3.1.6 +Mako==1.3.12 +MarkupSafe==3.0.3 +pyperf==2.10.0 +psutil==7.2.2 diff --git a/benchmarks/python/runner/__init__.py b/benchmarks/python/runner/__init__.py new file mode 100644 index 00000000..5a9ba99d --- /dev/null +++ b/benchmarks/python/runner/__init__.py @@ -0,0 +1,4 @@ +"""Python benchmark harness runner package. + +Unpublished benchmark harness -- no package metadata, never uploaded. +""" diff --git a/benchmarks/python/runner/__pycache__/__init__.cpython-313.pyc b/benchmarks/python/runner/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 00000000..07ddec06 Binary files /dev/null and b/benchmarks/python/runner/__pycache__/__init__.cpython-313.pyc differ diff --git a/benchmarks/python/runner/__pycache__/data.cpython-313.pyc b/benchmarks/python/runner/__pycache__/data.cpython-313.pyc new file mode 100644 index 00000000..d9fc7d20 Binary files /dev/null and b/benchmarks/python/runner/__pycache__/data.cpython-313.pyc differ diff --git a/benchmarks/python/runner/__pycache__/engines.cpython-313.pyc b/benchmarks/python/runner/__pycache__/engines.cpython-313.pyc new file mode 100644 index 00000000..20adaff5 Binary files /dev/null and b/benchmarks/python/runner/__pycache__/engines.cpython-313.pyc differ diff --git a/benchmarks/python/runner/__pycache__/gate_all.cpython-313.pyc b/benchmarks/python/runner/__pycache__/gate_all.cpython-313.pyc new file mode 100644 index 00000000..9530d88c Binary files /dev/null and b/benchmarks/python/runner/__pycache__/gate_all.cpython-313.pyc differ diff --git a/benchmarks/python/runner/__pycache__/gates.cpython-313.pyc b/benchmarks/python/runner/__pycache__/gates.cpython-313.pyc new file mode 100644 index 00000000..76f3fde1 Binary files /dev/null and b/benchmarks/python/runner/__pycache__/gates.cpython-313.pyc differ diff --git a/benchmarks/python/runner/__pycache__/selftest.cpython-313.pyc b/benchmarks/python/runner/__pycache__/selftest.cpython-313.pyc new file mode 100644 index 00000000..9cec6963 Binary files /dev/null and b/benchmarks/python/runner/__pycache__/selftest.cpython-313.pyc differ diff --git a/benchmarks/python/runner/__pycache__/verify.cpython-313.pyc b/benchmarks/python/runner/__pycache__/verify.cpython-313.pyc new file mode 100644 index 00000000..89be206b Binary files /dev/null and b/benchmarks/python/runner/__pycache__/verify.cpython-313.pyc differ diff --git a/benchmarks/python/runner/data.py b/benchmarks/python/runner/data.py new file mode 100644 index 00000000..c3070468 --- /dev/null +++ b/benchmarks/python/runner/data.py @@ -0,0 +1,206 @@ +"""Workload models -- the Python construction of the cross-stack model data. + +All eight workloads' render contexts as plain dicts with the shared snake_case keys, +materialized once at module import. Workloads 3-8 are built from the exact generation +formulas the cross-stack workload contract pins; `trivial-substitution` is transcribed +from the C# source (`SubstitutionContent.cs`). + +`composed-page` carries ONLY structured navigation data under the `nav` key, loaded +once at import from the corpus fixture `GoldenCorpus/fixtures/composed-page/nav.json` +(the single source of truth the five non-.NET ecosystems load from) via the same +corpus-dir resolution the gate uses (`gates.CORPUS_DIR`). Every fragment of literal +page text -- chrome, blobs, asset/script snippets -- lives in the TEMPLATES: the +model-preparation tier carries DATA only. + +The model tier carries data, never display strings: derived display text +(`row-{i}`, `MX-{sku_number}`, `note {seq}`, the blurb sentence, the media caption / +image src / display price) is composed by the templates as literal-plus-substitution. +Zero-padded identity names (`item-{i:02d}`, `unit-{i:03d}`, `Product {i:02d}`) and the +encoded-suite payloads stay model-side by design. + +Numeric fields (`price`, `value`, `year`, `id`, `sku_number`, `batch`, `seq`, `delta`, ...) +are ints and render via `str(int)` (invariant by construction). `rating` is the pinned +STRING "4.8" -- a transcribed literal, not a formatted float. Parity is enforced by the +gate, not by trusting transcription (the byte gate is the transcription check). +""" + +import json + +from .gates import CORPUS_DIR + +# ---- composed-page (workload 1: structured nav only) ------------------------------------------ + +_NAV_FIXTURE = CORPUS_DIR / "fixtures" / "composed-page" / "nav.json" + + +def _composed() -> dict: + # Strict UTF-8, loaded once at import; schema (snake_case, declaration order): + # {menus: [{tabs: [{label, href, css, has_dropdown, dropdown_css, + # columns: [{sections: [{title, href, title_linked, links: [{label, href}]}]}]}]}], + # footer_columns: [<column shape>]} + with _NAV_FIXTURE.open(encoding="utf-8") as f: + return {"nav": json.load(f)} + + +# ---- trivial-substitution (SubstitutionContent.cs) -------------------------------------------- + + +def _substitution() -> dict: + return { + "title": "Heddle Handbook", + "sku": "HB-2001", + "price": 4200, + "brand": "Heddle Press", + "category": "Reference", + "availability": "In stock", + "url": "/catalog/handbook", + "image_url": "/img/handbook.png", + "summary": "A concise field guide to the engine.", + "rating": "4.8", # pinned string literal, never a formatted float + } + + +# ---- large-loop (LoopContent.cs: RowCount = 5000, Value = i; templates compose row-@(Value)) ---- + + +def _large_loop() -> dict: + return {"items": [{"value": i} for i in range(5000)]} + + +# ---- mixed-page (workload 4; 36 products, i in [1, 36]) --------------------------------------- + + +def _mixed() -> dict: + return { + "page_title": "Mercantile - Catalog", + "store_name": "Mercantile", + "hero_heading": "Autumn hardware sale", + "hero_tagline": "Hand-picked tools, fair prices, shipped tomorrow.", + "show_banner": True, + "banner_text": "Free shipping on orders over 60.", + "show_debug_panel": False, + "footer_note": "Prices include VAT where applicable.", + "year": 2026, + "support_email": "support at mercantile.example", + "products": [ + { + "name": f"Product {i:02d}", + # Templates compose the display SKU (MX-<sku_number>) and the + # blurb sentence around <batch>. + "sku_number": 1000 + i, + "price": 950 + i * 7, + "on_sale": i % 3 == 0, + "batch": i, + } + for i in range(1, 37) + ], + } + + +# ---- conditional-heavy (workload 5; 200 rows, i in [0, 199]) ---------------------------------- + + +def _conditional() -> dict: + return { + "rows": [ + { + "name": f"unit-{i:03d}", + "seq": i, # templates compose the note text (note <seq>) + "is_bronze": i % 4 == 0, + "is_silver": i % 4 == 1, + "is_gold": i % 4 == 2, + "has_note": i % 2 == 0, + "is_active": i % 5 != 0, + } + for i in range(200) + ] + } + + +# ---- fragment-heavy (workload 6; 48 rows, i in [0, 47]) --------------------------------------- + + +def _fragment() -> dict: + kinds = ["tile", "card", "media", "stat"] + badges = ["new", "hot", "sale", "std"] + items = [] + for i in range(48): + kind = kinds[i % 4] + badge = badges[i % 4] + items.append( + { + "kind": kind, # informational; engines dispatch on the booleans + "is_tile": kind == "tile", + "is_card": kind == "card", + "is_media": kind == "media", + "is_stat": kind == "stat", + "name": f"item-{i:02d}", # identity data -- the one padded value + "value": i * 11, + "badge": badge, + "delta": i % 7 - 3, + # On EVERY row (no engine needs a null guard); price is an int -- + # templates compose the caption, image src, and display price. + "promo": {"label": badge, "price": 9 + i}, + } + ) + return {"items": items} + + +# ---- fortunes-encoded (workload 7; the 12 pinned messages, byte-for-byte) --------------------- + +# Rows 4 and 8 carry U+2014 em dashes; row 11 is the TechEmpower XSS payload; row 12 the +# Japanese string (non-ASCII pinned as escapes so the source is ASCII-stable). +_FORTUNE_MESSAGES = [ + "A bad random number generator: 1, 1, 1, 1, 1, 4.33e67, 1, 1, 1", + "A computer program does what you tell it to do, not what you want it to do.", + "A computer scientist is someone who fixes things that aren't broken.", + "A list is only as strong as its weakest link. \u2014 Donald Knuth", + "After enough decimal places, nobody gives a damn.", + "Any program that runs right is obsolete.", + "Computers make very fast, very accurate mistakes.", + "Emacs is a nice operating system, but I prefer UNIX. \u2014 Tom Christiansen", + "Feature: A bug with seniority.", + "fortune: No such file or directory", + '<script>alert("This should not be displayed in a browser alert box.");</script>', + "\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u306e\u30d9\u30f3\u30c1\u30de\u30fc\u30af", +] + + +def _fortunes() -> dict: + return { + "rows": [ + {"id": i + 1, "message": message} + for i, message in enumerate(_FORTUNE_MESSAGES) + ] + } + + +# ---- encoded-loop (workload 8; 5000 rows, i in [0, 4999]) ------------------------------------- + + +def _encoded_loop() -> dict: + hiragana = "\u3053\u3093\u306b\u3061\u306f" # こんにちは + return { + "items": [ + { + "tag": f"tag-{i}&'{i % 7}'", + "name": f'item <{i}> & "co"', + "comment": f"'q' & <angle> \"d\" {hiragana} {i}", + } + for i in range(5000) + ] + } + + +# ---- the module-level registry (built once per process) --------------------------------------- + +MODELS: dict[str, dict] = { + "composed-page": _composed(), + "trivial-substitution": _substitution(), + "large-loop": _large_loop(), + "mixed-page": _mixed(), + "conditional-heavy": _conditional(), + "fragment-heavy": _fragment(), + "fortunes-encoded": _fortunes(), + "encoded-loop": _encoded_loop(), +} diff --git a/benchmarks/python/runner/engines.py b/benchmarks/python/runner/engines.py new file mode 100644 index 00000000..62ab06ed --- /dev/null +++ b/benchmarks/python/runner/engines.py @@ -0,0 +1,112 @@ +"""Engine wiring -- the four engine objects and per-track template loading. + +Raw workloads render through each engine's untouched non-escaping default output path; +encoded workloads through one engine-level escaping configuration each: + +- ``jinja2-raw`` -- ``Environment(autoescape=False)`` with the library whitespace + defaults pinned explicitly in code (``trim_blocks=False``, ``lstrip_blocks=False``, + ``keep_trailing_newline=False``). +- ``jinja2-encoded`` -- a separate ``Environment`` identical but ``autoescape=True`` + (controlled track; the idiomatic environment uses ``select_autoescape()``). +- ``mako-raw`` -- ``TemplateLookup`` with ``default_filters`` left at its ``None`` + default (internally ``["str"]``). +- ``mako-encoded`` -- a separate ``TemplateLookup(default_filters=["h"])`` (controlled + track; idiomatic encoded templates carry ``<%page expression_filter="h"/>``). + +Nothing else differs between raw and encoded engine objects. No escape-bypass syntax +exists anywhere in the templates; no per-expression escape filter appears in +controlled encoded templates. +""" + +from __future__ import annotations + +from pathlib import Path + +import jinja2 +import mako.template +from jinja2 import Environment, FileSystemLoader, select_autoescape +from mako.lookup import TemplateLookup + +TEMPLATES_DIR = Path(__file__).resolve().parents[1] / "templates" + +#: The two encoded-suite workload ids; everything else is raw. +ENCODED_WORKLOADS = frozenset({"fortunes-encoded", "encoded-loop"}) + + +def _jinja2_env(track: str, encoded: bool) -> Environment: + loader = FileSystemLoader(str(TEMPLATES_DIR / "jinja2" / track)) + if track == "idiomatic": + # select_autoescape(): escaping engages for the `.html`-named encoded + # templates and stays off for the `.jinja`-named raw templates. + return Environment(loader=loader, autoescape=select_autoescape()) + # The library whitespace defaults pinned explicitly in code; autoescape is + # the only difference between the raw and encoded environments. + return Environment( + loader=loader, + autoescape=encoded, + trim_blocks=False, + lstrip_blocks=False, + keep_trailing_newline=False, + ) + + +def _mako_lookup(track: str, encoded: bool) -> TemplateLookup: + directories = [str(TEMPLATES_DIR / "mako" / track)] + if track == "controlled" and encoded: + # Engine-level escaping only -- `h` is markupsafe.escape. + return TemplateLookup(directories=directories, default_filters=["h"]) + # Raw default: default_filters=None is internally ["str"] -- no escaping. The + # idiomatic lookup is also default-filtered; its encoded templates carry + # <%page expression_filter="h"/> themselves. + return TemplateLookup(directories=directories) + + +# The four engine objects per track, built lazily and cached (module-level singletons -- +# one long-lived engine object per configuration). +_engines: dict[tuple[str, str, bool], object] = {} + + +def _engine(engine: str, track: str, encoded: bool): + key = (engine, track, encoded) + if key not in _engines: + if engine == "jinja2": + _engines[key] = _jinja2_env(track, encoded) + elif engine == "mako": + _engines[key] = _mako_lookup(track, encoded) + else: + raise KeyError(f"unknown engine: {engine!r}") + return _engines[key] + + +def template_filename(engine: str, track: str, workload: str) -> str: + """The per-track template file name for one cell.""" + if engine == "jinja2": + if track == "idiomatic" and workload in ENCODED_WORKLOADS: + return f"{workload}.html" # select_autoescape engages by extension + return f"{workload}.jinja" + if engine == "mako": + return f"{workload}.mako" + raise KeyError(f"unknown engine: {engine!r}") + + +def load(engine: str, track: str, workload: str): + """Loads one cell's template from its track directory through the appropriate + engine object. Raises ``FileNotFoundError`` for cells whose template file does not + exist (gate_all reports these UNREGISTERED).""" + if track not in ("controlled", "idiomatic"): + raise KeyError(f"unknown track: {track!r}") + filename = template_filename(engine, track, workload) + path = TEMPLATES_DIR / engine / track / filename + if not path.is_file(): + raise FileNotFoundError(path) + encoded = workload in ENCODED_WORKLOADS + return _engine(engine, track, encoded).get_template(filename) + + +def render(template, ctx: dict) -> str: + """One render = one complete output string from the cached template, as a single + positional-args call (``bench_func`` rejects kwargs): Jinja2 takes the context as + one mapping argument, Mako expands it.""" + if isinstance(template, mako.template.Template): + return template.render(**ctx) + return template.render(ctx) diff --git a/benchmarks/python/runner/gate_all.py b/benchmarks/python/runner/gate_all.py new file mode 100644 index 00000000..9b269f1d --- /dev/null +++ b/benchmarks/python/runner/gate_all.py @@ -0,0 +1,108 @@ +"""Per-track gate sweep -- ``python -m runner.gate_all --track controlled|idiomatic``. + +Runs the appropriate gate for every selected cell (engine x workload): the controlled +byte gate (``gates.check_parity``) or the idiomatic verifier (``verify.check_verified``). +A full sweep must report 16/16 cells PASS per track (2 engines x 8 workloads) before +any measurement. + +Engine wiring lives in ``runner/engines.py``. Cells it cannot load (a missing module +or template file) are reported UNREGISTERED -- cleanly, without a traceback -- and the +sweep exits non-zero. + +Filters: ``--track``, ``--engine``, ``--workload`` (each repeatable-free single values; +defaults sweep everything). +""" + +from __future__ import annotations + +import argparse +import sys + +from . import gates, verify +from .data import MODELS + +ENGINES = ["jinja2", "mako"] +TRACKS = ["controlled", "idiomatic"] + + +def _load_engines(): + """Imports ``runner.engines`` if present.""" + try: + from . import engines # type: ignore[attr-defined] + except ImportError: + return None + return engines + + +def run_cell(engines_mod, engine: str, track: str, workload: str) -> tuple[str, str]: + """Gates one cell; returns ``(status, detail)`` where status is + ``PASS`` / ``FAIL`` / ``UNREGISTERED``.""" + if engines_mod is None: + return "UNREGISTERED", "runner/engines.py not present" + try: + template = engines_mod.load(engine, track, workload) + except (KeyError, NotImplementedError, FileNotFoundError) as e: + return "UNREGISTERED", f"cell not registered: {e}" + try: + output = engines_mod.render(template, MODELS[workload]) + except Exception as e: # noqa: BLE001 -- a cell's render crash must not abort the sweep + return "FAIL", f"RENDER FAIL {engine}/{track}/{workload}: {type(e).__name__}: {e}" + if track == "controlled": + failure = gates.check_parity(workload, output) + if failure is not None: + if failure.startswith("SECURITY: "): + return "FAIL", f"SECURITY FAIL {engine}/{track}/{workload}: " + failure[10:] + return "FAIL", f"GATE FAIL {engine}/{track}/{workload}: {failure}" + else: + failures = verify.check_verified(workload, output) + if failures: + detail = "; ".join( + f"VERIFY FAIL {engine}/{workload} {f.kind}: {f.message}" for f in failures + ) + return "FAIL", detail + return "PASS", "" + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser( + prog="python -m runner.gate_all", + description="16-cell gate sweep per track (2 engines x 8 workloads).", + ) + parser.add_argument("--track", choices=TRACKS, help="sweep one track only") + parser.add_argument("--engine", choices=ENGINES, help="sweep one engine only") + parser.add_argument("--workload", choices=gates.WORKLOADS, help="sweep one workload only") + args = parser.parse_args(argv) + + tracks = [args.track] if args.track else TRACKS + engines_sel = [args.engine] if args.engine else ENGINES + workloads = [args.workload] if args.workload else gates.WORKLOADS + + engines_mod = _load_engines() + passed = failed = unregistered = 0 + for track in tracks: + for engine in engines_sel: + for workload in workloads: + status, detail = run_cell(engines_mod, engine, track, workload) + cell = f"{engine}/{track}/{workload}" + if status == "PASS": + passed += 1 + print(f"[PASS] {cell}") + elif status == "UNREGISTERED": + unregistered += 1 + print(f"[UNREGISTERED] {cell}: {detail}") + else: + failed += 1 + print(f"[FAIL] {cell}", file=sys.stderr) + print(f" {detail}", file=sys.stderr) + + total = passed + failed + unregistered + print( + f"gate_all: {passed}/{total} cells PASS" + + (f", {failed} FAIL" if failed else "") + + (f", {unregistered} unregistered" if unregistered else "") + ) + return 0 if failed == 0 and unregistered == 0 else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/benchmarks/python/runner/gates.py b/benchmarks/python/runner/gates.py new file mode 100644 index 00000000..b6b3c82d --- /dev/null +++ b/benchmarks/python/runner/gates.py @@ -0,0 +1,257 @@ +"""Controlled-track gate runner -- parity contract v2 (N1-N5), manifest SHA-256 +verification, byte gate with first-diff excerpt, and the encoded-suite security floor. + +Implements the parity contract's closed list exactly, nothing else. *Whitespace* is +everywhere the closed six-character set ``{TAB, LF, VT, FF, CR, SPACE}`` spelled as the +explicit class ``[\\t\\n\\x0b\\x0c\\r ]`` -- never ``\\s`` (Unicode-wide in Python) and +never ``str.strip()``'s default (also Unicode-wide). +""" + +from __future__ import annotations + +import hashlib +import json +import re +import sys +from pathlib import Path + +# ---- corpus access ---------------------------------------------------------------------------- + +REPO_ROOT = Path(__file__).resolve().parents[3] +CORPUS_DIR = REPO_ROOT / "benchmarks" / "dotnet" / "GoldenCorpus" + +#: The eight workload ids in workload-number order. +WORKLOADS = [ + "composed-page", + "trivial-substitution", + "large-loop", + "mixed-page", + "conditional-heavy", + "fragment-heavy", + "fortunes-encoded", + "encoded-loop", +] + +_manifest_cache: dict[str, dict] | None = None +_golden_cache: dict[str, str] = {} + + +def manifest_entries() -> dict[str, dict]: + """Loads ``manifest.json`` once and returns its entries keyed by workload id.""" + global _manifest_cache + if _manifest_cache is None: + path = CORPUS_DIR / "manifest.json" + try: + raw = path.read_bytes() + except OSError as e: + print(f"CORPUS FAIL manifest: cannot read {path}: {e}", file=sys.stderr) + raise SystemExit(1) from None + manifest = json.loads(raw.decode("utf-8")) + _manifest_cache = {entry["workload"]: entry for entry in manifest["entries"]} + return _manifest_cache + + +def suite_of(workload: str) -> str: + """``"raw"`` or ``"encoded"`` per the manifest entry.""" + return manifest_entries()[workload]["suite"] + + +def load_golden(workload: str) -> str: + """Loads ``<id>.golden.html``, verifying its SHA-256 (and byteLength) against + ``manifest.json`` before use -- a mismatch means the checkout is stale or corrupt + and aborts.""" + if workload in _golden_cache: + return _golden_cache[workload] + entry = manifest_entries().get(workload) + if entry is None: + print( + f"CORPUS FAIL {workload}: no manifest.json entry for this workload", + file=sys.stderr, + ) + raise SystemExit(1) + path = CORPUS_DIR / entry["file"] + try: + raw = path.read_bytes() + except OSError as e: + print(f"CORPUS FAIL {workload}: cannot read {path}: {e}", file=sys.stderr) + raise SystemExit(1) from None + digest = "sha256:" + hashlib.sha256(raw).hexdigest() + if digest != entry["hash"] or len(raw) != entry["byteLength"]: + print( + f"CORPUS FAIL {workload}: sha256 mismatch vs manifest.json" + " — checkout is stale or corrupt", + file=sys.stderr, + ) + raise SystemExit(1) + # N1: strict UTF-8; the stored oracle is UTF-8 without BOM. + _golden_cache[workload] = raw.decode("utf-8") + return _golden_cache[workload] + + +# ---- normalization pipeline (contract v2, the closed list) ------------------------------------ + +#: The contract's closed six-character whitespace set (as a str.strip argument). +WHITESPACE = "\t\n\x0b\x0c\r " + +_N3_RE = re.compile(r">[\t\n\x0b\x0c\r ]+<") +_N3B_RE = re.compile(r"[\t\n\x0b\x0c\r ]+") + +# N5 -- the full closed recognized-spelling alternation: named +# entities case-sensitive; numeric references with any number of leading zeros, +# case-insensitive hex digits and `x`. +_N5 = re.compile( + r"&(?:" + r"amp|#0*38|#[xX]0*26|" + r"lt|#0*60|#[xX]0*3[cC]|" + r"gt|#0*62|#[xX]0*3[eE]|" + r"quot|#0*34|#[xX]0*22|" + r"apos|#0*39|#[xX]0*27" + r");" +) + +_N5_CANONICAL = {0x26: "&", 0x3C: "<", 0x3E: ">", 0x22: """, 0x27: "'"} +_N5_NAMED = {"amp": 0x26, "lt": 0x3C, "gt": 0x3E, "quot": 0x22, "apos": 0x27} + + +def _n5_replacement(match: re.Match) -> str: + body = match.group(0)[1:-1] # between '&' and ';' + if body.startswith("#"): + code = int(body[2:], 16) if body[1] in "xX" else int(body[1:], 10) + else: + code = _N5_NAMED[body] + return _N5_CANONICAL[code] + + +def n1_decode(data: bytes) -> str: + """N1 -- strict UTF-8 decode; a BOM is NOT stripped (it survives to the comparison + and fails it). Invalid UTF-8 is a gate failure (ValueError propagates to the caller's + failure surface).""" + return data.decode("utf-8") # deliberately not "utf-8-sig" + + +def n2_line_endings(s: str) -> str: + """N2 -- every CRLF becomes LF, then every remaining CR becomes LF.""" + return s.replace("\r\n", "\n").replace("\r", "\n") + + +def n3_inter_tag(s: str) -> str: + """N3 -- collapse every whitespace run between ``>`` and ``<`` to nothing. A single + pass is sufficient: the replacement ``><`` contains no whitespace, so no new match + can form.""" + return _N3_RE.sub("><", s) + + +def n3b_strip(s: str) -> str: + """N3b -- remove every whitespace run, anywhere, to nothing (applied to BOTH + sides at comparison time, never stored).""" + return _N3B_RE.sub("", s) + + +def n4_trim(s: str) -> str: + """N4 -- trim leading/trailing whitespace of exactly the six-character set + (never ``str.strip()``'s Unicode-wide default -- a leading U+00A0 must survive).""" + return s.strip(WHITESPACE) + + +def n5_canonicalize(s: str) -> str: + """N5 (encoded suites only) -- one left-to-right scan, non-overlapping, output never + rescanned; only the five markup-significant characters' spellings are canonicalized + (``+`` and friends pass through untouched).""" + return _N5.sub(_n5_replacement, s) + + +def normalize(s: str, suite: str) -> str: + """The stored-form pipeline: N2 -> N3 -> N4 (+ N5 when ``suite == "encoded"``). + N1 is inherent for ``str`` input; use :func:`n1_decode` for bytes.""" + s = n4_trim(n3_inter_tag(n2_line_endings(s))) + if suite == "encoded": + s = n5_canonicalize(s) + return s + + +# ---- byte comparison (first-diff index + excerpt, the ParityCheck.Describe shape) ------------- + + +def describe_diff(expected: bytes, actual: bytes) -> str: + """First differing byte index, expected/actual lengths, and a +/-40-char excerpt + window from each side, ``\\n``-escaped.""" + limit = min(len(expected), len(actual)) + index = next( + (i for i in range(limit) if expected[i] != actual[i]), + limit if len(expected) != len(actual) else -1, + ) + if index < 0: + return "no difference" + + def excerpt(data: bytes) -> str: + window = data[max(0, index - 40): index + 40] + return window.decode("utf-8", errors="replace").replace("\n", "\\n") + + return ( + f"first diff at byte {index} (expected {len(expected)} bytes, got {len(actual)})\n" + f" expected: ...{excerpt(expected)}...\n" + f" actual: ...{excerpt(actual)}..." + ) + + +# ---- security floor (encoded suites) ---------------------------------------------------------- + +RAW_PAYLOAD = "<script>alert(" +ESCAPED_PAYLOAD = "<script>alert(" + +#: Expected escaped-payload counts in normalized encoded output: the payload string +#: appears only in the fortunes model. +EXPECTED_ESCAPED_COUNTS = {"fortunes-encoded": 1, "encoded-loop": 0} + + +def check_security_floor(workload: str, raw_output: str, normalized: str) -> str | None: + """Raw ``<script>alert(`` must occur 0 times in the UN-normalized output; the escaped + form must occur the expected count in the normalized output. Returns a failure + message or ``None``.""" + raw_hits = raw_output.count(RAW_PAYLOAD) + if raw_hits != 0: + return f'raw "{RAW_PAYLOAD}" found {raw_hits} times (expected 0)' + expected = EXPECTED_ESCAPED_COUNTS[workload] + escaped_hits = normalized.count(ESCAPED_PAYLOAD) + if escaped_hits != expected: + return f'escaped "{ESCAPED_PAYLOAD}" found {escaped_hits} times (expected {expected})' + return None + + +# ---- the controlled gate ---------------------------------------------------------------------- + + +def check_parity(workload: str, raw_output: str) -> str | None: + """Runs the full controlled gate for one cell; returns a failure message or ``None``. + + Pipeline: normalize the candidate (N1-N5), then apply N3b to BOTH the normalized + candidate and the loaded oracle, UTF-8-encode, and compare the non-whitespace bytes. + Encoded suites additionally pass the security floor. + """ + suite = suite_of(workload) + golden = load_golden(workload) + normalized = normalize(raw_output, suite) + actual = n3b_strip(normalized).encode("utf-8") + expected = n3b_strip(golden).encode("utf-8") + if actual != expected: + return describe_diff(expected, actual) + if suite == "encoded": + failure = check_security_floor(workload, raw_output, normalized) + if failure is not None: + return "SECURITY: " + failure + return None + + +def assert_parity(workload: str, raw_output: str, engine: str = "?", track: str = "controlled") -> None: + """Hard gate: prints the error-surface message and exits 1 on any failure. + Bench scripts call this at module top level, before any ``bench_func`` registration, + so pyperf emits nothing for a failed suite.""" + failure = check_parity(workload, raw_output) + if failure is None: + return + cell = f"{engine}/{track}/{workload}" + if failure.startswith("SECURITY: "): + print(f"SECURITY FAIL {cell}: {failure[len('SECURITY: '):]}", file=sys.stderr) + else: + print(f"GATE FAIL {cell}: {failure}", file=sys.stderr) + raise SystemExit(1) diff --git a/benchmarks/python/runner/selftest.py b/benchmarks/python/runner/selftest.py new file mode 100644 index 00000000..90a6f167 --- /dev/null +++ b/benchmarks/python/runner/selftest.py @@ -0,0 +1,404 @@ +"""Verifier/gate conformance calibration -- ``python -m runner.selftest``. + +Proves this Python implementation is conformant before it gates anything: + +1. N-step unit fixtures derived from the contract (BOM survival, the closed six-character + whitespace class, N3b space-vs-nothing, the full N5 recognized-spelling table incl. + leading-zero/hex-case variants, the no-rescan rule, non-five-character references + untouched). +2. Model pins -- spot counts/values against ``runner.data``. +3. Every committed golden loads (SHA-256-verified against the manifest) and is accepted + by its verifier; the controlled byte gate accepts each golden as its own candidate. +4. The pinned calibration corruptions are rejected with the correct check kind: + two per raw workload, three per encoded workload (2x6 + 3x2 = 18). + +Exit 0 iff everything passes. +""" + +from __future__ import annotations + +import sys + +from . import gates, verify +from .data import MODELS + +_passed = 0 +_failed = 0 + + +def _check(ok: bool, label: str) -> None: + global _passed, _failed + if ok: + _passed += 1 + else: + _failed += 1 + print(f"[FAIL] {label}", file=sys.stderr) + + +# ---- 1. N-step fixtures ----------------------------------------------------------------------- + +SIX = ["\t", "\n", "\x0b", "\x0c", "\r", " "] + + +def run_normalization_fixtures() -> None: + # N1: strict decode; a BOM is not stripped and fails the comparison. + _check(gates.n1_decode(b"\xef\xbb\xbfx") == "x", "N1: BOM survives decode") + bom_candidate = gates.n3b_strip(gates.normalize("<a></a>", "raw")) + plain = gates.n3b_strip(gates.normalize("<a></a>", "raw")) + _check(bom_candidate != plain, "N1: BOM survives normalization and fails compare") + try: + gates.n1_decode(b"\xff\xfe") + _check(False, "N1: invalid UTF-8 must fail") + except (UnicodeDecodeError, ValueError): + _check(True, "N1: invalid UTF-8 must fail") + + # N2: line endings. + _check(gates.n2_line_endings("a\r\nb\rc\nd") == "a\nb\nc\nd", "N2: CRLF/CR -> LF") + + # N3: inter-tag collapse -- each of the six characters, and only the six. + for ws in SIX: + _check( + gates.n3_inter_tag(f"<a>{ws}{ws}<b>") == "<a><b>", + f"N3: collapses U+{ord(ws):04X} between tags", + ) + _check( + gates.n3_inter_tag("<a> <b>") == "<a> <b>", + "N3: U+00A0 is NOT whitespace (closed set, never \\s)", + ) + _check( + gates.n3_inter_tag("<a> <b>") == "<a> <b>", + "N3: U+3000 is NOT whitespace (closed set, never \\s)", + ) + _check(gates.n3_inter_tag("<p>a b</p>") == "<p>a b</p>", "N3: element text untouched") + _check(gates.n3_inter_tag("/> \n/* c */") == "/> \n/* c */", "N3: >-ws-non-< untouched") + + # N3b: every whitespace run removed to NOTHING (not to a space), anywhere. + _check(gates.n3b_strip("a \t\n\x0b\x0c\r b") == "ab", "N3b: six-char runs -> nothing") + _check(gates.n3b_strip("> /") == gates.n3b_strip(">/"), "N3b: presence-vs-absence equal") + _check(gates.n3b_strip("a b") == "ab", "N3b: space removed, not collapsed to space") + _check(gates.n3b_strip("a b") == "a b", "N3b: U+00A0 survives (closed set)") + + # N4: trim of exactly the six-character set (never str.strip()'s Unicode default). + _check(gates.n4_trim(" \t\n\x0b\x0c\r x \t\n\x0b\x0c\r ") == "x", "N4: six-char trim") + _check(gates.n4_trim(" x ") == " x ", "N4: Unicode whitespace survives") + + # N5: the full closed recognized-spelling table -> canonical. + table = { + "&": "&", "&": "&", "&": "&", "&": "&", + "&": "&", "&": "&", + "<": "<", "<": "<", "<": "<", "<": "<", + "<": "<", "<": "<", "<": "<", + ">": ">", ">": ">", ">": ">", ">": ">", + ">": ">", ">": ">", + """: """, """: """, """: """, """: """, + """: """, """: """, + "'": "'", "'": "'", "'": "'", "'": "'", + "'": "'", + } + for spelling, canonical in table.items(): + _check( + gates.n5_canonicalize(spelling) == canonical, + f"N5: {spelling} -> {canonical}", + ) + # The one rewrite this cast actually fires (MarkupSafe's quote spelling). + _check( + gates.n5_canonicalize('<td data-x=""q"">') == '<td data-x=""q"">', + "N5: MarkupSafe " -> " in context", + ) + # Single pass, no rescan: data that escaped to `&#39;` stays put. + _check(gates.n5_canonicalize("&#39;") == "&#39;", "N5: no rescan of replacements") + # Non-five-character references and unrecognized entities pass through untouched. + for untouched in ["+", "`", "=", "©", "&", "", "& ", "&#"]: + _check( + gates.n5_canonicalize(untouched) == untouched, + f"N5: {untouched!r} untouched", + ) + # Full hex-family vector (the Askama-family spellings). + _check( + gates.n5_canonicalize("<script>alert("x");") == + "<script>alert("x");", + "N5: full decimal-family vector", + ) + + +# ---- 2. Model pins (spot counts and values) --------------------------------------------------- + + +def run_model_pins() -> None: + _check(sorted(MODELS) == sorted(gates.WORKLOADS), "data: eight workload ids") + _check(len(MODELS["mixed-page"]["products"]) == 36, "data: 36 products") + _check( + sum(1 for p in MODELS["mixed-page"]["products"] if p["on_sale"]) == 12, + "data: 12 products on sale", + ) + _check(len(MODELS["conditional-heavy"]["rows"]) == 200, "data: 200 conditional rows") + _check( + sum(1 for r in MODELS["conditional-heavy"]["rows"] if r["is_active"]) == 160, + "data: 160 active rows", + ) + _check(len(MODELS["fragment-heavy"]["items"]) == 48, "data: 48 tiles") + _check(len(MODELS["fortunes-encoded"]["rows"]) == 12, "data: 12 fortunes") + _check(len(MODELS["large-loop"]["items"]) == 5000, "data: 5000 loop rows") + _check(len(MODELS["encoded-loop"]["items"]) == 5000, "data: 5000 encoded rows") + _check( + MODELS["fortunes-encoded"]["rows"][10]["message"] == + '<script>alert("This should not be displayed in a browser alert box.");</script>', + "data: row-11 XSS payload byte-exact", + ) + _check( + MODELS["fortunes-encoded"]["rows"][11]["message"] == "フレームワークのベンチマーク", + "data: row-12 Japanese string", + ) + _check(MODELS["encoded-loop"]["items"][0]["tag"] == "tag-0&'0'", "data: encoded tag-0") + _check( + MODELS["encoded-loop"]["items"][0]["comment"] == "'q' & <angle> \"d\" こんにちは 0", + "data: encoded comment 0", + ) + _check(MODELS["trivial-substitution"]["rating"] == "4.8", "data: rating is the string 4.8") + + # composed-page: the model is {nav} and NOTHING else -- no blob text. + composed = MODELS["composed-page"] + _check(list(composed) == ["nav"], "data: composed-page carries only nav") + nav = composed["nav"] + _check(sorted(nav) == ["footer_columns", "menus"], "data: nav top-level keys") + _check(len(nav["menus"]) == 2, "data: two mega menus") + _check([len(m["tabs"]) for m in nav["menus"]] == [6, 6], "data: six tabs per menu") + _check(len(nav["footer_columns"]) == 4, "data: four footer columns") + tab0 = nav["menus"][0]["tabs"][0] + _check( + tab0["label"] == "Shop All Products" and tab0["has_dropdown"] is True, + "data: first tab label + precomputed has_dropdown", + ) + links = 0 + columns = 0 + all_columns = [ + c for m in nav["menus"] for t in m["tabs"] for c in t["columns"] + ] + list(nav["footer_columns"]) + for column in all_columns: + columns += 1 + for section in column["sections"]: + links += len(section["links"]) + _check(columns == 36, "data: 36 nav columns (menus + footer)") + _check(links == 245, "data: 245 nav links") + + # Nav-string sanitization: every nav string is ASCII with none of & < > " ' + # -- raw and escaped renderings coincide. + def _rule4_clean(obj) -> bool: + if isinstance(obj, str): + return obj.isascii() and not any(c in obj for c in "&<>\"'") + if isinstance(obj, list): + return all(_rule4_clean(x) for x in obj) + if isinstance(obj, dict): + return all(_rule4_clean(v) for v in obj.values()) + return True + + _check(_rule4_clean(nav), "data: nav strings need no escaping (raw == escaped)") + + # large-loop: rows carry ONLY value -- the display name is template-composed. + _check(MODELS["large-loop"]["items"][0] == {"value": 0}, "data: loop row is value-only") + _check(MODELS["large-loop"]["items"][4999] == {"value": 4999}, "data: last loop row") + + # conditional-heavy: seq int replaces the note display string. + row0 = MODELS["conditional-heavy"]["rows"][0] + _check(row0["seq"] == 0 and "note" not in row0, "data: conditional seq replaces note") + _check(MODELS["conditional-heavy"]["rows"][199]["seq"] == 199, "data: last conditional seq") + + # mixed-page: sku_number/batch ints replace the sku/blurb display strings. + p1 = MODELS["mixed-page"]["products"][0] + _check( + p1["sku_number"] == 1001 and p1["batch"] == 1 + and "sku" not in p1 and "blurb" not in p1, + "data: mixed product carries sku_number/batch ints", + ) + _check(MODELS["mixed-page"]["products"][35]["sku_number"] == 1036, "data: last sku_number") + + # fragment-heavy: four dispatched kinds, 12 each, promo on every row. + items = MODELS["fragment-heavy"]["items"] + for kind in ("tile", "card", "media", "stat"): + _check( + sum(1 for it in items if it["kind"] == kind and it[f"is_{kind}"]) == 12, + f"data: 12 {kind} rows with matching boolean", + ) + _check( + all(sum((it["is_tile"], it["is_card"], it["is_media"], it["is_stat"])) == 1 + for it in items), + "data: exactly one dispatch boolean per row", + ) + it0, it47 = items[0], items[47] + _check( + it0 == { + "kind": "tile", "is_tile": True, "is_card": False, "is_media": False, + "is_stat": False, "name": "item-00", "value": 0, "badge": "new", + "delta": -3, "promo": {"label": "new", "price": 9}, + }, + "data: fragment row 0 exact shape", + ) + _check( + it47["name"] == "item-47" and it47["value"] == 517 and it47["delta"] == 2 + and it47["promo"] == {"label": "std", "price": 56}, + "data: fragment row 47 values", + ) + _check( + all(isinstance(it["promo"]["price"], int) and isinstance(it["delta"], int) + for it in items), + "data: promo price and delta are ints", + ) + + +# ---- 3./4. Corpus acceptance + corruption calibration ----------------------------------------- + +# 'removed row': delete the first occurrence of the workload's pinned segment. +# 'reordered section': swap the first occurrences of A and B (A strictly before B). +# 'unescaped payload' (encoded only): replace the first escaped form with its raw form. +# Pins mirror the cross-stack calibration corruptions (the IdiomaticChecks +# corruption pins). + +_ENCODED_LOOP_ROW_0 = ( + '<tr><td data-tag="tag-0&'0'">item <0> & "co"</td>' + "<td>'q' & <angle> "d" こんにちは 0</td></tr>" +) + +# composed-page: the removed segment is the slider fragment composed-page.heddle splices into +# the layout's live body slot -- an idiomatic page with an EMPTY body must fail; the swap +# exchanges the wholesale-only and retail-only mega-menu anchors (the menus are +# near-identical; these hrefs are the unique rows). Both mirror VerifierDefinitions.cs. +_COMPOSED_SLIDER = ( + '<img src="/files/homepage/homebtmbanners/gluten-hp.jpg" width="984" border="0" />' +) + +# fragment-heavy: row 0's whole tile fragment, computed from the model so the pin +# cannot drift; rows 0 and 24 are both tiles (i % 4 == 0), covering the dispatch cycle. +_FRAGMENT_ROW_0 = MODELS["fragment-heavy"]["items"][0] +_FIRST_TILE = ( + f'<section class="tile"><h3>{_FRAGMENT_ROW_0["name"]}</h3>' + f'<p class="v">{_FRAGMENT_ROW_0["value"]}</p>' + f'<span class="badge">{_FRAGMENT_ROW_0["badge"]}</span></section>' +) + +#: (workload, removed_segment, removed_kind, swap_a, swap_b, (escaped, raw) or None) +CALIBRATION_PINS = [ + ( + "composed-page", + _COMPOSED_SLIDER, + "marker", + "/product/coming-soon-paleo-pork", + "/products/paleo-friendly-pork", + None, + ), + ("trivial-substitution", "HB-2001", "value", 'class="sku"', 'class="rating"', None), + ( + "large-loop", + "<tr><td>row-0</td><td>0</td></tr>", + "value", + "<tr><td>row-0</td><td>0</td></tr>", + "<tr><td>row-2500</td><td>2500</td></tr>", + None, + ), + ("mixed-page", '<article class="card">', "value", "<header>", 'class="hero"', None), + ("conditional-heavy", "unit-000", "value", "unit-000", "unit-100", None), + ("fragment-heavy", _FIRST_TILE, "value", "item-00", "item-24", None), + ( + "fortunes-encoded", + "<tr><td>1</td><td>A bad random number generator: 1, 1, 1, 1, 1, 4.33e67, 1, 1, 1</td></tr>", + "value", + "<tr><th>id</th><th>message</th></tr>", + "フレームワークのベンチマーク", + ("<script>alert(", "<script>alert("), + ), + ( + "encoded-loop", + _ENCODED_LOOP_ROW_0, + "value", + "tag-0&'0'", + "item <2500>", + # This workload carries no script payload; its escaped->raw + # corruption is the comment's angle text (forbidden: `<angle>`). + ("<angle>", "<angle>"), + ), +] + + +def _remove_first(golden: str, segment: str) -> str: + at = golden.find(segment) + assert at >= 0, f"removed-segment pin not found: {segment[:48]}" + return golden[:at] + golden[at + len(segment):] + + +def _swap_first(golden: str, a: str, b: str) -> str: + ia = golden.find(a) + ib = golden.find(b) + assert ia >= 0 and ib >= ia + len(a), "swap pins must exist, ordered, non-overlapping" + return golden[:ia] + b + golden[ia + len(a):ib] + a + golden[ib + len(b):] + + +def _unescape_first(golden: str, escaped: str, raw: str) -> str: + assert escaped in golden, f"unescape pin not found: {escaped}" + return golden.replace(escaped, raw, 1) + + +def _check_rejected(workload: str, corrupted: str, kind: str, label: str) -> None: + failures = verify.check_verified(workload, corrupted) + if not failures: + _check(False, f"{workload} calibration: corruption '{label}' was NOT rejected") + elif not any(f.kind == kind for f in failures): + _check( + False, + f"{workload} calibration: '{label}' expected a {kind} failure," + f" got {[f.kind for f in failures]}", + ) + else: + _check(True, f"{workload} calibration: {label} rejected as {kind}") + + +def run_calibration() -> None: + corruptions = 0 + for workload in gates.WORKLOADS: + golden = gates.load_golden(workload) # SHA-256-verified against the manifest + # The verifier accepts its golden. + failures = verify.check_verified(workload, golden) + _check( + not failures, + f"{workload}: golden must be accepted, got {[(f.kind, f.message) for f in failures]}", + ) + # The controlled byte gate accepts the golden as its own candidate. + _check( + gates.check_parity(workload, golden) is None, + f"{workload}: byte gate accepts the golden as candidate", + ) + + for workload, removed, removed_kind, swap_a, swap_b, unescape in CALIBRATION_PINS: + golden = gates.load_golden(workload) + _check_rejected( + workload, _remove_first(golden, removed), removed_kind, "removed-row" + ) + corruptions += 1 + _check_rejected( + workload, _swap_first(golden, swap_a, swap_b), "marker", "reordered-section" + ) + corruptions += 1 + if unescape is not None: + escaped, raw = unescape + _check_rejected( + workload, + _unescape_first(golden, escaped, raw), + "forbidden", + "unescaped-payload", + ) + corruptions += 1 + _check(corruptions == 18, f"calibration: 18 corruptions exercised (got {corruptions})") + + +def main() -> int: + run_normalization_fixtures() + run_model_pins() + run_calibration() + total = _passed + _failed + status = "OK" if _failed == 0 else "FAILED" + print(f"selftest {status}: {_passed}/{total} checks passed" + f" (8 goldens accepted, 18 corruptions rejected)" if _failed == 0 + else f"selftest {status}: {_failed}/{total} checks failed") + return 0 if _failed == 0 else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/benchmarks/python/runner/verify.py b/benchmarks/python/runner/verify.py new file mode 100644 index 00000000..4dce13a7 --- /dev/null +++ b/benchmarks/python/runner/verify.py @@ -0,0 +1,124 @@ +"""Idiomatic-track verifier -- the Python implementation of the parity contract's +idiomatic-track gate, driven by the per-workload ``<id>.verify.json`` definitions +in the golden corpus. + +Matching semantics: the candidate is normalized (N1-N4, +N5 for encoded suites), then +the N3b whitespace strip is applied to the output AND to every needle string before +matching; ``values`` are exact non-overlapping counts, ``markers`` are strictly ordered, +``forbidden`` must be absent from both the raw and the normalized output, ``required`` +is a minimum count. Whitespace is everywhere the closed six-character set (gates.py). +""" + +from __future__ import annotations + +import json +import sys +from dataclasses import dataclass + +from . import gates + +_verify_cache: dict[str, dict] = {} + + +def load_verify(workload: str) -> dict: + """Loads and parses ``<id>.verify.json``.""" + if workload not in _verify_cache: + path = gates.CORPUS_DIR / f"{workload}.verify.json" + try: + raw = path.read_bytes() + except OSError as e: + print(f"CORPUS FAIL {workload}: cannot read {path}: {e}", file=sys.stderr) + raise SystemExit(1) from None + _verify_cache[workload] = json.loads(raw.decode("utf-8")) + return _verify_cache[workload] + + +@dataclass(frozen=True) +class Failure: + """One failed check: its kind (``value``/``marker``/``forbidden``/``required``) + plus the failure-message tail.""" + + kind: str + message: str + + +def _excerpt(s: str) -> str: + truncated = s if len(s) <= 48 else s[:48] + "…" + return truncated.replace("\n", "\\n") + + +def count_occurrences(haystack: str, needle: str) -> int: + """Non-overlapping occurrence count (``str.count`` is non-overlapping); an empty + needle counts 0.""" + if not needle: + return 0 + return haystack.count(needle) + + +def verify(definition: dict, raw_output: str) -> list[Failure]: + """Runs the verifier against a candidate's raw output. Empty list = accepted.""" + stripped = gates.n3b_strip(gates.normalize(raw_output, definition["suite"])) + stripped_raw = gates.n3b_strip(raw_output) + failures: list[Failure] = [] + + for check in definition["values"]: + needle = gates.n3b_strip(check["text"]) + found = count_occurrences(stripped, needle) + if found != check["count"]: + failures.append(Failure( + "value", + f'expected {check["count"]} of "{_excerpt(check["text"])}", found {found}', + )) + + pos = 0 + for marker in definition["markers"]: + needle = gates.n3b_strip(marker) + at = stripped.find(needle, pos) + if at < 0: + # Keep scanning subsequent markers from the current position so every + # out-of-order/missing marker is reported. + failures.append(Failure( + "marker", f'marker "{_excerpt(marker)}" not found after index {pos}' + )) + else: + pos = at + len(needle) + + for forbidden in definition["forbidden"]: + needle = gates.n3b_strip(forbidden) + found = max( + count_occurrences(stripped_raw, needle), + count_occurrences(stripped, needle), + ) + if found != 0: + failures.append(Failure( + "forbidden", f'expected 0 of "{_excerpt(forbidden)}", found {found}' + )) + + for check in definition["required"]: + needle = gates.n3b_strip(check["text"]) + found = count_occurrences(stripped, needle) + if found < check["minCount"]: + failures.append(Failure( + "required", + f'expected {check["minCount"]} of "{_excerpt(check["text"])}", found {found}', + )) + + return failures + + +def check_verified(workload: str, raw_output: str) -> list[Failure]: + """Loads the workload's verifier definition and runs it.""" + return verify(load_verify(workload), raw_output) + + +def assert_verified(workload: str, raw_output: str, engine: str = "?") -> None: + """Hard gate: prints ``VERIFY FAIL`` lines and exits 1 on any failed check.""" + failures = check_verified(workload, raw_output) + if not failures: + return + for failure in failures: + print( + f"VERIFY FAIL {engine}/{workload} {failure.kind}: {failure.message}", + file=sys.stderr, + ) + raise SystemExit(1) diff --git a/benchmarks/python/templates/jinja2/controlled/composed-page.jinja b/benchmarks/python/templates/jinja2/controlled/composed-page.jinja new file mode 100644 index 00000000..bc2fb20a --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/composed-page.jinja @@ -0,0 +1,14 @@ +{% extends "shared/layout.jinja" %} +{% block content %} + <div class="slider-wrapper theme-default"> + <div id="slider" class="nivoSlider"> + </div> + <div class="home-content"> + <div> + <a href="/products/gluten-free"> + <img src="/files/homepage/homebtmbanners/gluten-hp.jpg" width="984" border="0" /> + </a> + </div> + </div> + </div> +{% endblock %} diff --git a/benchmarks/python/templates/jinja2/controlled/conditional-heavy.jinja b/benchmarks/python/templates/jinja2/controlled/conditional-heavy.jinja new file mode 100644 index 00000000..f58c7e1e --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/conditional-heavy.jinja @@ -0,0 +1 @@ +<ul class="matrix">{% for r in rows %}<li>{% if r.is_bronze %}<span class="t0">bronze</span>{% elif r.is_silver %}<span class="t1">silver</span>{% elif r.is_gold %}<span class="t2">gold</span>{% else %}<span class="t3">platinum</span>{% endif %}<em>{{ r.name }}</em>{% if r.has_note %}<small>note {{ r.seq }}</small>{% endif %}{% if r.is_active %}<b>active</b>{% endif %}</li>{% endfor %}</ul> diff --git a/benchmarks/python/templates/jinja2/controlled/encoded-loop.jinja b/benchmarks/python/templates/jinja2/controlled/encoded-loop.jinja new file mode 100644 index 00000000..e2bf4430 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/encoded-loop.jinja @@ -0,0 +1 @@ +<table>{% for item in items %}<tr><td data-tag="{{ item.tag }}">{{ item.name }}</td><td>{{ item.comment }}</td></tr>{% endfor %}</table> diff --git a/benchmarks/python/templates/jinja2/controlled/fortunes-encoded.jinja b/benchmarks/python/templates/jinja2/controlled/fortunes-encoded.jinja new file mode 100644 index 00000000..4c341ea5 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/fortunes-encoded.jinja @@ -0,0 +1 @@ +<!DOCTYPE html><html><head><title>Fortunes{% for r in rows %}{% endfor %}
      idmessage
      {{ r.id }}{{ r.message }}
      diff --git a/benchmarks/python/templates/jinja2/controlled/fragment-heavy.jinja b/benchmarks/python/templates/jinja2/controlled/fragment-heavy.jinja new file mode 100644 index 00000000..d78580b3 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/fragment-heavy.jinja @@ -0,0 +1 @@ +
      {% for item in items %}{% if item.is_tile %}{% include "shared/tile.jinja" %}{% elif item.is_card %}{% include "shared/card.jinja" %}{% elif item.is_media %}{% include "shared/media-row.jinja" %}{% else %}{% include "shared/stat.jinja" %}{% endif %}{% endfor %}
      diff --git a/benchmarks/python/templates/jinja2/controlled/large-loop.jinja b/benchmarks/python/templates/jinja2/controlled/large-loop.jinja new file mode 100644 index 00000000..5e6b9a65 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/large-loop.jinja @@ -0,0 +1 @@ +{% for item in items %}row-{{ item.value }}{{ item.value }}{% endfor %} diff --git a/benchmarks/python/templates/jinja2/controlled/mixed-page.jinja b/benchmarks/python/templates/jinja2/controlled/mixed-page.jinja new file mode 100644 index 00000000..2efd4045 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/mixed-page.jinja @@ -0,0 +1,29 @@ + + + + +{{ page_title }} + + + +
      +

      {{ store_name }}

      + +
      +
      +{% if show_banner %}{% endif %} +
      +

      {{ hero_heading }}

      +

      {{ hero_tagline }}

      +
      +
      +{% for p in products %}

      {{ p.name }}

      MX-{{ p.sku_number }}

      {{ p.price }}

      {% if p.on_sale %}

      On sale

      {% endif %}

      A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

      {% endfor %} +
      +{% if show_debug_panel %}
      debug
      {% endif %} +
      +
      +

      {{ footer_note }}

      +

      {{ store_name }} {{ year }} {{ support_email }}

      +
      + + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/alert-below.jinja b/benchmarks/python/templates/jinja2/controlled/shared/alert-below.jinja new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/python/templates/jinja2/controlled/shared/alert-top.jinja b/benchmarks/python/templates/jinja2/controlled/shared/alert-top.jinja new file mode 100644 index 00000000..d889f879 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/alert-top.jinja @@ -0,0 +1 @@ +
      holiday shipping
      diff --git a/benchmarks/python/templates/jinja2/controlled/shared/assets-scripts.jinja b/benchmarks/python/templates/jinja2/controlled/shared/assets-scripts.jinja new file mode 100644 index 00000000..bf801bb9 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/assets-scripts.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/assets-styles.jinja b/benchmarks/python/templates/jinja2/controlled/shared/assets-styles.jinja new file mode 100644 index 00000000..28df0356 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/assets-styles.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/badge.jinja b/benchmarks/python/templates/jinja2/controlled/shared/badge.jinja new file mode 100644 index 00000000..9dd928bf --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/badge.jinja @@ -0,0 +1 @@ +{{ item.promo.label }} diff --git a/benchmarks/python/templates/jinja2/controlled/shared/body-end-scripts.jinja b/benchmarks/python/templates/jinja2/controlled/shared/body-end-scripts.jinja new file mode 100644 index 00000000..51c5f27e --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/body-end-scripts.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/body-scripts.jinja b/benchmarks/python/templates/jinja2/controlled/shared/body-scripts.jinja new file mode 100644 index 00000000..7bcf90f9 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/body-scripts.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/card.jinja b/benchmarks/python/templates/jinja2/controlled/shared/card.jinja new file mode 100644 index 00000000..390f5368 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/card.jinja @@ -0,0 +1 @@ +

      {{ item.name }}

      {% include "shared/badge.jinja" %}{% include "shared/price.jinja" %}

      {{ item.value }}

      diff --git a/benchmarks/python/templates/jinja2/controlled/shared/custom-styles.jinja b/benchmarks/python/templates/jinja2/controlled/shared/custom-styles.jinja new file mode 100644 index 00000000..c03f73c5 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/custom-styles.jinja @@ -0,0 +1 @@ +/* CSS Comment Test */ diff --git a/benchmarks/python/templates/jinja2/controlled/shared/head-scripts.jinja b/benchmarks/python/templates/jinja2/controlled/shared/head-scripts.jinja new file mode 100644 index 00000000..35f0ac9a --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/head-scripts.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/layout.jinja b/benchmarks/python/templates/jinja2/controlled/shared/layout.jinja new file mode 100644 index 00000000..cd8e2d7a --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/layout.jinja @@ -0,0 +1,126 @@ + + + + + + + + + + Title + + + + + + + + + {% include "shared/assets-styles.jinja" %} + + {% include "shared/head-scripts.jinja" %} + + + {% include "shared/body-scripts.jinja" %} +
      +
      + +
      +
      +
      +
      + {% include "shared/alert-top.jinja" %} +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + {% for menu in nav.menus %}{% include "shared/mega-menu.jinja" %}{% endfor %} +
      +
      +
      + {% include "shared/alert-below.jinja" %} +
      +
      + {% block content %}{% endblock %} +
      +
      +
      +
      +
      + +
      +
      + {% include "shared/assets-scripts.jinja" %} + + {% include "shared/body-end-scripts.jinja" %} + + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/media-row.jinja b/benchmarks/python/templates/jinja2/controlled/shared/media-row.jinja new file mode 100644 index 00000000..caab49f1 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/media-row.jinja @@ -0,0 +1 @@ +
      {{ item.name }}

      {{ item.name }}

      Caption for {{ item.name }}

      diff --git a/benchmarks/python/templates/jinja2/controlled/shared/mega-menu.jinja b/benchmarks/python/templates/jinja2/controlled/shared/mega-menu.jinja new file mode 100644 index 00000000..c82d5bc9 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/mega-menu.jinja @@ -0,0 +1 @@ +
        {% for tab in menu.tabs %}
      • {{ tab.label }}{% if tab.has_dropdown %}
        {% for column in tab.columns %}{% include "shared/nav-column.jinja" %}{% endfor %}
        {% endif %}
      • {% endfor %}
      diff --git a/benchmarks/python/templates/jinja2/controlled/shared/nav-column.jinja b/benchmarks/python/templates/jinja2/controlled/shared/nav-column.jinja new file mode 100644 index 00000000..12e69cad --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/nav-column.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/nav-link.jinja b/benchmarks/python/templates/jinja2/controlled/shared/nav-link.jinja new file mode 100644 index 00000000..b07a3c05 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/nav-link.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/nav-section.jinja b/benchmarks/python/templates/jinja2/controlled/shared/nav-section.jinja new file mode 100644 index 00000000..8e449bc0 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/nav-section.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/price.jinja b/benchmarks/python/templates/jinja2/controlled/shared/price.jinja new file mode 100644 index 00000000..bba5bedf --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/price.jinja @@ -0,0 +1 @@ +

      {{ item.promo.price }}.99

      diff --git a/benchmarks/python/templates/jinja2/controlled/shared/secondary-retail-menu.jinja b/benchmarks/python/templates/jinja2/controlled/shared/secondary-retail-menu.jinja new file mode 100644 index 00000000..6c6147b8 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/secondary-retail-menu.jinja @@ -0,0 +1,116 @@ + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/secondary-wholesale-menu.jinja b/benchmarks/python/templates/jinja2/controlled/shared/secondary-wholesale-menu.jinja new file mode 100644 index 00000000..b80f8830 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/secondary-wholesale-menu.jinja @@ -0,0 +1,138 @@ + diff --git a/benchmarks/python/templates/jinja2/controlled/shared/stat.jinja b/benchmarks/python/templates/jinja2/controlled/shared/stat.jinja new file mode 100644 index 00000000..c7e0e140 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/stat.jinja @@ -0,0 +1 @@ +
      {{ item.name }}{{ item.value }}{{ item.delta }}
      diff --git a/benchmarks/python/templates/jinja2/controlled/shared/tile.jinja b/benchmarks/python/templates/jinja2/controlled/shared/tile.jinja new file mode 100644 index 00000000..35a89004 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/shared/tile.jinja @@ -0,0 +1 @@ +

      {{ item.name }}

      {{ item.value }}

      {{ item.badge }}
      diff --git a/benchmarks/python/templates/jinja2/controlled/trivial-substitution.jinja b/benchmarks/python/templates/jinja2/controlled/trivial-substitution.jinja new file mode 100644 index 00000000..d3960b65 --- /dev/null +++ b/benchmarks/python/templates/jinja2/controlled/trivial-substitution.jinja @@ -0,0 +1 @@ +

      {{ title }}

      {{ sku }}

      {{ price }}

      {{ brand }}

      {{ category }}

      {{ availability }}

      {{ summary }}

      {{ rating }}

      diff --git a/benchmarks/python/templates/jinja2/idiomatic/composed-page.jinja b/benchmarks/python/templates/jinja2/idiomatic/composed-page.jinja new file mode 100644 index 00000000..da59cdea --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/composed-page.jinja @@ -0,0 +1,20 @@ +{# Idiomatic Jinja2 composed-page: template inheritance -- the page extends the + full-page layout and fills its live content block with the slider body; the + body is the SAME as the controlled track's (the verifier's removed-segment + calibration pin is the slider, so an empty block fails). + Doc: https://jinja.palletsprojects.com/en/stable/templates/#template-inheritance #} +{% extends "shared/layout.jinja" %} + +{% block content %} +
      +
      +
      +
      +
      + + + +
      +
      +
      +{% endblock %} diff --git a/benchmarks/python/templates/jinja2/idiomatic/conditional-heavy.jinja b/benchmarks/python/templates/jinja2/idiomatic/conditional-heavy.jinja new file mode 100644 index 00000000..98aa7369 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/conditional-heavy.jinja @@ -0,0 +1,27 @@ +{# Idiomatic Jinja2 conditional-heavy: an {% if %}/{% elif %}/{% else %} chain + inside a {% for %} loop, authored indented; the note text is + template-composed as the literal `note ` plus the seq substitution. + Docs: https://jinja.palletsprojects.com/en/stable/templates/#if + https://jinja.palletsprojects.com/en/stable/templates/#for #} +
        +{% for r in rows %} +
      • + {% if r.is_bronze %} + bronze + {% elif r.is_silver %} + silver + {% elif r.is_gold %} + gold + {% else %} + platinum + {% endif %} + {{ r.name }} + {% if r.has_note %} + note {{ r.seq }} + {% endif %} + {% if r.is_active %} + active + {% endif %} +
      • +{% endfor %} +
      diff --git a/benchmarks/python/templates/jinja2/idiomatic/encoded-loop.html b/benchmarks/python/templates/jinja2/idiomatic/encoded-loop.html new file mode 100644 index 00000000..8a32d4e9 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/encoded-loop.html @@ -0,0 +1,9 @@ +{# Idiomatic Jinja2 encoded-loop: `.html`-named template -- escaping is the + environment's select_autoescape(), engaged by file extension; the attribute + value position is escaped by the same autoescape path. + Doc: https://jinja.palletsprojects.com/en/stable/api/#autoescaping #} + +{% for item in items %} + +{% endfor %} +
      {{ item.name }}{{ item.comment }}
      diff --git a/benchmarks/python/templates/jinja2/idiomatic/fortunes-encoded.html b/benchmarks/python/templates/jinja2/idiomatic/fortunes-encoded.html new file mode 100644 index 00000000..5def615b --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/fortunes-encoded.html @@ -0,0 +1,18 @@ +{# Idiomatic Jinja2 fortunes-encoded: `.html`-named template -- escaping is the + environment's select_autoescape(), engaged by file extension; no filter syntax + appears. + Doc: https://jinja.palletsprojects.com/en/stable/api/#autoescaping #} + + + +Fortunes + + + + +{% for r in rows %} + +{% endfor %} +
      idmessage
      {{ r.id }}{{ r.message }}
      + + diff --git a/benchmarks/python/templates/jinja2/idiomatic/fragment-heavy.jinja b/benchmarks/python/templates/jinja2/idiomatic/fragment-heavy.jinja new file mode 100644 index 00000000..5f1e0cc8 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/fragment-heavy.jinja @@ -0,0 +1,24 @@ +{# Idiomatic Jinja2 fragment-heavy: four fragment kinds dispatched per row on + the precomputed booleans via an {% if %}/{% elif %}/{% else %} chain; each + fragment is a macro imported from its own partial file, and the card + fragment nests the badge/price sub-macros against the row's promo. + Docs: https://jinja.palletsprojects.com/en/stable/templates/#macros + https://jinja.palletsprojects.com/en/stable/templates/#import + https://jinja.palletsprojects.com/en/stable/templates/#if #} +{% from "shared/tile.jinja" import tile %} +{% from "shared/card.jinja" import card %} +{% from "shared/media-row.jinja" import media_row %} +{% from "shared/stat.jinja" import stat %} +
      +{% for item in items %} +{% if item.is_tile %} +{{ tile(item) }} +{% elif item.is_card %} +{{ card(item) }} +{% elif item.is_media %} +{{ media_row(item) }} +{% else %} +{{ stat(item) }} +{% endif %} +{% endfor %} +
      diff --git a/benchmarks/python/templates/jinja2/idiomatic/large-loop.jinja b/benchmarks/python/templates/jinja2/idiomatic/large-loop.jinja new file mode 100644 index 00000000..dc118a75 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/large-loop.jinja @@ -0,0 +1,7 @@ +{# Idiomatic Jinja2 large-loop: a {% for %} loop over items, one row per source + line; the display name is template-composed as the literal `row-` plus the + value substitution. + Doc: https://jinja.palletsprojects.com/en/stable/templates/#for #} +{% for item in items %} +row-{{ item.value }}{{ item.value }} +{% endfor %} diff --git a/benchmarks/python/templates/jinja2/idiomatic/mixed-page.jinja b/benchmarks/python/templates/jinja2/idiomatic/mixed-page.jinja new file mode 100644 index 00000000..66462a98 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/mixed-page.jinja @@ -0,0 +1,50 @@ +{# Idiomatic Jinja2 mixed-page: SINGLE-FILE by rule (layout + composition is composed-page's dimension); full page skeleton with + scalar substitutions, the product {% for %} loop, and {% if %} toggles; the + display SKU (`MX-` + sku_number) and the blurb sentence around batch are + template-composed. + Docs: https://jinja.palletsprojects.com/en/stable/templates/#for + https://jinja.palletsprojects.com/en/stable/templates/#if #} + + + + +{{ page_title }} + + + +
      +

      {{ store_name }}

      + +
      +
      +{% if show_banner %} + +{% endif %} +
      +

      {{ hero_heading }}

      +

      {{ hero_tagline }}

      +
      +
      +{% for p in products %} +
      +

      {{ p.name }}

      +

      MX-{{ p.sku_number }}

      +

      {{ p.price }}

      +{% if p.on_sale %} +

      On sale

      +{% endif %} +

      A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

      +
      +{% endfor %} +
      +{% if show_debug_panel %} +
      debug
      +{% endif %} +
      +
      +

      {{ footer_note }}

      +

      {{ store_name }} {{ year }} {{ support_email }}

      +
      + + diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/alert-below.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/alert-below.jinja new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/alert-top.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/alert-top.jinja new file mode 100644 index 00000000..d889f879 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/alert-top.jinja @@ -0,0 +1 @@ +
      holiday shipping
      diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/assets-scripts.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/assets-scripts.jinja new file mode 100644 index 00000000..bf801bb9 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/assets-scripts.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/assets-styles.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/assets-styles.jinja new file mode 100644 index 00000000..28df0356 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/assets-styles.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/badge.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/badge.jinja new file mode 100644 index 00000000..edc9b6ef --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/badge.jinja @@ -0,0 +1,6 @@ +{# Idiomatic Jinja2 badge sub-fragment: nested inside the card fragment, + called against the row's promo member. + Doc: https://jinja.palletsprojects.com/en/stable/templates/#macros #} +{% macro badge(promo) %} +{{ promo.label }} +{% endmacro %} diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/body-end-scripts.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/body-end-scripts.jinja new file mode 100644 index 00000000..51c5f27e --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/body-end-scripts.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/body-scripts.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/body-scripts.jinja new file mode 100644 index 00000000..7bcf90f9 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/body-scripts.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/card.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/card.jinja new file mode 100644 index 00000000..e9634e96 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/card.jinja @@ -0,0 +1,14 @@ +{# Idiomatic Jinja2 card fragment: the one nesting level -- the card invokes + the badge and price sub-macros against the row's promo member. + Docs: https://jinja.palletsprojects.com/en/stable/templates/#macros + https://jinja.palletsprojects.com/en/stable/templates/#import #} +{% from "shared/badge.jinja" import badge %} +{% from "shared/price.jinja" import price %} +{% macro card(item) %} +
      +

      {{ item.name }}

      + {{ badge(item.promo) }} + {{ price(item.promo) }} +

      {{ item.value }}

      +
      +{% endmacro %} diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/custom-styles.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/custom-styles.jinja new file mode 100644 index 00000000..c03f73c5 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/custom-styles.jinja @@ -0,0 +1 @@ +/* CSS Comment Test */ diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/head-scripts.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/head-scripts.jinja new file mode 100644 index 00000000..35f0ac9a --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/head-scripts.jinja @@ -0,0 +1 @@ + diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/layout.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/layout.jinja new file mode 100644 index 00000000..9415d144 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/layout.jinja @@ -0,0 +1,140 @@ +{# Idiomatic Jinja2 layout for composed-page: the FULL literal page chrome + (all text lives in templates), with overridable section-default + blocks (meta/socialmeta/page_scripts/endpage_scripts), the inert chrome + fragments as per-fragment includes, the structured navigation rendered + through the imported nav macros, and a live {% block content %} body slot + that extending pages fill. + Docs: https://jinja.palletsprojects.com/en/stable/templates/#template-inheritance + https://jinja.palletsprojects.com/en/stable/templates/#include + https://jinja.palletsprojects.com/en/stable/templates/#import #} +{% from "shared/nav.jinja" import mega_menu, nav_column %} + + + + + + + + + + {% block meta %}Title{% endblock %} + {% block socialmeta %} + + + + {% endblock %} + + + + + + {% include "shared/assets-styles.jinja" %} + + {% include "shared/head-scripts.jinja" %} + + + {% include "shared/body-scripts.jinja" %} +
      +
      + +
      +
      +
      +
      + {% include "shared/alert-top.jinja" %} +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + {% for menu in nav.menus %}{{ mega_menu(menu) }}{% endfor %} +
      +
      +
      + {% include "shared/alert-below.jinja" %} +
      +
      + {% block content %}{% endblock %} +
      +
      +
      +
      +
      + +
      +
      + {% include "shared/assets-scripts.jinja" %} + + {% block page_scripts %}{% endblock %} + {% block endpage_scripts %}{% endblock %} + {% include "shared/body-end-scripts.jinja" %} + + diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/media-row.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/media-row.jinja new file mode 100644 index 00000000..3b691f04 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/media-row.jinja @@ -0,0 +1,13 @@ +{# Idiomatic Jinja2 media-row fragment: the media caption (`Caption for ` + + name) and image src (`/img/` + name + `.jpg`) are template-composed as + literal-plus-substitution. + Doc: https://jinja.palletsprojects.com/en/stable/templates/#macros #} +{% macro media_row(item) %} +
      + {{ item.name }} +
      +

      {{ item.name }}

      +

      Caption for {{ item.name }}

      +
      +
      +{% endmacro %} diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/nav.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/nav.jinja new file mode 100644 index 00000000..58595914 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/nav.jinja @@ -0,0 +1,43 @@ +{# Idiomatic Jinja2 nav macro library for composed-page: the four nested nav + fragments (menu -> column -> section -> link) as macros taking their model + node explicitly; layout.jinja imports mega_menu and nav_column. + Docs: https://jinja.palletsprojects.com/en/stable/templates/#macros + https://jinja.palletsprojects.com/en/stable/templates/#import #} +{% macro nav_link(link) %} + +{% endmacro %} + +{% macro nav_section(section) %} + +{% endmacro %} + +{% macro nav_column(column) %} + +{% endmacro %} + +{% macro mega_menu(menu) %} +
      +
        + {% for tab in menu.tabs %} +
      • {{ tab.label }} + {% if tab.has_dropdown %} +
        + {% for column in tab.columns %}{{ nav_column(column) }}{% endfor %} +
        + {% endif %} +
      • + {% endfor %} +
      +
      +{% endmacro %} diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/price.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/price.jinja new file mode 100644 index 00000000..2345c3e6 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/price.jinja @@ -0,0 +1,7 @@ +{# Idiomatic Jinja2 price sub-fragment: nested inside the card fragment; the + display price is template-composed as the promo price int plus the literal + `.99`. + Doc: https://jinja.palletsprojects.com/en/stable/templates/#macros #} +{% macro price(promo) %} +

      {{ promo.price }}.99

      +{% endmacro %} diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/secondary-retail-menu.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/secondary-retail-menu.jinja new file mode 100644 index 00000000..6c6147b8 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/secondary-retail-menu.jinja @@ -0,0 +1,116 @@ + diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/secondary-wholesale-menu.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/secondary-wholesale-menu.jinja new file mode 100644 index 00000000..b80f8830 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/secondary-wholesale-menu.jinja @@ -0,0 +1,138 @@ + diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/stat.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/stat.jinja new file mode 100644 index 00000000..8e59b9ee --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/stat.jinja @@ -0,0 +1,10 @@ +{# Idiomatic Jinja2 stat fragment: one of the four dispatched fragment kinds, + as a macro imported by fragment-heavy.jinja. + Doc: https://jinja.palletsprojects.com/en/stable/templates/#macros #} +{% macro stat(item) %} +
      + {{ item.name }} + {{ item.value }} + {{ item.delta }} +
      +{% endmacro %} diff --git a/benchmarks/python/templates/jinja2/idiomatic/shared/tile.jinja b/benchmarks/python/templates/jinja2/idiomatic/shared/tile.jinja new file mode 100644 index 00000000..020bb709 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/shared/tile.jinja @@ -0,0 +1,10 @@ +{# Idiomatic Jinja2 tile fragment: one of the four dispatched fragment kinds, + as a macro imported by fragment-heavy.jinja. + Doc: https://jinja.palletsprojects.com/en/stable/templates/#macros #} +{% macro tile(item) %} +
      +

      {{ item.name }}

      +

      {{ item.value }}

      + {{ item.badge }} +
      +{% endmacro %} diff --git a/benchmarks/python/templates/jinja2/idiomatic/trivial-substitution.jinja b/benchmarks/python/templates/jinja2/idiomatic/trivial-substitution.jinja new file mode 100644 index 00000000..5652ac04 --- /dev/null +++ b/benchmarks/python/templates/jinja2/idiomatic/trivial-substitution.jinja @@ -0,0 +1,14 @@ +{# Idiomatic Jinja2 trivial-substitution: plain template, multi-line card, + bare variable expressions. + Doc: https://jinja.palletsprojects.com/en/stable/templates/#variables #} +
      +

      {{ title }}

      +

      {{ sku }}

      +

      {{ price }}

      +

      {{ brand }}

      +

      {{ category }}

      +

      {{ availability }}

      + +

      {{ summary }}

      +

      {{ rating }}

      +
      diff --git a/benchmarks/python/templates/mako/controlled/composed-page.mako b/benchmarks/python/templates/mako/controlled/composed-page.mako new file mode 100644 index 00000000..39308ef0 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/composed-page.mako @@ -0,0 +1,12 @@ +<%inherit file="shared/layout.mako"/>\ +
      +
      +
      +
      +
      + + + +
      +
      +
      diff --git a/benchmarks/python/templates/mako/controlled/conditional-heavy.mako b/benchmarks/python/templates/mako/controlled/conditional-heavy.mako new file mode 100644 index 00000000..8dd04531 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/conditional-heavy.mako @@ -0,0 +1,22 @@ +
        \ +% for r in rows: +
      • \ +% if r["is_bronze"]: +bronze\ +% elif r["is_silver"]: +silver\ +% elif r["is_gold"]: +gold\ +% else: +platinum\ +% endif +${r["name"]}\ +% if r["has_note"]: +note ${r["seq"]}\ +% endif +% if r["is_active"]: +active\ +% endif +
      • \ +% endfor +
      diff --git a/benchmarks/python/templates/mako/controlled/encoded-loop.mako b/benchmarks/python/templates/mako/controlled/encoded-loop.mako new file mode 100644 index 00000000..5cb4bb76 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/encoded-loop.mako @@ -0,0 +1,5 @@ +\ +% for item in items: +\ +% endfor +
      ${item["name"]}${item["comment"]}
      diff --git a/benchmarks/python/templates/mako/controlled/fortunes-encoded.mako b/benchmarks/python/templates/mako/controlled/fortunes-encoded.mako new file mode 100644 index 00000000..371de74c --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/fortunes-encoded.mako @@ -0,0 +1,5 @@ +Fortunes\ +% for r in rows: +\ +% endfor +
      idmessage
      ${r["id"]}${r["message"]}
      diff --git a/benchmarks/python/templates/mako/controlled/fragment-heavy.mako b/benchmarks/python/templates/mako/controlled/fragment-heavy.mako new file mode 100644 index 00000000..d134baa0 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/fragment-heavy.mako @@ -0,0 +1,13 @@ +
      \ +% for item in items: +% if item["is_tile"]: +<%include file="shared/tile.mako" args="item=item"/>\ +% elif item["is_card"]: +<%include file="shared/card.mako" args="item=item"/>\ +% elif item["is_media"]: +<%include file="shared/media-row.mako" args="item=item"/>\ +% else: +<%include file="shared/stat.mako" args="item=item"/>\ +% endif +% endfor +
      diff --git a/benchmarks/python/templates/mako/controlled/large-loop.mako b/benchmarks/python/templates/mako/controlled/large-loop.mako new file mode 100644 index 00000000..3fe43b27 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/large-loop.mako @@ -0,0 +1,3 @@ +% for item in items: +row-${item["value"]}${item["value"]}\ +% endfor diff --git a/benchmarks/python/templates/mako/controlled/mixed-page.mako b/benchmarks/python/templates/mako/controlled/mixed-page.mako new file mode 100644 index 00000000..bf9687d1 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/mixed-page.mako @@ -0,0 +1,39 @@ + + + + +${page_title} + + + +
      +

      ${store_name}

      + +
      +
      +% if show_banner: + +% endif +
      +

      ${hero_heading}

      +

      ${hero_tagline}

      +
      +
      +% for p in products: +

      ${p["name"]}

      MX-${p["sku_number"]}

      ${p["price"]}

      \ +% if p["on_sale"]: +

      On sale

      \ +% endif +

      A dependable workshop staple from batch ${p["batch"]}, checked for daily use and backed by our lifetime guarantee.

      \ +% endfor +
      +% if show_debug_panel: +
      debug
      +% endif +
      +
      +

      ${footer_note}

      +

      ${store_name} ${year} ${support_email}

      +
      + + diff --git a/benchmarks/python/templates/mako/controlled/shared/badge.mako b/benchmarks/python/templates/mako/controlled/shared/badge.mako new file mode 100644 index 00000000..9c98e3ea --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/badge.mako @@ -0,0 +1 @@ +<%page args="promo"/>${promo["label"]}\ diff --git a/benchmarks/python/templates/mako/controlled/shared/card.mako b/benchmarks/python/templates/mako/controlled/shared/card.mako new file mode 100644 index 00000000..010edaff --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/card.mako @@ -0,0 +1 @@ +<%page args="item"/>

      ${item["name"]}

      <%include file="badge.mako" args="promo=item['promo']"/><%include file="price.mako" args="promo=item['promo']"/>

      ${item["value"]}

      \ diff --git a/benchmarks/python/templates/mako/controlled/shared/chrome-alert-below.mako b/benchmarks/python/templates/mako/controlled/shared/chrome-alert-below.mako new file mode 100644 index 00000000..d2f079e7 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/chrome-alert-below.mako @@ -0,0 +1,2 @@ + + \ diff --git a/benchmarks/python/templates/mako/controlled/shared/chrome-alert-top.mako b/benchmarks/python/templates/mako/controlled/shared/chrome-alert-top.mako new file mode 100644 index 00000000..db96f679 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/chrome-alert-top.mako @@ -0,0 +1 @@ +
      holiday shipping
      \ diff --git a/benchmarks/python/templates/mako/controlled/shared/chrome-assets-scripts.mako b/benchmarks/python/templates/mako/controlled/shared/chrome-assets-scripts.mako new file mode 100644 index 00000000..6a29b922 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/chrome-assets-scripts.mako @@ -0,0 +1 @@ +\ diff --git a/benchmarks/python/templates/mako/controlled/shared/chrome-assets-styles.mako b/benchmarks/python/templates/mako/controlled/shared/chrome-assets-styles.mako new file mode 100644 index 00000000..eaa0dc21 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/chrome-assets-styles.mako @@ -0,0 +1 @@ +\ diff --git a/benchmarks/python/templates/mako/controlled/shared/chrome-body-end-scripts.mako b/benchmarks/python/templates/mako/controlled/shared/chrome-body-end-scripts.mako new file mode 100644 index 00000000..e17335ab --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/chrome-body-end-scripts.mako @@ -0,0 +1 @@ +\ diff --git a/benchmarks/python/templates/mako/controlled/shared/chrome-body-scripts.mako b/benchmarks/python/templates/mako/controlled/shared/chrome-body-scripts.mako new file mode 100644 index 00000000..a5d8f089 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/chrome-body-scripts.mako @@ -0,0 +1 @@ +\ diff --git a/benchmarks/python/templates/mako/controlled/shared/chrome-custom-styles.mako b/benchmarks/python/templates/mako/controlled/shared/chrome-custom-styles.mako new file mode 100644 index 00000000..e67c4003 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/chrome-custom-styles.mako @@ -0,0 +1 @@ +/* CSS Comment Test */\ diff --git a/benchmarks/python/templates/mako/controlled/shared/chrome-head-scripts.mako b/benchmarks/python/templates/mako/controlled/shared/chrome-head-scripts.mako new file mode 100644 index 00000000..e524d6cc --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/chrome-head-scripts.mako @@ -0,0 +1 @@ +\ diff --git a/benchmarks/python/templates/mako/controlled/shared/chrome-secondary-retail-menu.mako b/benchmarks/python/templates/mako/controlled/shared/chrome-secondary-retail-menu.mako new file mode 100644 index 00000000..86238347 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/chrome-secondary-retail-menu.mako @@ -0,0 +1,116 @@ + \ diff --git a/benchmarks/python/templates/mako/controlled/shared/chrome-secondary-wholesale-menu.mako b/benchmarks/python/templates/mako/controlled/shared/chrome-secondary-wholesale-menu.mako new file mode 100644 index 00000000..70a61c3e --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/chrome-secondary-wholesale-menu.mako @@ -0,0 +1,138 @@ + \ diff --git a/benchmarks/python/templates/mako/controlled/shared/layout.mako b/benchmarks/python/templates/mako/controlled/shared/layout.mako new file mode 100644 index 00000000..8d343c7f --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/layout.mako @@ -0,0 +1,130 @@ + + + + + + + + + + Title + + + + + + + + + <%include file="chrome-assets-styles.mako"/> + + <%include file="chrome-head-scripts.mako"/> + + + <%include file="chrome-body-scripts.mako"/> +
      +
      + +
      +
      +
      +
      + <%include file="chrome-alert-top.mako"/> +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + +% for menu in nav["menus"]: + <%include file="nav-mega-menu.mako" args="menu=menu"/> +% endfor +
      +
      +
      + <%include file="chrome-alert-below.mako"/> +
      +
      + ${self.body()} +
      +
      +
      +
      +
      + +
      +
      + <%include file="chrome-assets-scripts.mako"/> + + <%include file="chrome-body-end-scripts.mako"/> + + diff --git a/benchmarks/python/templates/mako/controlled/shared/media-row.mako b/benchmarks/python/templates/mako/controlled/shared/media-row.mako new file mode 100644 index 00000000..e9674064 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/media-row.mako @@ -0,0 +1 @@ +<%page args="item"/>
      ${item[

      ${item["name"]}

      Caption for ${item["name"]}

      \ diff --git a/benchmarks/python/templates/mako/controlled/shared/nav-column.mako b/benchmarks/python/templates/mako/controlled/shared/nav-column.mako new file mode 100644 index 00000000..c8a21d9b --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/nav-column.mako @@ -0,0 +1,6 @@ +<%page args="column"/>\ +\ diff --git a/benchmarks/python/templates/mako/controlled/shared/nav-link.mako b/benchmarks/python/templates/mako/controlled/shared/nav-link.mako new file mode 100644 index 00000000..e40b1518 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/nav-link.mako @@ -0,0 +1 @@ +<%page args="link"/>\ diff --git a/benchmarks/python/templates/mako/controlled/shared/nav-mega-menu.mako b/benchmarks/python/templates/mako/controlled/shared/nav-mega-menu.mako new file mode 100644 index 00000000..c5190892 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/nav-mega-menu.mako @@ -0,0 +1,14 @@ +<%page args="menu"/>\ +
        \ +% for tab in menu["tabs"]: +
      • ${tab["label"]}\ +% if tab["has_dropdown"]: +
        \ +% for column in tab["columns"]: +<%include file="nav-column.mako" args="column=column"/>\ +% endfor +
        \ +% endif +
      • \ +% endfor +
      \ diff --git a/benchmarks/python/templates/mako/controlled/shared/nav-section.mako b/benchmarks/python/templates/mako/controlled/shared/nav-section.mako new file mode 100644 index 00000000..0072da73 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/nav-section.mako @@ -0,0 +1,12 @@ +<%page args="section"/>\ +\ diff --git a/benchmarks/python/templates/mako/controlled/shared/price.mako b/benchmarks/python/templates/mako/controlled/shared/price.mako new file mode 100644 index 00000000..f7d64f49 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/price.mako @@ -0,0 +1 @@ +<%page args="promo"/>

      ${promo["price"]}.99

      \ diff --git a/benchmarks/python/templates/mako/controlled/shared/stat.mako b/benchmarks/python/templates/mako/controlled/shared/stat.mako new file mode 100644 index 00000000..9f3d3e80 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/stat.mako @@ -0,0 +1 @@ +<%page args="item"/>
      ${item["name"]}${item["value"]}${item["delta"]}
      \ diff --git a/benchmarks/python/templates/mako/controlled/shared/tile.mako b/benchmarks/python/templates/mako/controlled/shared/tile.mako new file mode 100644 index 00000000..7db21f12 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/shared/tile.mako @@ -0,0 +1 @@ +<%page args="item"/>

      ${item["name"]}

      ${item["value"]}

      ${item["badge"]}
      \ diff --git a/benchmarks/python/templates/mako/controlled/trivial-substitution.mako b/benchmarks/python/templates/mako/controlled/trivial-substitution.mako new file mode 100644 index 00000000..b94ce2d2 --- /dev/null +++ b/benchmarks/python/templates/mako/controlled/trivial-substitution.mako @@ -0,0 +1 @@ +

      ${title}

      ${sku}

      ${price}

      ${brand}

      ${category}

      ${availability}

      ${summary}

      ${rating}

      diff --git a/benchmarks/python/templates/mako/idiomatic/composed-page.mako b/benchmarks/python/templates/mako/idiomatic/composed-page.mako new file mode 100644 index 00000000..e85954aa --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/composed-page.mako @@ -0,0 +1,17 @@ +## Idiomatic Mako composed-page: native template inheritance -- the +## page inherits the full-chrome layout with <%inherit>, and its body (the slider +## markup, the same in both tracks) splices at the layout's live ${self.body()} slot +##. +## Doc: https://docs.makotemplates.org/en/latest/inheritance.html +<%inherit file="shared/layout.mako"/> +
      +
      +
      +
      +
      + + + +
      +
      +
      diff --git a/benchmarks/python/templates/mako/idiomatic/conditional-heavy.mako b/benchmarks/python/templates/mako/idiomatic/conditional-heavy.mako new file mode 100644 index 00000000..2aae705f --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/conditional-heavy.mako @@ -0,0 +1,26 @@ +## Idiomatic Mako conditional-heavy: % if / % elif / % else control lines inside a +## % for loop, authored naturally; the note text (note `seq`) is composed by the +## template. +## Doc: https://docs.makotemplates.org/en/latest/syntax.html#control-structures +
        +% for r in rows: +
      • +% if r["is_bronze"]: +bronze +% elif r["is_silver"]: +silver +% elif r["is_gold"]: +gold +% else: +platinum +% endif +${r["name"]} +% if r["has_note"]: +note ${r["seq"]} +% endif +% if r["is_active"]: +active +% endif +
      • +% endfor +
      diff --git a/benchmarks/python/templates/mako/idiomatic/encoded-loop.mako b/benchmarks/python/templates/mako/idiomatic/encoded-loop.mako new file mode 100644 index 00000000..c0908766 --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/encoded-loop.mako @@ -0,0 +1,12 @@ +<%doc> +Idiomatic Mako encoded-loop: escaping is declared in the template via +<%page expression_filter="h"/>; the attribute value position is escaped by +the same h filter. +Doc: https://docs.makotemplates.org/en/latest/filtering.html + +<%page expression_filter="h"/> + +% for item in items: + +% endfor +
      ${item["name"]}${item["comment"]}
      diff --git a/benchmarks/python/templates/mako/idiomatic/fortunes-encoded.mako b/benchmarks/python/templates/mako/idiomatic/fortunes-encoded.mako new file mode 100644 index 00000000..5ede60d0 --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/fortunes-encoded.mako @@ -0,0 +1,21 @@ +<%doc> +Idiomatic Mako fortunes-encoded: escaping is declared in the template via +<%page expression_filter="h"/> -- the filtering docs' template-declared +escaping pattern; no per-expression filter appears. +Doc: https://docs.makotemplates.org/en/latest/filtering.html + +<%page expression_filter="h"/> + + + +Fortunes + + + + +% for r in rows: + +% endfor +
      idmessage
      ${r["id"]}${r["message"]}
      + + diff --git a/benchmarks/python/templates/mako/idiomatic/fragment-heavy.mako b/benchmarks/python/templates/mako/idiomatic/fragment-heavy.mako new file mode 100644 index 00000000..a14cb718 --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/fragment-heavy.mako @@ -0,0 +1,20 @@ +## Idiomatic Mako fragment-heavy: per-row four-way dispatch on the +## precomputed booleans with % if / % elif / % else control lines, invoking the +## per-kind <%def>s imported from fragments.mako via <%namespace>. +## Docs: https://docs.makotemplates.org/en/latest/defs.html +## https://docs.makotemplates.org/en/latest/namespaces.html +## https://docs.makotemplates.org/en/latest/syntax.html#control-structures +<%namespace file="shared/fragments.mako" import="tile, card, media_row, stat"/> +
      +% for item in items: +% if item["is_tile"]: +${tile(item)} +% elif item["is_card"]: +${card(item)} +% elif item["is_media"]: +${media_row(item)} +% else: +${stat(item)} +% endif +% endfor +
      diff --git a/benchmarks/python/templates/mako/idiomatic/large-loop.mako b/benchmarks/python/templates/mako/idiomatic/large-loop.mako new file mode 100644 index 00000000..8faccdfb --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/large-loop.mako @@ -0,0 +1,6 @@ +## Idiomatic Mako large-loop: % for control lines, one row per source line; the +## display name row-`value` is composed by the template. +## Doc: https://docs.makotemplates.org/en/latest/syntax.html#control-structures +% for item in items: +row-${item["value"]}${item["value"]} +% endfor diff --git a/benchmarks/python/templates/mako/idiomatic/mixed-page.mako b/benchmarks/python/templates/mako/idiomatic/mixed-page.mako new file mode 100644 index 00000000..e097cae0 --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/mixed-page.mako @@ -0,0 +1,49 @@ +## Idiomatic Mako mixed-page: SINGLE-FILE by rule (layout +## composition is composed-page's dimension); the full page skeleton with scalar ${x} +## substitutions and % control lines. The display SKU (MX-`sku_number`) and the blurb +## sentence around `batch` are composed by the template. +## Docs: https://docs.makotemplates.org/en/latest/syntax.html#expression-substitution +## https://docs.makotemplates.org/en/latest/syntax.html#control-structures + + + + +${page_title} + + + +
      +

      ${store_name}

      + +
      +
      +% if show_banner: + +% endif +
      +

      ${hero_heading}

      +

      ${hero_tagline}

      +
      +
      +% for p in products: +
      +

      ${p["name"]}

      +

      MX-${p["sku_number"]}

      +

      ${p["price"]}

      +% if p["on_sale"]: +

      On sale

      +% endif +

      A dependable workshop staple from batch ${p["batch"]}, checked for daily use and backed by our lifetime guarantee.

      +
      +% endfor +
      +% if show_debug_panel: +
      debug
      +% endif +
      +
      +

      ${footer_note}

      +

      ${store_name} ${year} ${support_email}

      +
      + + diff --git a/benchmarks/python/templates/mako/idiomatic/shared/chrome.mako b/benchmarks/python/templates/mako/idiomatic/shared/chrome.mako new file mode 100644 index 00000000..46c6e882 --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/shared/chrome.mako @@ -0,0 +1,289 @@ +## Idiomatic Mako composed-page chrome fragments: the page's inert literal +## text -- alert banner, secondary menus, asset/script snippets -- as a definition-only +## library of <%def> blocks the layout imports via <%namespace> and calls at its +## composition points; importing this file renders nothing. +## Docs: https://docs.makotemplates.org/en/latest/defs.html +## https://docs.makotemplates.org/en/latest/namespaces.html +<%def name="alert_top()">\ +
      holiday shipping
      \ +\ +<%def name="secondary_wholesale_menu()">\ + \ +\ +<%def name="secondary_retail_menu()">\ + \ +\ +<%def name="alert_below()">\ + + \ +\ +<%def name="assets_styles()">\ +\ +\ +<%def name="assets_scripts()">\ +\ +\ +<%def name="custom_styles()">\ +/* CSS Comment Test */\ +\ +<%def name="head_scripts()">\ +\ +\ +<%def name="body_scripts()">\ +\ +\ +<%def name="body_end_scripts()">\ +\ +\ diff --git a/benchmarks/python/templates/mako/idiomatic/shared/fragments.mako b/benchmarks/python/templates/mako/idiomatic/shared/fragments.mako new file mode 100644 index 00000000..75e2d198 --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/shared/fragments.mako @@ -0,0 +1,45 @@ +## Idiomatic Mako fragment-heavy library: the six fragment kinds as +## <%def> blocks -- tile, badge, price, card (which nests badge + price against the +## row's promo, the one nesting level), media_row, and stat -- imported by +## fragment-heavy.mako via <%namespace>. Derived display text (the display price +## `price`.99, the image src /img/`name`.jpg, the caption "Caption for `name`") is +## composed here as literal-plus-substitution. +## Docs: https://docs.makotemplates.org/en/latest/defs.html +## https://docs.makotemplates.org/en/latest/namespaces.html +<%def name="tile(item)"> +
      +

      ${item["name"]}

      +

      ${item["value"]}

      + ${item["badge"]} +
      + +<%def name="badge(promo)"> +${promo["label"]} + +<%def name="price(promo)"> +

      ${promo["price"]}.99

      + +<%def name="card(item)"> +
      +

      ${item["name"]}

      + ${badge(item["promo"])} + ${price(item["promo"])} +

      ${item["value"]}

      +
      + +<%def name="media_row(item)"> +
      + ${item[ +
      +

      ${item["name"]}

      +

      Caption for ${item["name"]}

      +
      +
      + +<%def name="stat(item)"> +
      + ${item["name"]} + ${item["value"]} + ${item["delta"]} +
      + diff --git a/benchmarks/python/templates/mako/idiomatic/shared/layout.mako b/benchmarks/python/templates/mako/idiomatic/shared/layout.mako new file mode 100644 index 00000000..e82e5d2d --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/shared/layout.mako @@ -0,0 +1,140 @@ +## Idiomatic Mako composed-page layout: the full literal page chrome +## with a live body slot -- the inheriting page's content splices at ${self.body()}. +## The inert chrome fragments are <%def>s imported from chrome.mako; the two mega menus +## and the footer columns render from the structured nav model through the nav.mako +## defs inside % for loops. All display text lives in templates. +## Docs: https://docs.makotemplates.org/en/latest/inheritance.html +## https://docs.makotemplates.org/en/latest/namespaces.html +## https://docs.makotemplates.org/en/latest/syntax.html#control-structures +<%namespace file="chrome.mako" import="*"/> +<%namespace file="nav.mako" import="mega_menu, nav_column"/> + + + + + + + + + + Title + + + + + + + + + ${assets_styles()} + + ${head_scripts()} + + + ${body_scripts()} +
      +
      + +
      +
      +
      +
      + ${alert_top()} +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + +% for menu in nav["menus"]: + ${mega_menu(menu)} +% endfor +
      +
      +
      + ${alert_below()} +
      +
      + ${self.body()} +
      +
      +
      +
      +
      + +
      +
      + ${assets_scripts()} + + ${body_end_scripts()} + + diff --git a/benchmarks/python/templates/mako/idiomatic/shared/nav.mako b/benchmarks/python/templates/mako/idiomatic/shared/nav.mako new file mode 100644 index 00000000..5a3c8996 --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/shared/nav.mako @@ -0,0 +1,47 @@ +## Idiomatic Mako composed-page navigation: the structured nav model +## rendered through nested <%def> blocks -- link -> section -> column -> mega menu -- +## imported by the layout via <%namespace> and called from % for loops. +## Definition-only: importing this file renders nothing. +## Docs: https://docs.makotemplates.org/en/latest/defs.html +## https://docs.makotemplates.org/en/latest/namespaces.html +<%def name="nav_link(link)"> + + +<%def name="nav_section(section)"> + + +<%def name="nav_column(column)"> + + +<%def name="mega_menu(menu)"> +
      +
        +% for tab in menu["tabs"]: +
      • ${tab["label"]} +% if tab["has_dropdown"]: +
        +% for column in tab["columns"]: + ${nav_column(column)} +% endfor +
        +% endif +
      • +% endfor +
      +
      + diff --git a/benchmarks/python/templates/mako/idiomatic/trivial-substitution.mako b/benchmarks/python/templates/mako/idiomatic/trivial-substitution.mako new file mode 100644 index 00000000..f461305c --- /dev/null +++ b/benchmarks/python/templates/mako/idiomatic/trivial-substitution.mako @@ -0,0 +1,16 @@ +<%doc> +Idiomatic Mako trivial-substitution: plain template, multi-line card, +${} expression substitution. +Doc: https://docs.makotemplates.org/en/latest/syntax.html#expression-substitution + +
      +

      ${title}

      +

      ${sku}

      +

      ${price}

      +

      ${brand}

      +

      ${category}

      +

      ${availability}

      + +

      ${summary}

      +

      ${rating}

      +
      diff --git a/benchmarks/report/consolidate.py b/benchmarks/report/consolidate.py new file mode 100644 index 00000000..2b4a2819 --- /dev/null +++ b/benchmarks/report/consolidate.py @@ -0,0 +1,1333 @@ +#!/usr/bin/env python3 +"""Assemble the published tables for a cross-stack benchmark run directory. + +Stdlib-only, CPython >= 3.12. Reads a run directory's raw harness artifacts and writes +`consolidated-tables.md` and `summary-tables.md` next to them. The report's `index.md` embeds the +latter with VitePress's `` directive and links the former; `--check` re-derives +both and diffs against the committed files, so the report is byte-reproducible from the artifacts. + +Table ORDER is owned by this script, not by the report: workloads are emitted tier 1 (realistic +sizing) before tier 2 (edge-case sizing), ascending by rendered size within each tier. See the +`sizing regimes` block below for how the tier is derived. + + python benchmarks/report/consolidate.py docs/benchmarks/2026-07-25 + python benchmarks/report/consolidate.py --check docs/benchmarks/2026-07-25 + +Contract: + + * No new measurements and no new metrics. The only arithmetic is unit conversion to + ns/render, the `vs Heddle` ratio, and the implied-throughput plausibility figure + (rendered output size / ns) required on every cross-stack table. + * Each ecosystem contributes its harness's default central-tendency point estimate with the + harness-native dispersion alongside. That statistic mapping is a contract this script may + not vary. + * No geomean, points total, medal count, cross-workload average or aggregate score is + emitted anywhere. benchstat's `geomean` rows are read past deliberately. +""" + +from __future__ import annotations + +import argparse +import csv +import json +import re +import statistics +import sys +from dataclasses import dataclass +from pathlib import Path + +REPO = Path(__file__).resolve().parents[2] +MANIFEST = REPO / "benchmarks" / "dotnet" / "GoldenCorpus" / "manifest.json" +OUTPUT_NAME = "consolidated-tables.md" +# The headline tables index.md embeds via VitePress ``, so the narrative page +# never hand-transcribes a measured number. +SUMMARY_NAME = "summary-tables.md" + +# The fixed ecosystem order every table and sidebar below uses. +ECOSYSTEMS = [".NET", "Rust", "JVM", "JS", "Python", "Go"] + +# Evidence class per ecosystem, published as a per-row column on the cross-stack tables. +EVIDENCE = { + ".NET": "fair fight", + "Rust": "fair fight", + "JVM": "fair fight", + "Go": "fair fight", + "JS": "reach/context", + "Python": "reach/context", +} + + +# Display names, pinned to the versions in each harness's manifest. +ENGINE_NAMES = { + (".NET", "Heddle"): "Heddle", + # Heddle's streaming sinks, measured as their own rows in the cross-stack sweep. They are the + # SAME engine as the anchor doing the same work through a different output path, so they are + # reported everywhere .NET rows are reported but never ranked as if they were rival engines -- + # see HEDDLE_TECHNIQUE_ENGINES. + (".NET", "HeddleUtf8"): "Heddle (utf8 sink)", + (".NET", "HeddleTextWriter"): "Heddle (textwriter sink)", + (".NET", "Fluid"): "Fluid.Core 2.31.0", + (".NET", "Scriban"): "Scriban 7.2.5", + (".NET", "DotLiquid"): "DotLiquid 2.3.197", + (".NET", "Handlebars"): "Handlebars.Net 2.1.6", + (".NET", "Razor"): "Razor (full page)", + ("Rust", "askama"): "Askama 0.16.0", + ("Rust", "tera"): "Tera 2.0.0", + ("JVM", "jte"): "JTE 3.2.4", + ("JVM", "thymeleaf"): "Thymeleaf 3.1.5", + ("JS", "handlebars"): "handlebars 4.7.9", + ("JS", "eta"): "eta 4.6.0", + ("Python", "jinja2"): "Jinja2 3.1.6", + ("Python", "mako"): "Mako 1.3.12", + ("Go", "stdlib-text"): "text/template (go1.26)", + ("Go", "stdlib-html"): "html/template (go1.26)", + ("Go", "templ"): "templ v0.3.1020", +} + +# Razor became a real byte-parity twin on 2026-07-25: it now renders +# `Views/twin-*.cshtml` off the shared TwinContent fixtures and is asserted by ParityCheck like +# Fluid/Scriban/DotLiquid/Handlebars. Before that it rendered the full `Views/layout.cshtml` page — +# a larger, different payload — and sat outside every gate. +# +# Run directories predating that date hold the OLD measurement, so they must keep the caveat: the +# figure in them really is a different workload, and its implied throughput really is meaningless +# against the golden byte length. Runs from that date onward get a plain twin row. Keying this to +# the run date rather than deleting the branch is what keeps already-published evidence honest. +RAZOR_PARITY_FROM = "2026-07-25" + +# Engines measured and ranked like every other row but NOT under the byte-parity assertion in the +# run being processed. Every measured cell is still published and ranked — nothing is dropped — but +# these rows carry the reason inline and their implied-throughput figure is withheld, since the +# golden byte length does not describe what they produced. This has nothing to do with whitespace: +# the parity gate's N3b rule already strips every whitespace run from both sides before comparing, +# so whitespace differences never disqualify a cell anywhere in this program. +NOT_PARITY_CHECKED: dict[tuple[str, str], str] = {} + +_RAZOR_LEGACY_REASON = ( + "renders the full Views/layout.cshtml page — a larger, different payload, not the golden " + "output; therefore outside the parity assertion in this run and its implied-throughput " + "figure is withheld. Razor became a byte-parity twin on " + RAZOR_PARITY_FROM + + "; runs from that date onward carry a plain twin row, and this run predates it" +) + + +def configure_run_era(run: Path) -> bool: + """Set up the Razor-era-dependent tables from the run directory's date. Returns True if the + run postdates the Razor parity change.""" + razor_is_twin = run.name >= RAZOR_PARITY_FROM # both are ISO dates; lexical == chronological + NOT_PARITY_CHECKED.clear() + if razor_is_twin: + ENGINE_NAMES[(".NET", "Razor")] = "Razor (ASP.NET Core MVC)" + else: + ENGINE_NAMES[(".NET", "Razor")] = "Razor (full page)" + NOT_PARITY_CHECKED[(".NET", "Razor (full page)")] = _RAZOR_LEGACY_REASON + return razor_is_twin + + +# Display names of the Heddle rows that are NOT the anchor: the same engine measured through a +# different sink. They are excluded from every ranking and from the "next .NET engine" margin, +# because ranking an engine against itself would both inflate the field size and let Heddle appear +# in its own "ahead of it" list. They remain visible in the .NET per-ecosystem tables, the +# allocation sidebar and the dedicated techniques section. +# +# They are also not like-for-like with the competitor rows in a second way: the streaming sinks +# never materialise their output, while every competitor row (and the anchor) does. That is the +# point of measuring them, and the reason they cannot stand in a materialised-output ranking. +HEDDLE_TECHNIQUE_ENGINES = frozenset({"Heddle (utf8 sink)", "Heddle (textwriter sink)"}) + + +def is_heddle_technique(cell: Cell) -> bool: + return cell.ecosystem == ".NET" and cell.engine in HEDDLE_TECHNIQUE_ENGINES + + +def evidence_of(cell: Cell) -> str: + if cell.ecosystem == ".NET" and cell.engine == "Heddle": + return "anchor (baseline)" + if is_heddle_technique(cell): + return "same engine, streaming sink" + if (cell.ecosystem, cell.engine) in NOT_PARITY_CHECKED: + return "not parity-checked" + return EVIDENCE[cell.ecosystem] + + +# .NET cross-stack suite class -> workload; a fixed mapping, never re-derived from artifacts. +# The class names are the workload ids in Pascal case, matching the JVM harness's convention; +# renaming a suite in benchmarks/dotnet means renaming its row here. +DOTNET_SUITES = { + "ComposedPageBenchmarks": "composed-page", + "TrivialSubstitutionBenchmarks": "trivial-substitution", + "LargeLoopBenchmarks": "large-loop", + "MixedPageBenchmarks": "mixed-page", + "ConditionalHeavyBenchmarks": "conditional-heavy", + "FragmentHeavyBenchmarks": "fragment-heavy", + "FortunesEncodedBenchmarks": "fortunes-encoded", + "EncodedLoopBenchmarks": "encoded-loop", +} +# Every .NET artifact is namespaced by the harness assembly. +DOTNET_PREFIX = "Heddle.Benchmarks.Dotnet.Bench." +# Sidebar suites in the same directory: Heddle against itself (render techniques, props, +# branching, language-service metadata). Not competitor tables — excluded from every comparison +# and every ranking, surfaced only in the .NET sidebar. +DOTNET_NON_COMPETITOR = ( + "TechniqueRuntimeBenchmarks", + "TechniquePrecompiledBenchmarks", + "PropsBenchmarks", + "BranchBenchmarks", + "LanguageServiceBenchmarks", +) +# The cold parse/compile sidebar, which does contribute cold-compile cells. +DOTNET_COLD_SUITE = "ColdCompileBenchmarks" + +# JMH class prefix -> workload. +JVM_CLASSES = { + "ComposedPage": "composed-page", + "TrivialSubstitution": "trivial-substitution", + "LargeLoop": "large-loop", + "MixedPage": "mixed-page", + "ConditionalHeavy": "conditional-heavy", + "FragmentHeavy": "fragment-heavy", + "FortunesEncoded": "fortunes-encoded", + "EncodedLoop": "encoded-loop", +} + +TIME_UNITS = {"ns": 1.0, "us": 1e3, "µs": 1e3, "μs": 1e3, "ms": 1e6, "s": 1e9} +BYTE_UNITS = {"B": 1.0, "KB": 1024.0, "MB": 1024.0**2, "KiB": 1024.0, "MiB": 1024.0**2} +# benchstat's SI suffixes on a sec/op column. +BENCHSTAT_UNITS = {"n": 1.0, "µ": 1e3, "u": 1e3, "m": 1e6, "": 1e9} + + +# Implied-throughput ceiling, in output bytes per nanosecond. Above this a cell claims more +# sustained store bandwidth than a single core of the protocol machine has while *also* running +# template logic, so the harness cannot be materialising the full output. Set from the observed +# distribution of an earlier run, which had a clean gap. It is deliberately CONSERVATIVE for +# modern hardware: a raw 55,466-byte memcpy on the 2026-07-25 box costs 438 ns, i.e. 126 B/ns, so +# a compiled template that is largely a memcpy of literal chunks can legitimately sit above 50. +# A flagged cell means "look at this", not "this is impossible" — the authoritative materialisation +# control is the harness-side MATERIALISATION-CHECK, not this ceiling. +PLAUSIBILITY_CEILING_B_PER_NS = 50.0 + +# ---- sizing regimes --------------------------------------------------------------------------- +# +# The CLR allocates any object of 85,000 bytes or more on the Large Object Heap, and .NET strings +# are UTF-16 — so a rendered page crosses that line at 42,500 characters, and every render past it +# allocates on the LOH and drives a full, blocking Gen2 collection. The step is sharp and +# measurable: on the 2026-07-25 box `new string(ReadOnlySpan)` sustains 40.3 B/ns at +# 84,800 B and 8.9 B/ns at 108,680 B — 4.5x, at the threshold. None of the other five ecosystems +# has this cliff; their outputs are UTF-8 or Latin-1 and stay on the normal heap. +# +# Workloads on either side of that boundary are therefore not measuring the same thing, so the +# generated tables lead with the ones below it and present the ones above it as edge cases with +# the caveat attached, instead of using the normative protocol order. The protocol order is not +# lost — it is what `manifest.json` records. +LOH_THRESHOLD_BYTES = 85_000 +UTF16_BYTES_PER_CHAR = 2 + +# Rendered output length in CHARACTERS, which is what decides the LOH question. This is NOT the +# golden `byteLength`: the golden is the NORMALIZED form (the stored-form whitespace collapse in +# Gate/Normalize.cs runs before the oracle is stored). The two agree within a few percent on +# seven of the eight workloads and differ by ~1.15x on composed-page (41,111 B stored, 47,455 +# chars rendered since the full-page redesign), so using the golden here would understate that +# workload's implied throughput. +# +# Measured 2026-07-25, re-measured 2026-08-08 after the redesign for the two workloads +# whose output changed (composed-page, fragment-heavy): .NET via `HeddleTest.Render()`, JS via +# `tracks.controlled.[]()`, Rust via `engines::askama_controlled::render_*()`. The +# three ecosystems agree within 2% (they differ only in whitespace, which N3b erases before the +# gate compares); the .NET figure is recorded because it is the one that decides the LOH +# question. Re-measure if templates or models change. A workload missing from this table falls +# back to the golden byteLength and is footnoted as such in the generated tables, so a new +# workload degrades loudly rather than silently. +RENDERED_CHARS: dict[str, int] = { + "composed-page": 47_455, + "trivial-substitution": 338, + "large-loop": 192_780, + "mixed-page": 9_740, + "conditional-heavy": 15_549, + "fragment-heavy": 6_058, + "fortunes-encoded": 1_157, + "encoded-loop": 851_685, +} + +# A workload whose rendered size differs from its golden byteLength by more than this fraction +# gets an explicit both-figures caption, because the reader would otherwise take the golden as +# the payload. +SIZE_DIVERGENCE_NOTE_THRESHOLD = 0.05 + +TIER_TITLES = { + 1: "Tier 1 — realistic sizing", + 2: "Tier 2 — edge-case sizing", +} + +TIER_BLURBS = { + 1: ( + "Outputs that fit the size of a real page, partial or fragment, and stay clear of the " + f"{LOH_THRESHOLD_BYTES:,}-byte Large Object Heap threshold once materialised as UTF-16. " + "**These are the primary results.**" + ), + 2: ( + "Outputs that exceed the " + f"{LOH_THRESHOLD_BYTES:,}-byte Large Object Heap threshold as UTF-16, so every .NET " + "render allocates on the LOH and drives a full Gen2 collection — a cost structural to the " + "runtime and absent in the other five ecosystems. These are stress tests, not page " + "renders; read them with that caveat attached." + ), +} + + +def rendered_chars(workload: str, golden_bytes: dict[str, int]) -> tuple[int, bool]: + """(chars, measured). Falls back to the golden byteLength when the workload is unmeasured.""" + if workload in RENDERED_CHARS: + return RENDERED_CHARS[workload], True + return golden_bytes[workload], False + + +def tier_of(workload: str, golden_bytes: dict[str, int]) -> int: + """1 below the LOH threshold, 2 at or above it. Derived, never declared per workload.""" + chars, _ = rendered_chars(workload, golden_bytes) + return 2 if chars * UTF16_BYTES_PER_CHAR >= LOH_THRESHOLD_BYTES else 1 + + +def ordered_workloads(workloads: list[str], golden_bytes: dict[str, int]) -> list[str]: + """Tier 1 first, then tier 2; ascending by rendered size within each tier.""" + return sorted( + workloads, + key=lambda w: (tier_of(w, golden_bytes), rendered_chars(w, golden_bytes)[0], w), + ) + + +def size_caption(workload: str, golden_bytes: dict[str, int]) -> str: + """The size clause for a table caption, naming both figures when they diverge.""" + chars, measured = rendered_chars(workload, golden_bytes) + gold = golden_bytes[workload] + if not measured: + return f"{gold:,} B golden output (rendered size unmeasured — see RENDERED_CHARS)" + if abs(chars - gold) / gold > SIZE_DIVERGENCE_NOTE_THRESHOLD: + return f"{chars:,} B rendered output ({gold:,} B golden, after whitespace normalization)" + return f"{chars:,} B rendered output" + + +# mitata's per-render heap estimate, keyed (track, engine, workload). Populated by load_js and +# used only by the JS materialisation register, where it corroborates the throughput signal. +JS_HEAP: dict[tuple[str, str, str], float] = {} + + +class Fail(Exception): + """A structural assumption about an artifact did not hold.""" + + +# ---- helpers --------------------------------------------------------------------------------- + + +def parse_quantity(text: str, units: dict[str, float]) -> float: + """`25.31 μs` / `1,733.8 ns` / `227.86 KB` -> a float in the units' base unit.""" + m = re.match(r"^\s*([\d,.]+)\s*(\S+)\s*$", text) + if not m: + raise Fail(f"not a ` ` quantity: {text!r}") + unit = m.group(2) + if unit not in units: + raise Fail(f"unknown unit {unit!r} in {text!r}") + return float(m.group(1).replace(",", "")) * units[unit] + + +def fmt_time(ns: float) -> str: + """Native-unit rendering, matching the convention in benchmarks/rust/src/bin/summarize.rs.""" + if ns < 1_000: + return f"{ns:.4g} ns" + if ns < 1_000_000: + return f"{ns / 1e3:.4g} μs" + return f"{ns / 1e6:.4g} ms" + + +def fmt_ns(ns: float) -> str: + return f"{ns:,.0f}" + + +def fmt_bytes(b: float) -> str: + if b < 1024: + return f"{b:.0f} B" + if b < 1024**2: + return f"{b / 1024:.2f} KB" + return f"{b / 1024**2:.2f} MB" + + +def fmt_ratio(value: float) -> str: + return f"{value:.2f}" + + +def table(header: list[str], aligns: list[str], rows: list[list[str]]) -> list[str]: + sep = {"l": "---", "r": "---:", "c": ":---:"} + out = ["| " + " | ".join(header) + " |", "| " + " | ".join(sep[a] for a in aligns) + " |"] + out += ["| " + " | ".join(r) + " |" for r in rows] + return out + + +# ---- the cell record ------------------------------------------------------------------------ + + +@dataclass(frozen=True) +class Cell: + ecosystem: str + engine: str # display name + track: str # controlled | idiomatic | cold-compile + workload: str + ns: float + stat: str # native-unit point estimate + dispersion: str # native-unit dispersion + + +def name(ecosystem: str, engine: str) -> str: + try: + return ENGINE_NAMES[(ecosystem, engine)] + except KeyError: + raise Fail(f"no display name pinned for {ecosystem} engine {engine!r}") from None + + +# ---- per-ecosystem parsers ------------------------------------------------------------------ + + +def _dotnet_dispersion(row: dict) -> str: + """`Error` plus `StdDev`. A one-iteration job reports no StdDev + column at all, so it degrades rather than raising a KeyError on an otherwise readable row.""" + sd = (row.get("StdDev") or "").strip() + return f"±{row['Error'].strip()}" + (f" (SD {sd})" if sd else "") + + +def load_dotnet(run: Path) -> tuple[list[Cell], list[list[str]]]: + """BenchmarkDotNet CSV: `Mean`, dispersion `Error` + `StdDev`. + + Values are formatted strings with units that vary per row and per suite. Each suite carries + BOTH fairness tracks — the `Track` column is a BenchmarkDotNet parameter — so one artifact + holds six engines twice over. + """ + cells: list[Cell] = [] + alloc: list[list[str]] = [] + results = run / "dotnet" / "results" + for suite, workload in DOTNET_SUITES.items(): + path = results / f"{DOTNET_PREFIX}{suite}-report.csv" + if not path.exists(): + raise Fail(f"missing .NET artifact: {path.relative_to(run)}") + with path.open(encoding="utf-8-sig", newline="") as fh: + rows = list(csv.DictReader(fh)) + if not rows: + raise Fail(f"empty .NET artifact: {path.relative_to(run)}") + for row in rows: + method = row["Method"] + if not method.startswith("Render"): + raise Fail(f"unexpected .NET method {method!r} in {suite}") + engine = method[len("Render") :] + track = (row.get("Track") or "").strip() + if track not in ("controlled", "idiomatic"): + raise Fail(f"unexpected .NET track {track!r} in {suite} ({method})") + ns = parse_quantity(row["Mean"], TIME_UNITS) + cells.append( + Cell(".NET", name(".NET", engine), track, workload, ns, + row["Mean"].strip(), _dotnet_dispersion(row)) + ) + allocated = (row.get("Allocated") or "").strip() + if allocated and allocated != "NA": + display = name(".NET", engine) + alloc.append([ + workload, + display + " ‡" if display in HEDDLE_TECHNIQUE_ENGINES else display, + track, allocated, + (row.get("Alloc Ratio") or "").strip() or "—", + " / ".join((row.get(g) or "-").strip() or "-" for g in ("Gen0", "Gen1", "Gen2")), + ]) + return cells, alloc + + +def load_dotnet_cold(run: Path) -> list[Cell]: + """The .NET cold parse/compile sidebar. Per-ecosystem only, never cross-compared. + + The method name carries the disclosure the table needs: `Parse*` rows produce an + interpretable tree, `Compile*` rows produce executable code, and those are different steps. + """ + cells: list[Cell] = [] + path = run / "dotnet" / "results" / f"{DOTNET_PREFIX}{DOTNET_COLD_SUITE}-report.csv" + if not path.exists(): + return cells + with path.open(encoding="utf-8-sig", newline="") as fh: + for row in csv.DictReader(fh): + ns = parse_quantity(row["Mean"], TIME_UNITS) + cells.append(Cell(".NET", row["Method"].strip(), "cold-compile", "composed-page", ns, + row["Mean"].strip(), _dotnet_dispersion(row))) + return cells + + +def load_dotnet_internal(run: Path) -> list[list[str]]: + """The Heddle-internal .NET suites, for the .NET sidebar only.""" + rows: list[list[str]] = [] + results = run / "dotnet" / "results" + for suite in DOTNET_NON_COMPETITOR: + path = results / f"{DOTNET_PREFIX}{suite}-report.csv" + if not path.exists(): + continue + with path.open(encoding="utf-8-sig", newline="") as fh: + for row in csv.DictReader(fh): + # The technique suites parameterize on Workload; the rest have no parameter. + subject = (row.get("Workload") or "").strip() + method = row["Method"] + (f" ({subject})" if subject else "") + rows.append([ + suite, method, row["Mean"].strip(), + (row.get("Allocated") or "—").strip() or "—", + ]) + return rows + + +def load_rust(run: Path) -> tuple[list[Cell], list[Cell]]: + """Criterion: `mean.point_estimate`, dispersion = the 95% CI bounds. `new/` only.""" + cells: list[Cell] = [] + cold: list[Cell] = [] + base = run / "rust" / "criterion" + for est in sorted(base.glob("*/*/new/estimates.json")): + group = est.parents[2].name + engine = est.parents[1].name + mean = json.loads(est.read_text(encoding="utf-8"))["mean"] + ns = float(mean["point_estimate"]) + ci = mean["confidence_interval"] + disp = f"[{fmt_time(ci['lower_bound'])}, {fmt_time(ci['upper_bound'])}] 95% CI" + if group == "cold": + # criterion's function id here is the cold sidebar's own name, not an engine id. + label = {"tera-parse-all-templates": "Tera 2.0.0 (parse all templates)"}.get( + engine, engine) + cold.append(Cell("Rust", label, "cold-compile", "all templates", ns, + fmt_time(ns), disp)) + continue + track, _, workload = group.partition("-") + if track not in ("controlled", "idiomatic"): + raise Fail(f"unexpected criterion group {group!r}") + cells.append(Cell("Rust", name("Rust", engine), track, workload, ns, + fmt_time(ns), disp)) + if not cells: + raise Fail("no criterion estimates found under rust/criterion") + return cells, cold + + +def load_jvm(run: Path) -> tuple[list[Cell], list[list[str]]]: + """JMH `Mode.AverageTime`: `primaryMetric.score`, dispersion `scoreError` (99.9% CI).""" + path = run / "jvm" / "jmh-result.json" + if not path.exists(): + raise Fail("missing jvm/jmh-result.json") + cells: list[Cell] = [] + alloc: list[list[str]] = [] + for entry in json.loads(path.read_text(encoding="utf-8")): + cls, _, method = entry["benchmark"].rpartition(".") + cls = cls.rsplit(".", 1)[-1] + if not cls.endswith("Bench"): + raise Fail(f"unexpected JMH class {cls!r}") + workload = JVM_CLASSES.get(cls[: -len("Bench")]) + if workload is None: + raise Fail(f"unmapped JMH class {cls!r}") + for track in ("controlled", "idiomatic"): + if method.endswith(track.capitalize()): + engine = method[: -len(track)] + break + else: + raise Fail(f"unexpected JMH method {method!r}") + pm = entry["primaryMetric"] + if pm["scoreUnit"] != "ns/op": + raise Fail(f"unexpected JMH unit {pm['scoreUnit']!r}") + ns = float(pm["score"]) + cells.append(Cell("JVM", name("JVM", engine), track, workload, ns, + fmt_time(ns), f"±{fmt_time(float(pm['scoreError']))} 99.9% CI")) + norm = entry.get("secondaryMetrics", {}).get("gc.alloc.rate.norm") + if norm: + alloc.append([ + workload, name("JVM", engine), track, + fmt_bytes(float(norm["score"])), + f"{entry['secondaryMetrics']['gc.count']['score']:.0f}", + ]) + return cells, alloc + + +def load_js(run: Path) -> tuple[list[Cell], list[Cell]]: + """mitata: the reported `avg`, dispersion = the emitted min…max spread. + + The JSON carries no workload name — `alias` is only the engine, repeated once per workload, + so the workload is positional. That is safe because benchmarks/js/bench/_shared.mjs + `registerTrackGroups()` iterates WORKLOAD_IDS in protocol order, but it is asserted here + rather than assumed. `cold-compile.json` alone carries composite aliases. + """ + workloads = [e["workload"] for e in golden_entries()] + cells: list[Cell] = [] + cold: list[Cell] = [] + + for track in ("controlled", "idiomatic"): + path = run / "js" / f"{track}.json" + if not path.exists(): + raise Fail(f"missing js/{track}.json") + data = json.loads(path.read_text(encoding="utf-8")) + expected = 2 * len(workloads) + if len(data) != expected: + raise Fail(f"js/{track}.json: expected {expected} entries, found {len(data)}") + groups = [e.get("group") for e in data] + if any(groups[i] != groups[i + 1] for i in range(0, len(groups), 2)): + raise Fail(f"js/{track}.json: entries are not engine-paired per group") + pair_groups = groups[::2] + if any(b <= a for a, b in zip(pair_groups, pair_groups[1:])): + raise Fail(f"js/{track}.json: group ids are not strictly ascending") + aliases = [e["alias"] for e in data] + if aliases[0::2] != ["handlebars"] * len(workloads) or aliases[1::2] != ["eta"] * len(workloads): + raise Fail(f"js/{track}.json: alias order is not handlebars/eta per group") + for i, entry in enumerate(data): + st = entry["runs"][0]["stats"] + ns = float(st["avg"]) + disp = f"{fmt_time(float(st['min']))} … {fmt_time(float(st['max']))}" + cells.append(Cell("JS", name("JS", entry["alias"]), track, workloads[i // 2], + ns, fmt_time(ns), disp)) + + global JS_HEAP + JS_HEAP = {} + for track in ("controlled", "idiomatic"): + data = json.loads((run / "js" / f"{track}.json").read_text(encoding="utf-8")) + for i, entry in enumerate(data): + heap = entry["runs"][0]["stats"].get("heap") or {} + if "avg" in heap: + JS_HEAP[(track, entry["alias"], workloads[i // 2])] = float(heap["avg"]) + + path = run / "js" / "cold-compile.json" + if path.exists(): + for entry in json.loads(path.read_text(encoding="utf-8")): + engine, _, workload = entry["alias"].partition(" ") + st = entry["runs"][0]["stats"] + ns = float(st["avg"]) + cold.append(Cell("JS", name("JS", engine), "cold-compile", workload, ns, + fmt_time(ns), + f"{fmt_time(float(st['min']))} … {fmt_time(float(st['max']))}")) + return cells, cold + + +def load_python(run: Path) -> tuple[list[Cell], list[Cell], list[list[str]]]: + """pyperf: the reported mean with its standard deviation. + + pyperf stores no precomputed mean, so it is aggregated from every measurement run's + `values` (seconds). runs[0] is the calibration run and carries `warmups` but no `values`. + """ + def aggregate(path: Path) -> list[tuple[str, str, str, float, float]]: + doc = json.loads(path.read_text(encoding="utf-8")) + out = [] + for bench in doc["benchmarks"]: + parts = bench["metadata"]["name"].split("/") + if len(parts) != 3: + raise Fail(f"{path.name}: unexpected pyperf name {bench['metadata']['name']!r}") + engine, track, workload = parts + values = [v for r in bench["runs"] if "values" in r for v in r["values"]] + if not values: + raise Fail(f"{path.name}: no measurement values for {'/'.join(parts)}") + out.append((engine, track, workload, + statistics.mean(values) * 1e9, + statistics.stdev(values) * 1e9 if len(values) > 1 else 0.0)) + return out + + cells: list[Cell] = [] + for track in ("controlled", "idiomatic"): + for engine in ("jinja2", "mako"): + path = run / "python" / f"bench_{engine}_{track}.json" + if not path.exists(): + raise Fail(f"missing python/{path.name}") + for eng, tr, workload, ns, sd in aggregate(path): + if tr != track: + raise Fail(f"{path.name}: track {tr!r} in the {track} file") + cells.append(Cell("Python", name("Python", eng), track, workload, ns, + fmt_time(ns), f"SD {fmt_time(sd)}")) + + cold: list[Cell] = [] + cold_path = run / "python" / "bench_cold_compile.json" + if cold_path.exists(): + for eng, _, workload, ns, sd in aggregate(cold_path): + cold.append(Cell("Python", name("Python", eng), "cold-compile", workload, ns, + fmt_time(ns), f"SD {fmt_time(sd)}")) + + alloc: list[list[str]] = [] + mem_path = run / "python" / "memory.json" + if mem_path.exists(): + mem = json.loads(mem_path.read_text(encoding="utf-8")) + for key in sorted(mem): + engine, track, workload = key.split("/") + rec = mem[key] + alloc.append([ + workload, name("Python", engine), track, + fmt_bytes(rec["allocated"]["mean"]), fmt_bytes(rec["retained"]["mean"]), + str(rec["repetitions"]), + ]) + return cells, cold, alloc + + +def load_go(run: Path) -> tuple[list[Cell], list[Cell], list[list[str]]]: + """benchstat: the `sec/op` summary (median-based) with its ±% variation. + + The point estimate and dispersion both come from benchstat, per the statistic mapping. The + `B/op` and `allocs/op` blocks feed the Go sidebar. benchstat's `geomean` rows are skipped: + no aggregate score is ever published. + """ + ROW = re.compile( + r"^(?P\S+?)-\d+\s+(?P[\d.]+)(?P[a-zA-Zµ]*)\s*±\s*(?P[\d.]+|\?)%?" + ) + + def blocks(path: Path) -> dict[str, list[tuple[str, str, str]]]: + """column-name -> [(bench name, value+unit, ±pct)]""" + out: dict[str, list[tuple[str, str, str]]] = {} + column = None + for line in path.read_text(encoding="utf-8").splitlines(): + if "│" in line: # a benchstat header rule: │ label │ + label = line.replace("│", " ").strip() + if label and "/" in label or label in ("sec/op", "B/op", "allocs/op"): + if label in ("sec/op", "B/op", "allocs/op"): + column = label + out.setdefault(column, []) + continue + if line.startswith("geomean"): + continue # no aggregate score is ever published + m = ROW.match(line.strip()) + if not m or column is None: + continue + out[column].append( + (m.group("name"), m.group("value") + m.group("unit"), m.group("pct")) + ) + return out + + render = newest_go_artifact(run, "benchstat-render-*.txt") + if render is None: + raise Fail("missing go/benchstat-render-*.txt") + data = blocks(render) + if "sec/op" not in data: + raise Fail("go benchstat: no sec/op block found") + + cells: list[Cell] = [] + by_name_alloc: dict[str, dict[str, str]] = {} + for bench, value, pct in data["sec/op"]: + parts = bench.split("/") + if len(parts) != 4 or parts[0] != "Render": + raise Fail(f"unexpected Go bench name {bench!r}") + _, track, workload, engine = parts + m = re.match(r"^([\d.]+)([a-zA-Zµ]*)$", value) + if not m or m.group(2) not in BENCHSTAT_UNITS: + raise Fail(f"unparsable benchstat sec/op value {value!r}") + ns = float(m.group(1)) * BENCHSTAT_UNITS[m.group(2)] + cells.append(Cell("Go", name("Go", engine), track, workload, ns, + fmt_time(ns), f"±{pct}%")) + for column in ("B/op", "allocs/op"): + for bench, value, _ in data.get(column, []): + by_name_alloc.setdefault(bench, {})[column] = value + + alloc: list[list[str]] = [] + for bench in sorted(by_name_alloc): + _, track, workload, engine = bench.split("/") + rec = by_name_alloc[bench] + alloc.append([workload, name("Go", engine), track, + rec.get("B/op", "—"), rec.get("allocs/op", "—")]) + + cold: list[Cell] = [] + coldparse = newest_go_artifact(run, "benchstat-coldparse-*.txt") + if coldparse is not None: + for bench, value, pct in blocks(coldparse).get("sec/op", []): + engine = bench.split("/")[-1] + m = re.match(r"^([\d.]+)([a-zA-Zµ]*)$", value) + ns = float(m.group(1)) * BENCHSTAT_UNITS[m.group(2)] + cold.append(Cell("Go", name("Go", engine), "cold-compile", "all templates", ns, + fmt_time(ns), f"±{pct}%")) + return cells, cold, alloc + + +# ---- corpus --------------------------------------------------------------------------------- + + +def golden_entries() -> list[dict]: + doc = json.loads(MANIFEST.read_text(encoding="utf-8")) + return doc["entries"] + + +def newest_go_artifact(run: Path, pattern: str) -> Path | None: + """The most recent `benchstat-*-.txt`, not merely the first one sorted. + + `benchmarks/go/results/` is an accumulating directory and the runner copies all of it into the + run, so a run folder routinely holds several dates. Plain `sorted(...)[0]` took the ASCII-first + name, which is the OLDEST -- a report that silently described a previous session's Go leg while + every other ecosystem's rows came from this one. The stamp is `YYYYMMDD`, so lexical `max` is + chronological; mtime is deliberately not used, since copying does not preserve it reliably. + """ + return max((run / "go").glob(pattern), default=None) + + +def toolchain_table(run: Path) -> list[str]: + """The pin-drift table, from the runner's `toolchain.json`. + + Drift matters: a cross-stack ranking taken at unpinned toolchains is honest about that run but + weaker as a claim about the ecosystems, so the deltas belong in the report rather than only in + a step log. Older runs have no such file — the runners started writing it on 2026-07-25 — and + for those the report states that rather than silently omitting the section. + """ + path = run / "toolchain.json" + if not path.exists(): + return [ + "No `toolchain.json` in this run: the runners began recording pin deltas " + "machine-readably on 2026-07-25. Any drift for this run was transcribed by hand into " + "the report's environment section from the harness artifacts' own metadata.", + "", + ] + doc = json.loads(path.read_text(encoding="utf-8")) + rows = [] + drifted = 0 + for tool, rec in doc.items(): + drift = bool(rec.get("drift")) + drifted += drift + rows.append([ + tool, rec.get("pin", "—"), rec.get("actual", "—"), + "**yes**" if drift else "no", + ]) + out = table(["Toolchain", "Pin", "Actually ran", "Drift"], ["l", "l", "l", "l"], rows) + out += [""] + out += [ + f"{drifted} of {len(rows)} toolchains drifted from their pin in this run. Within-ecosystem " + "comparisons are unaffected — both engines in an ecosystem ran on the identical toolchain — " + "but cross-stack rankings involving a drifted ecosystem are provisional as statements about " + "that ecosystem." + if drifted + else "Every toolchain ran at its pin in this run.", + "", + ] + return out + + +# ---- rendering ------------------------------------------------------------------------------ + + +def render(run: Path) -> str: + # Which era's Razor this run holds decides its display name and whether it carries the + # non-parity caveat. Must run before any engine name is resolved. + configure_run_era(run) + + entries = golden_entries() + golden_bytes = {e["workload"]: e["byteLength"] for e in entries} + suite_of = {e["workload"]: e["suite"] for e in entries} + # Tier 1 (realistic sizing) first, then tier 2 (edge cases), ascending by rendered size in + # each. Every table in this file is emitted in this order; nothing is ordered by hand. + workloads = ordered_workloads([e["workload"] for e in entries], golden_bytes) + # The implied-throughput numerator is the RENDERED size, not the normalized golden — see + # RENDERED_CHARS. Using the golden understates composed-page by 1.56x. + size_bytes = {w: rendered_chars(w, golden_bytes)[0] for w in workloads} + + dotnet, dotnet_alloc = load_dotnet(run) + dotnet_cold = load_dotnet_cold(run) + rust, rust_cold = load_rust(run) + jvm, jvm_alloc = load_jvm(run) + js, js_cold = load_js(run) + python, python_cold, python_alloc = load_python(run) + go, go_cold, go_alloc = load_go(run) + + cells = dotnet + rust + jvm + js + python + go + for c in cells: + if c.workload not in golden_bytes: + raise Fail(f"{c.ecosystem}/{c.engine}: unknown workload {c.workload!r}") + + # The anchor is the CONTROLLED-track Heddle row. The .NET leg now measures both tracks, and an + # unfiltered comprehension would silently let whichever appeared last become the baseline every + # ratio in the report is divided by. + heddle = {c.workload: c.ns for c in dotnet + if c.engine == "Heddle" and c.track == "controlled"} + missing = [w for w in workloads if w not in heddle] + if missing: + raise Fail(f"no Heddle anchor for: {', '.join(missing)}") + + out: list[str] = [ + "", + "", + f"# Consolidated tables — {run.name}", + "", + "## Toolchain pins and drift", + "", + ] + out += toolchain_table(run) + + # ---- 0. the sizing regimes that fix table order everywhere below ---- + out += [ + "## Sizing regimes", + "", + f"The CLR allocates any object of **{LOH_THRESHOLD_BYTES:,} bytes or more on the Large", + "Object Heap**, and .NET strings are UTF-16 — so a rendered page crosses that line at", + f"**{LOH_THRESHOLD_BYTES // UTF16_BYTES_PER_CHAR:,} characters**, and every render past it", + "allocates on the LOH and drives a full, blocking Gen2 collection. None of the other five", + "ecosystems has this cliff: their outputs are UTF-8 or Latin-1 and stay on the normal heap.", + "", + "Workloads on either side of that boundary are therefore not measuring the same thing.", + "Every table below is ordered **tier 1 first, then tier 2, ascending by rendered size**", + "within each — not in normative protocol order, which `manifest.json` and the phase specs", + "retain. The tier is derived from the rendered size, never declared per workload.", + "", + ] + tier_rows = [] + for w in workloads: + chars, measured = rendered_chars(w, golden_bytes) + tier_rows.append([ + w, suite_of[w], f"{golden_bytes[w]:,}", + f"{chars:,}" + ("" if measured else " ‡"), + f"{chars * UTF16_BYTES_PER_CHAR:,}", + f"**{tier_of(w, golden_bytes)}**", + ]) + out += table( + ["Workload", "Suite", "golden B", "rendered chars", "as UTF-16 B", "tier"], + ["l", "l", "r", "r", "r", "r"], tier_rows) + out += [""] + if any(w not in RENDERED_CHARS for w in workloads): + out += [ + "‡ rendered size unmeasured — the golden `byteLength` was substituted. Re-measure and", + "update `RENDERED_CHARS` in `consolidate.py`.", + "", + ] + + # ---- 1. cross-stack ranked, one table per workload ---- + out += [ + "## Cross-stack ranked — wall time per render", + "", + "One ranking per workload. There is no aggregate score, overall winner or", + "cross-workload average anywhere — the consolidated report never carries one,", + "so no single-number verdict can be quoted from these tables.", + "", + ] + for track in ("controlled", "idiomatic"): + out += [f"### {track.capitalize()} track", ""] + emitted_tier = None + for workload in workloads: + rows_src = sorted( + [c for c in cells + if c.track == track and c.workload == workload and not is_heddle_technique(c)], + key=lambda c: c.ns, + ) + if not rows_src: + continue + tier = tier_of(workload, golden_bytes) + if tier != emitted_tier: + emitted_tier = tier + out += [f"#### {TIER_TITLES[tier]}", "", TIER_BLURBS[tier], ""] + anchor = heddle[workload] + rows = [] + for i, c in enumerate(rows_src, start=1): + unchecked = (c.ecosystem, c.engine) in NOT_PARITY_CHECKED + # The golden size does not describe a non-parity-checked payload, so its + # implied throughput would be arithmetic on mismatched operands. + bpn = "n/a †" if unchecked else f"{size_bytes[workload] / c.ns:.1f}" + rows.append([ + str(i), c.engine + (" †" if unchecked else ""), c.ecosystem, + evidence_of(c), c.stat, c.dispersion, fmt_ns(c.ns), + fmt_ratio(c.ns / anchor), bpn, + ]) + out += [ + f"**{workload} — cross-stack ({track}) — {size_caption(workload, golden_bytes)}**", + "", + ] + out += table( + ["#", "Engine", "Ecosystem", "Evidence", "harness statistic", + "harness dispersion", "ns/render", "vs Heddle", "implied B/ns"], + ["r", "l", "l", "l", "r", "r", "r", "r", "r"], + rows, + ) + out += [""] + for c in rows_src: + if (c.ecosystem, c.engine) in NOT_PARITY_CHECKED: + out += [f"† **{c.engine}** ({c.ecosystem}) — " + f"{NOT_PARITY_CHECKED[(c.ecosystem, c.engine)]}. It is ranked " + "here on its measured wall time like every other row; only the " + "throughput figure is withheld.", ""] + out += [ + f"*Source: {run.as_posix()} — each figure is its harness's default " + "central-tendency point estimate, unmodified except for conversion to " + "ns/render.*", + "", + ] + + # ---- 2. per-ecosystem tables, the normative view ---- + by_eco = {eco: [c for c in cells if c.ecosystem == eco] for eco in ECOSYSTEMS} + for track in ("controlled", "idiomatic"): + out += [f"## {track.capitalize()} track — per ecosystem", ""] + for eco in ECOSYSTEMS: + eco_cells = [c for c in by_eco[eco] if c.track == track] + if not eco_cells: + out += [ + f"### {eco}", + "", + f"No {track}-track cells — the .NET leg originally shipped " + "controlled-track-only." if eco == ".NET" else + f"No {track}-track cells in this run.", + "", + ] + continue + rows = [] + for workload in workloads: + anchor = heddle[workload] + if eco != ".NET": + rows.append([ + workload, "Heddle (reference)", fmt_time(anchor), "—", + fmt_ns(anchor), "1.00", + ]) + for c in sorted((c for c in eco_cells if c.workload == workload), + key=lambda c: c.ns): + label = c.engine + if (c.ecosystem, c.engine) in NOT_PARITY_CHECKED: + label += " †" + if is_heddle_technique(c): + label += " ‡" + rows.append([ + workload, label, c.stat, c.dispersion, fmt_ns(c.ns), + fmt_ratio(c.ns / anchor), + ]) + out += [f"### {eco}", ""] + out += table( + ["Workload", "Engine", "harness statistic", "harness dispersion", + "ns/render", "vs Heddle"], + ["l", "l", "r", "r", "r", "r"], + rows, + ) + out += [""] + for (e_eco, e_engine), reason in NOT_PARITY_CHECKED.items(): + if e_eco == eco and any(c.engine == e_engine for c in eco_cells): + out += [f"† **{e_engine}** — {reason}. Excluded from the cross-stack " + "rankings for that reason; its ratio column above is indicative " + "only.", ""] + if any(is_heddle_technique(c) for c in eco_cells): + out += ["‡ **Streaming-sink rows** — the same engine streaming into a " + "caller-owned buffer that is pre-sized in untimed setup and reused " + "across iterations, so the row is engine cost with no output " + "materialisation. Every other row, the Heddle anchor included, " + "materialises a string. The `vs Heddle` ratio therefore compares " + "different work; the rows are excluded from every ranking and exist " + "to show what a caller that can stream avoids paying.", ""] + out += [ + f"*Source: {run.as_posix()} — {EVIDENCE[eco]} evidence. The Heddle row is " + "the .NET anchor measured in this same run on the same machine.*", + "", + ] + + # ---- 3. cold compile / parse, per ecosystem, never cross-compared ---- + out += [ + "## Cold compile / parse — per ecosystem", + "", + "Per-ecosystem only, never cross-compared. Within the .NET table the rows are not", + "comparable with each other either: a `Parse*` row produces an interpretable tree and a", + "`Compile*` row produces executable code, which are different steps of a first use.", + "", + ] + for eco, cold in ((".NET", dotnet_cold), ("Rust", rust_cold), ("JVM", []), ("JS", js_cold), + ("Python", python_cold), ("Go", go_cold)): + out += [f"### {eco}", ""] + if not cold: + out += ["No cold-compile cells in this run.", ""] + continue + rows = [[c.workload, c.engine, c.stat, c.dispersion] + for c in sorted(cold, key=lambda c: (c.workload, c.ns))] + out += table(["Workload", "Engine", "harness statistic", "harness dispersion"], + ["l", "l", "r", "r"], rows) + out += ["", f"*Source: {run.as_posix()}.*", ""] + + # ---- 4. per-ecosystem sidebars, not cross-comparable ---- + out += [ + "## Per-ecosystem sidebars — not cross-comparable", + "", + "Allocation, GC and memory figures are per-ecosystem measurements taken by different", + "tools with different definitions. No table or sentence juxtaposes them across", + "runtimes.", + "", + ] + out += ["### .NET — allocation (BenchmarkDotNet `[MemoryDiagnoser]`)", ""] + out += table(["Workload", "Engine", "Track", "Allocated", "Alloc ratio", "Gen0 / Gen1 / Gen2"], + ["l", "l", "l", "r", "r", "r"], dotnet_alloc) + if any(r[1].endswith(" ‡") for r in dotnet_alloc): + out += [ + "", + "‡ **The two streaming-sink rows measure a different quantity from every other row, " + "and their `Allocated` figures must not be compared with the materialising rows'.** A " + "materialising row's `Allocated` includes the rendered output; the sink rows stream " + "into a caller-owned buffer that is allocated once in untimed setup, pre-sized past " + "the output's high-water mark, and reused across iterations. Their `Allocated` is " + "therefore the engine's per-render bookkeeping — the steady-state GC pressure a " + "pooled streaming consumer (a `PipeWriter`-shaped caller) sees — and NOT the cost of " + "owning the output: the buffer's working set, on the order of the rendered output " + "itself, is real memory the caller holds for the render's duration and simply is not " + "a per-render allocation. Read an `Alloc ratio` of 0.001 as \"streaming retires the " + "per-render allocation\", never as \"the render fits in a few hundred bytes\".", + ] + internal = load_dotnet_internal(run) + if internal: + out += ["", "#### .NET — Heddle-internal suites (not competitor tables)", ""] + out += table(["Suite", "Method", "Mean", "Allocated"], ["l", "l", "r", "r"], internal) + out += ["", "### JVM — allocation (JMH `-prof gc`)", ""] + out += table(["Workload", "Engine", "Track", "gc.alloc.rate.norm", "gc.count"], + ["l", "l", "l", "r", "r"], jvm_alloc) + out += ["", "### Python — memory (`tracemalloc`)", ""] + out += table(["Workload", "Engine", "Track", "allocated (mean)", "retained (mean)", "reps"], + ["l", "l", "l", "r", "r", "r"], python_alloc) + out += ["", "### Go — allocation (`go test -benchmem` via benchstat)", ""] + out += table(["Workload", "Engine", "Track", "B/op", "allocs/op"], + ["l", "l", "l", "r", "r"], go_alloc) + out += [ + "", + "### JS — no memory sidebar", + "", + "The JS leg is **time-only** by design: no memory sidebar exists, so none is", + "published here even though mitata emits a heap estimate.", + "", + ] + if (run / "rust" / "alloc-report.txt").exists(): + out += [ + "### Rust — allocation report", + "", + "The counting-allocator report ships as the raw artifact", + "[rust/alloc-report.txt](rust/alloc-report.txt); this script does not parse it into", + "a table, so no Rust allocation figures appear here.", + "", + ] + else: + out += [ + "### Rust — allocation report absent", + "", + "`alloc-report.txt` was produced by the run (`rust / measure / alloc-report` = OK in", + "`summary.txt`) but the `copy-criterion` step copied only `target/criterion`, so the", + "artifact is not in this directory and no Rust allocation figures are published.", + "", + ] + + # ---- 5. the plausibility register ---- + out += [ + "## Plausibility register", + "", + "`implied B/ns` is the **rendered** output size divided by the wall time — a diagnostic", + "required on every cross-stack table. It is **not** a performance metric.", + "Its purpose is to expose cells where the harness cannot be producing the full output,", + "so a reader does not mistake a measurement artifact for engine speed.", + "", + "The numerator is the rendered size, not the golden `byteLength`. The golden oracle is", + "stored in its **normalized** form — `TwinContent.Normalize` collapses every inter-tag", + "whitespace run before export — so on `composed-page` it is 1.56x smaller than what the", + "engines actually emit (34,847 B stored against 54,401 chars rendered). Dividing by the", + "golden there understated every engine's throughput by that factor and would have let a", + "cell sit above the ceiling unflagged. The other seven workloads agree within 2.4%.", + "", + f"### Cells above the {PLAUSIBILITY_CEILING_B_PER_NS:.0f} B/ns ceiling", + "", + "A cell above this ceiling claims more sustained store bandwidth than one core of this", + "machine has while also executing template logic. The threshold was set from the observed", + "distribution of an earlier run rather than from a model. That run — since withdrawn, and", + "its render figures invalid — had two cells at 105.4 and 91.7 B/ns and then nothing until", + "30.9 B/ns, which was a compiled Rust template whose output is mostly a memcpy of large", + "literal chunks: fast, but physically possible. The ceiling sits in that gap. The two high", + "cells were the V8 rope artifact, since fixed harness-side (benchmarks amendment E4),", + "and the threshold", + "is retained as a standing cross-check rather than as a finding about that run.", + "", + ] + # This run's own distribution, stated rather than asserted: a hardcoded sentence about + # "this run" silently became false the first time the tables were regenerated. + ranked_bpn = sorted((size_bytes[c.workload] / c.ns for c in cells), reverse=True) + if ranked_bpn: + out += [ + f"In *this* run the highest implied throughput is **{ranked_bpn[0]:.1f} B/ns**, and the " + f"top five are " + + ", ".join(f"{v:.1f}" for v in ranked_bpn[:5]) + + f" B/ns against the {PLAUSIBILITY_CEILING_B_PER_NS:.0f} B/ns ceiling.", + "", + ] + flagged = [] + for c in sorted(cells, key=lambda c: -(size_bytes[c.workload] / c.ns)): + bpn = size_bytes[c.workload] / c.ns + if bpn > PLAUSIBILITY_CEILING_B_PER_NS: + flagged.append([c.ecosystem, c.engine, c.track, c.workload, + f"{size_bytes[c.workload]:,}", fmt_time(c.ns), f"{bpn:.1f}"]) + if flagged: + out += table( + ["Ecosystem", "Engine", "Track", "Workload", "rendered B", "wall time", "implied B/ns"], + ["l", "l", "l", "l", "r", "r", "r"], flagged) + else: + out += ["No cell exceeds the ceiling in this run."] + out += [""] + + # Corroborating signal, JS only: mitata reports a per-render heap estimate, so a cell whose + # heap is a small fraction of its output size cannot be materialising that output. + if JS_HEAP: + out += [ + "### JS — heap per render against output size (corroborating signal)", + "", + "mitata reports an estimated heap figure per render, published here as context only.", + "", + "**This column cannot decide materialisation, and is no longer read as if it could.**", + "The figure is a *net* heap delta measured across a batch of thousands of iterations,", + "so anything the collector reclaims inside that batch is invisible to it: a render", + "that allocates its full output and immediately drops it can report a near-zero", + "delta. That is why the same metric yields a ratio above 5 on `large-loop` (where", + "allocation outruns the collector within a batch) and near 0.01 on `composed-page`", + "(where it does not) in one and the same run. Earlier revisions of this register", + "treated a ratio below 0.1 as proof of a non-materialised output; on the artifacts of", + "the run that first exposed the defect that happened to agree with it, but it is not a", + "sound inference and it false-positives on cells that are now provably correct.", + "", + "**The authoritative control is harness-side, not report-side.** Every bench body", + "materialises through `%FlattenString` and each run asserts `MATERIALISATION-CHECK`", + "before writing artifacts, failing the step outright rather than annotating a table", + "(benchmarks amendment E4). The", + "throughput ceiling above is the report-side cross-check on that gate. A low heap", + "ratio here is a prompt to look at those two, not a verdict of its own.", + "", + ] + rows = [] + for (track, engine, workload), heap in sorted( + JS_HEAP.items(), key=lambda kv: (kv[1] / size_bytes[kv[0][2]]) + ): + gb = size_bytes[workload] + ratio = heap / gb + over_ceiling = gb / next( + c.ns for c in cells + if c.ecosystem == "JS" and c.track == track and c.workload == workload + and c.engine == name("JS", engine) + ) > PLAUSIBILITY_CEILING_B_PER_NS + # Deliberately none of these is a materialisation verdict; see the note above. + if over_ceiling: + verdict = "THROUGHPUT ABOVE CEILING — see the section above" + elif ratio < 0.1: + verdict = "net delta ≈ 0 (garbage reclaimed within the batch)" + elif ratio < 1.0: + verdict = "net delta below output size" + else: + verdict = "net delta at or above output size" + rows.append([workload, name("JS", engine), track, f"{gb:,}", + f"{heap:,.0f}", f"{ratio:.2f}", verdict]) + out += table( + ["Workload", "Engine", "Track", "rendered B", "heap/render B", "ratio", "reading"], + ["l", "l", "l", "r", "r", "r", "l"], rows) + out += [""] + + return { + OUTPUT_NAME: "\n".join(out).rstrip() + "\n", + SUMMARY_NAME: render_summary(run, cells, dotnet, heddle, workloads, golden_bytes), + } + + +def render_summary( + run: Path, + cells: list[Cell], + dotnet: list[Cell], + heddle: dict[str, float], + workloads: list[str], + golden_bytes: dict[str, int], +) -> str: + """The headline tables `index.md` embeds, in the same tier order as the full tables. + + These exist so the report's narrative page never hand-transcribes a number: index.md pulls + them in with VitePress's `` directive, and `--check` re-derives them from the + artifacts alongside the consolidated tables. + """ + ctl = [c for c in cells if c.track == "controlled" and not is_heddle_technique(c)] + tiers = {t: [w for w in workloads if tier_of(w, golden_bytes) == t] for t in (1, 2)} + + out: list[str] = [ + ". -->", + "", + ] + + def dotnet_margin_rows(ws: list[str]) -> list[list[str]]: + rows = [] + for w in ws: + field = sorted((c for c in dotnet if c.track == "controlled" and c.workload == w), + key=lambda c: c.ns) + if len(field) < 2: + continue + anchor = heddle[w] + rival = next((c for c in field + if c.engine != "Heddle" and not is_heddle_technique(c)), None) + if rival is None: + continue + ratio = rival.ns / anchor + verdict = (f"**{ratio:.2f}×**" if ratio > 1 + else f"**{ratio:.2f}× — Heddle loses**") + rows.append([w, f"{golden_bytes[w]:,} B", fmt_time(anchor), + f"{rival.engine} — {fmt_time(rival.ns)}", verdict]) + return rows + + def rank_rows(ws: list[str]) -> list[list[str]]: + rows = [] + for w in ws: + field = sorted((c for c in ctl if c.workload == w), key=lambda c: c.ns) + if not field: + continue + rank = next(i for i, c in enumerate(field, 1) + if c.ecosystem == ".NET" and c.engine == "Heddle") + ahead = ", ".join(f"{c.engine} ({c.ecosystem})" for c in field[:rank - 1]) or "—" + rows.append([w, f"{golden_bytes[w]:,} B", f"**#{rank}** of {len(field)}", ahead]) + return rows + + for t in (1, 2): + if not tiers[t]: + continue + out += [f"### {TIER_TITLES[t]} — .NET field", "", TIER_BLURBS[t], ""] + out += table(["Workload", "Golden", "Heddle", "Next .NET engine", "Margin"], + ["l", "r", "r", "l", "r"], dotnet_margin_rows(tiers[t])) + out += ["", f"### {TIER_TITLES[t]} — cross-stack rank", ""] + out += table(["Workload", "Golden", "Heddle rank", "Ahead of it"], + ["l", "r", "r", "l"], rank_rows(tiers[t])) + out += [""] + + out += [ + f"*Source: {run.as_posix()}, controlled track. Tier is derived from rendered output size " + f"against the {LOH_THRESHOLD_BYTES:,}-byte Large Object Heap threshold; see " + "[Sizing regimes](consolidated-tables.md#sizing-regimes).*", + "", + ] + return "\n".join(out).rstrip() + "\n" + + +# ---- entry point ---------------------------------------------------------------------------- + + +def main(argv: list[str]) -> int: + ap = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + ap.add_argument("run", type=Path, help="the run directory, e.g. docs/benchmarks/2026-07-25") + ap.add_argument("--check", action="store_true", + help="re-derive the tables and diff against the committed file") + args = ap.parse_args(argv) + + run = args.run + if not run.is_dir(): + print(f"consolidate: not a directory: {run}", file=sys.stderr) + return 2 + + try: + outputs = render(run) + except Fail as exc: + print(f"consolidate: {exc}", file=sys.stderr) + return 1 + + if args.check: + stale = False + for filename, text in outputs.items(): + target = run / filename + if not target.exists(): + print(f"consolidate --check: {target} does not exist", file=sys.stderr) + stale = True + continue + committed = target.read_text(encoding="utf-8") + if committed != text: + import difflib + diff = difflib.unified_diff( + committed.splitlines(keepends=True), text.splitlines(keepends=True), + fromfile=f"{target} (committed)", tofile="re-derived", n=2) + sys.stderr.writelines(diff) + print(f"consolidate --check: {target} is stale", file=sys.stderr) + stale = True + if stale: + return 1 + print("consolidate --check: " + + ", ".join(str(run / f) for f in outputs) + " match the artifacts") + return 0 + + for filename, text in outputs.items(): + target = run / filename + target.write_text(text, encoding="utf-8", newline="\n") + print(f"consolidate: wrote {target} ({len(text.splitlines())} lines)") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv[1:])) diff --git a/benchmarks/run-all.ps1 b/benchmarks/run-all.ps1 new file mode 100644 index 00000000..5a2205b4 --- /dev/null +++ b/benchmarks/run-all.ps1 @@ -0,0 +1,649 @@ +# run-all.ps1 -- Windows master runner for the cross-stack benchmark program. +# +# One command runs every ecosystem's gates and then its measurement (or smoke) pass +# with each harness's normative parameters -- every committed source/script default already +# IS the protocol shape, so this runner only sequences and logs. +# The Linux counterpart is benchmarks/linux-crosscheck/run-all.sh; this script keeps the +# same phase order (gates first, stop on first red; then dotnet -> rust -> jvm -> js -> +# python -> go) so both sides of the cross-check read the same way. +# +# usage (from the repo root): +# powershell -ExecutionPolicy Bypass -File benchmarks\run-all.ps1 # full measurement +# powershell -ExecutionPolicy Bypass -File benchmarks\run-all.ps1 -Smoke # short functional pass +# ... -Ecosystem rust,go # subset +# ... -OutDir E:\bench-out # artifact/log destination (no spaces in the path) +# ... -Budget baseline # ~30 min/ecosystem instead of the ~10 min default +# ... -JsPasses 24 # more JS repeat passes than the profile default +# +# Windows PowerShell 5.1 compatible: no pipeline chain operators, no ternary, ASCII only. + +[CmdletBinding()] +param( + [switch]$Smoke, + + [ValidateSet('dotnet', 'rust', 'jvm', 'js', 'python', 'go')] + [string[]]$Ecosystem = @('dotnet', 'rust', 'jvm', 'js', 'python', 'go'), + + [string]$OutDir = '', + + # Measurement budget. Every harness's committed source/script default IS 'short', + # so a bare single-harness invocation is the ~10 min shape; 'baseline' layers CLI overrides + # on top -- roughly 3x the capture samples and one extra warmup run -- for ~30 min each. + # Named -Budget, not -Profile: PowerShell already has an automatic variable of that + # name (the profile script path), and a parameter would shadow it inside this script. + [ValidateSet('short', 'baseline')] + [string]$Budget = 'short', + + # JS repeat passes per render track, aggregated by bench/aggregate.mjs into the published + # artifact plus the stability verdict. 0 means "take the profile default" (18 short / 54 + # baseline); 5 is the verdict floor and aggregate.mjs refuses fewer. + [ValidateRange(0, 200)] + [int]$JsPasses = 0 +) + +$ErrorActionPreference = 'Continue' + +# --- Measurement budget profiles -------------------------------------------------------------- +# +# Nothing here changes WHAT is measured, only how many times. The committed source/script +# defaults are the 'short' shape; 'baseline' layers CLI overrides for roughly 3x the capture +# samples plus one extra warmup run. +# +# The budget unit is ONE ENGINE, not one ecosystem. An engine +# is 16 cells -- 8 workloads x 2 fairness tracks -- so a leg's budget is 16 x (engines) cells' +# worth of measurement: ~10 min per engine at `short`, ~30 min at `baseline`. Five legs carry two +# engines, .NET carries six, so the .NET leg is about three times the others by construction +# rather than by accident. Every leg's committed source/script default IS its `short` shape. +# +# .NET spends its increment on LAUNCHES, and only on launches. It is overhead-bound (one process +# per benchmark case, plus JIT and MemoryDiagnoser), so wall clock is very nearly linear in +# LaunchCount -- which makes the knob predictable -- while raising the iteration counts instead +# runs through BenchmarkDotNet's pilot stage and does not. More to the point, a single launch +# never samples the cross-process term AT ALL: one process, one JIT, one heap layout. That is the +# same gap JMH closes with plural forks and JS with repeat passes, and the .NET leg was the one +# that had never bought it. The launches multiply the harness job's five-iteration floor: +# 10 x 5 = 50 samples per cell here, against short's 3 x 5 = 15. +if ($Budget -eq 'baseline') { + $dotnetProfileArgs = ' --launchCount 10' + $rustProfileArgs = ' --warm-up-time 10 --measurement-time 84' + $jmhProfileArgs = ' -f 5 -wi 2 -i 17' + $pyValuesArgs = ' --values 20 --warmups 2' + $pyColdArgs = '' # pyperf default 20 processes + $goProfileArgs = ' -Count 84' + $profileJsPasses = 114 +} +else { + $dotnetProfileArgs = '' # harness default job: LaunchCount 3 / W3 / I5 (five-sample floor) + $rustProfileArgs = '' # source: warm-up 5 s, measurement 26 s + $jmhProfileArgs = '' # annotations: Fork 5, W 1x2s, M 5x1s + $pyValuesArgs = ' --values 6 --warmups 1' + $pyColdArgs = ' --processes 7' + $goProfileArgs = '' # script default -Count 28 + $profileJsPasses = 38 +} +if ($JsPasses -eq 0) { $JsPasses = $profileJsPasses } +if ($JsPasses -lt 5) { + Write-Host 'ERROR: -JsPasses must be at least 5 (the stability-verdict floor).' + exit 1 +} + +# --- Layout --------------------------------------------------------------------------------- +$BenchRoot = Split-Path -Parent $MyInvocation.MyCommand.Path +$RepoRoot = Split-Path -Parent $BenchRoot +if ($OutDir -eq '') { + $OutDir = Join-Path $BenchRoot ('out\windows-run-' + (Get-Date -Format 'yyyyMMdd-HHmmss')) +} +if (-not [System.IO.Path]::IsPathRooted($OutDir)) { + $OutDir = Join-Path (Get-Location).Path $OutDir +} +if ($OutDir -match ' ') { + Write-Host 'ERROR: -OutDir must not contain spaces (paths are passed through cmd.exe unquoted).' + exit 1 +} +$LogDir = Join-Path $OutDir 'logs' +New-Item -ItemType Directory -Force -Path $OutDir | Out-Null +New-Item -ItemType Directory -Force -Path $LogDir | Out-Null + +# Fixed program order (anchor-first, then the program's priority order -- same as Linux). +$AllOrder = @('dotnet', 'rust', 'jvm', 'js', 'python', 'go') +$Selected = @() +foreach ($e in $AllOrder) { + if ($Ecosystem -contains $e) { $Selected += $e } +} + +# The eight protocol suites, named after the workloads they measure. Each is one `bench-crossstack --filter` step, so a suite gets +# its own log, its own exit code and its own place to resume from. +$DotnetSuites = @( + 'ComposedPageBenchmarks', + 'TrivialSubstitutionBenchmarks', + 'LargeLoopBenchmarks', + 'MixedPageBenchmarks', + 'ConditionalHeavyBenchmarks', + 'FragmentHeavyBenchmarks', + 'FortunesEncodedBenchmarks', + 'EncodedLoopBenchmarks' +) + +$DotnetDir = Join-Path $BenchRoot 'dotnet' +$RustDir = Join-Path $BenchRoot 'rust' +$JvmDir = Join-Path $BenchRoot 'jvm' +$JsDir = Join-Path $BenchRoot 'js' +$PyDir = Join-Path $BenchRoot 'python' +$GoDir = Join-Path $BenchRoot 'go' +$VenvPy = Join-Path $PyDir '.venv\Scripts\python.exe' + +# --- Step machinery ------------------------------------------------------------------------- +$script:Results = New-Object System.Collections.ArrayList +$script:Failed = $false + +function Invoke-Step { + param( + [string]$Eco, + [string]$Phase, # gate | measure | smoke | copy + [string]$Name, + [string]$WorkDir, + [string]$Command, # a cmd.exe command line; stderr is merged inside cmd + [switch]$NonFatal + ) + $logName = (($Eco + '-' + $Name) -replace '[^A-Za-z0-9\.\-_]', '_') + '.log' + $logPath = Join-Path $LogDir $logName + Write-Host '' + Write-Host ('== [' + $Eco + '/' + $Phase + '] ' + $Name) -ForegroundColor Cyan + Write-Host (' dir: ' + $WorkDir) + Write-Host (' cmd: ' + $Command) + Write-Host (' log: ' + $logPath) + + $sw = [System.Diagnostics.Stopwatch]::StartNew() + $code = 1 + Push-Location $WorkDir + $writer = New-Object System.IO.StreamWriter($logPath, $false, (New-Object System.Text.UTF8Encoding($false))) + try { + $writer.WriteLine('# step: ' + $Eco + '/' + $Name) + $writer.WriteLine('# dir: ' + $WorkDir) + $writer.WriteLine('# cmd: ' + $Command) + $writer.WriteLine('# date: ' + (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')) + $writer.WriteLine('') + # cmd /c merges stderr before PowerShell sees it (avoids PS 5.1 NativeCommandError + # wrapping); each line is teed to the console and the step log. + cmd /c ($Command + ' 2>&1') | ForEach-Object { + $line = [string]$_ + $writer.WriteLine($line) + Write-Host $line + } + $code = $LASTEXITCODE + $writer.WriteLine('') + $writer.WriteLine('# exit: ' + $code) + } + catch { + $msg = ($_ | Out-String) + $writer.WriteLine('# launcher exception: ' + $msg) + Write-Host ('launcher exception: ' + $msg) + $code = 1 + } + finally { + $writer.Close() + Pop-Location + } + $sw.Stop() + + $status = 'OK' + if ($code -ne 0) { + if ($NonFatal) { $status = 'WARN' } else { $status = 'FAIL'; $script:Failed = $true } + } + [void]$script:Results.Add([pscustomobject]@{ + Ecosystem = $Eco + Phase = $Phase + Step = $Name + ExitCode = $code + Seconds = [math]::Round($sw.Elapsed.TotalSeconds, 1) + Status = $status + }) + if ($status -eq 'FAIL') { + Write-Host ('== FAIL [' + $Eco + '/' + $Name + '] exit code ' + $code) -ForegroundColor Red + } + elseif ($status -eq 'WARN') { + Write-Host ('== WARN (non-fatal) [' + $Eco + '/' + $Name + '] exit code ' + $code) -ForegroundColor Yellow + } + else { + Write-Host ('== OK [' + $Eco + '/' + $Name + '] ' + [math]::Round($sw.Elapsed.TotalSeconds, 1) + ' s') -ForegroundColor Green + } + return $code +} + +function Copy-Artifacts { + param([string]$Eco, [string]$Name, [string]$Source, [string]$Dest) + if (-not (Test-Path $Source)) { + Write-Host (' (no artifacts at ' + $Source + ' -- skipping copy)') + return + } + try { + New-Item -ItemType Directory -Force -Path $Dest | Out-Null + Copy-Item -Recurse -Force -Path (Join-Path $Source '*') -Destination $Dest + Write-Host (' artifacts: ' + $Source + ' -> ' + $Dest) + [void]$script:Results.Add([pscustomobject]@{ + Ecosystem = $Eco; Phase = 'copy'; Step = $Name; ExitCode = 0; Seconds = 0; Status = 'OK' + }) + } + catch { + Write-Host (' WARN: artifact copy failed: ' + $_) -ForegroundColor Yellow + [void]$script:Results.Add([pscustomobject]@{ + Ecosystem = $Eco; Phase = 'copy'; Step = $Name; ExitCode = 1; Seconds = 0; Status = 'WARN' + }) + } +} + +function Get-ToolVersion { + param([string]$CommandLine) + $out = cmd /c ($CommandLine + ' 2>&1') + if ($LASTEXITCODE -ne 0 -and (-not $out)) { return 'NOT FOUND' } + if ($null -eq $out) { return 'NOT FOUND' } + return (($out | Select-Object -First 1) -join ' ').Trim() +} + +# --- Preamble: toolchain versions, pin deltas (warn, never fail) ---------------------------- +$PreambleLog = Join-Path $LogDir 'preamble.log' +$Preamble = New-Object System.Collections.ArrayList +function Note { + param([string]$Text, [string]$Color = 'Gray') + Write-Host $Text -ForegroundColor $Color + [void]$Preamble.Add($Text) +} + +$mode = 'MEASUREMENT (spec protocol shapes)' +if ($Smoke) { $mode = 'SMOKE (short functional flags -- results carry NO measurement validity)' } + +Note '==============================================================================' +Note ' Heddle cross-stack benchmarks -- Windows master runner' +Note (' date: ' + (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')) +Note (' mode: ' + $mode) +Note (' budget: ' + $Budget + ' (measurement budget)') +Note (' ecosystems: ' + ($Selected -join ', ')) +Note (' out dir: ' + $OutDir) +Note '==============================================================================' +Note '' +Note '-- Toolchain versions (pins in parentheses; deltas WARN, never fail) --' + +$vDotnet = Get-ToolVersion 'dotnet --version' +Note (' dotnet SDK : ' + $vDotnet + ' (protocol records the exact SDK; 10.0.302 was the observed line)') + +$vCargo = Get-ToolVersion 'cargo --version' +$vRustc = Get-ToolVersion 'rustc --version' +Note (' cargo : ' + $vCargo) +Note (' rustc : ' + $vRustc + ' (pin: 1.97.1)') +if ($vRustc -notmatch '1\.97\.1') { Note ' WARN: rustc differs from the pinned 1.97.1 (record as a version delta).' 'Yellow' } + +$vJava = Get-ToolVersion 'java -version' +Note (' java : ' + $vJava + ' (pin: Temurin 25)') +$JdkMajor = 0 +if ($vJava -match 'version "(\d+)') { $JdkMajor = [int]$Matches[1] } +if ($JdkMajor -ne 25) { Note (' WARN: installed JDK major is ' + $JdkMajor + ', pin is Temurin 25 (record as a version delta).') 'Yellow' } +$vMvn = Get-ToolVersion 'mvn --version' +Note (' maven : ' + $vMvn + ' (harness builds use its own mvnw.cmd wrapper)') + +$vNode = Get-ToolVersion 'node --version' +$vNpm = Get-ToolVersion 'npm --version' +Note (' node : ' + $vNode + ' (pin: v24.x)') +Note (' npm : ' + $vNpm) +$NodeIsPinned = ($vNode.Trim() -like 'v24.*') +if (-not $NodeIsPinned) { Note ' WARN: node differs from the pinned major v24.x (npm ci will run with --engine-strict=false; record as a version delta).' 'Yellow' } + +$vPy = 'NOT FOUND' +if (Test-Path $VenvPy) { $vPy = Get-ToolVersion ($VenvPy + ' --version') } +else { $vPy = Get-ToolVersion 'python --version' } +Note (' python : ' + $vPy + ' (pin: CPython 3.14.x; harness venv at benchmarks\python\.venv)') +if ($vPy -notmatch '3\.14\.') { Note ' WARN: python differs from the pinned minor CPython 3.14.x (record as a version delta).' 'Yellow' } + +$vGo = Get-ToolVersion 'go version' +Note (' go : ' + $vGo + ' (pin: go1.26.x; run-benchmarks.ps1 hard-asserts go1.26.5)') +if ($vGo -notmatch 'go1\.26\.') { Note ' WARN: go differs from the pinned 1.26.x line (record as a version delta).' 'Yellow' } +Push-Location $GoDir +$vTempl = Get-ToolVersion 'go tool templ version' +Pop-Location +Note (' templ : ' + $vTempl + ' (pin: v0.3.1020, via go tool)') + +# --- toolchain.json: the pin deltas, machine-readable ----------------------------------------- +# The notes above are for a human reading the step log. A published report also needs the deltas +# in its environment block, and reconstructing them by hand from artifact metadata after the fact +# is error-prone -- an earlier report had to do exactly that. benchmarks/report/consolidate.py +# reads this file and generates the pin-drift table from it. The posture is unchanged: drift is +# recorded, never fatal. +$toolchain = [ordered]@{ + '.NET SDK' = @{ pin = '(protocol records the observed line)'; actual = $vDotnet; drift = $false } + 'Rust' = @{ pin = '1.97.1'; actual = $vRustc; drift = ($vRustc -notmatch '1\.97\.1') } + 'JDK' = @{ pin = 'Temurin 25'; actual = $vJava; drift = ($JdkMajor -ne 25) } + 'Node.js' = @{ pin = 'v24.x'; actual = $vNode; drift = (-not $NodeIsPinned) } + 'CPython' = @{ pin = '3.14.x'; actual = $vPy; drift = ($vPy -notmatch '3\.14\.') } + 'Go' = @{ pin = 'go1.26.x'; actual = $vGo; drift = ($vGo -notmatch 'go1\.26\.') } + 'templ' = @{ pin = 'v0.3.1020'; actual = $vTempl; drift = ($vTempl -notmatch 'v0\.3\.1020') } +} +$toolchainPath = Join-Path $OutDir 'toolchain.json' +# -Depth 3 keeps the nested pin/actual/drift objects; the default (2) would stringify them. +# Written through .NET rather than Set-Content: this script runs under Windows PowerShell 5.1, +# whose -Encoding has no utf8NoBOM member (that is 7.0+), and whose plain `utf8` emits a BOM +# that consolidate.py's json.loads(..., encoding='utf-8') would choke on. The 5.1 failure was +# also silent in the worst way -- Set-Content threw on the parameter bind, the pipeline kept +# going, and the next line still announced the file as written. +[System.IO.File]::WriteAllText( + $toolchainPath, + ($toolchain | ConvertTo-Json -Depth 3), + (New-Object System.Text.UTF8Encoding($false))) +if (Test-Path $toolchainPath) { + Note (' toolchain.json written to ' + $toolchainPath + ' (pin deltas, machine-readable)') +} +else { + Note (' WARN: toolchain.json could NOT be written to ' + $toolchainPath + ' -- the report''s pin-drift table will be missing.') 'Yellow' +} + +# Goldens-rewrite hazard: a stray dotnet-hosted watcher (Heddle demo/docs tooling) touching +# the working tree during export/verify would dirty the corpus manifest. Best-effort check: +# list running dotnet PIDs so the operator can eyeball them. +$dotnetProcs = @(Get-Process -Name 'dotnet' -ErrorAction SilentlyContinue) +if ($dotnetProcs.Count -gt 0) { + Note '' + Note (' WARN: ' + $dotnetProcs.Count + ' dotnet process(es) are running (PIDs: ' + (($dotnetProcs | ForEach-Object { $_.Id }) -join ', ') + ').') 'Yellow' + Note ' If any is a Heddle file-watcher (demo/docs tooling), stop it before measuring:' 'Yellow' + Note ' a watcher rewriting goldens mid-run is a corpus-freshness hazard (verify-corpus would go red).' 'Yellow' +} +Note '' +$Preamble | Out-File -Encoding utf8 $PreambleLog + +# --- Phase 1: GATES (all selected ecosystems, stop on first red) ---------------------------- +Write-Host '################################################################################' +Write-Host '## PHASE 1: GATES (stop on first red -- a red gate must be triaged before' +Write-Host '## anything later runs; same rule as linux-crosscheck/run-all.sh)' +Write-Host '################################################################################' + +$MvnRelease = '' +if ($JdkMajor -gt 0 -and $JdkMajor -lt 25) { + $MvnRelease = ' -Dmaven.compiler.release=23' + Write-Host ('NOTE: JDK ' + $JdkMajor + ' < 25 -- passing' + $MvnRelease + ' to the JVM build (pom pins release=25).') -ForegroundColor Yellow +} + +$NpmCiSuffix = '' +if (-not $NodeIsPinned) { $NpmCiSuffix = ' --engine-strict=false' } + +foreach ($eco in $Selected) { + switch ($eco) { + 'dotnet' { + # The full cell registry: byte gate on the controlled track, functional verifier on the + # idiomatic one, security floor on the encoded workloads, plus the materialisation + # trailer and the precompiled-coverage statement. + [void](Invoke-Step -Eco 'dotnet' -Phase 'gate' -Name 'gate' -WorkDir $DotnetDir ` + -Command 'dotnet run -c Release -- gate') + if ($script:Failed) { break } + # The gate itself, gated: harness self-checks including the six-technique differential. + [void](Invoke-Step -Eco 'dotnet' -Phase 'gate' -Name 'gate-selftest' -WorkDir $DotnetDir ` + -Command 'dotnet run -c Release -- selftest') + if ($script:Failed) { break } + [void](Invoke-Step -Eco 'dotnet' -Phase 'gate' -Name 'gate-verify-corpus' -WorkDir $DotnetDir ` + -Command 'dotnet run -c Release -- verify-corpus') + } + 'rust' { + [void](Invoke-Step -Eco 'rust' -Phase 'gate' -Name 'gate' -WorkDir $RustDir ` + -Command 'cargo run --release --bin gate') + } + 'jvm' { + [void](Invoke-Step -Eco 'jvm' -Phase 'gate' -Name 'gate-build-verify' -WorkDir $JvmDir ` + -Command ('.\mvnw.cmd -q clean verify' + $MvnRelease)) + } + 'js' { + [void](Invoke-Step -Eco 'js' -Phase 'gate' -Name 'npm-ci' -WorkDir $JsDir ` + -Command ('npm ci' + $NpmCiSuffix)) + if ($script:Failed) { break } + [void](Invoke-Step -Eco 'js' -Phase 'gate' -Name 'selftest' -WorkDir $JsDir ` + -Command 'npm run selftest') + if ($script:Failed) { break } + [void](Invoke-Step -Eco 'js' -Phase 'gate' -Name 'gate' -WorkDir $JsDir ` + -Command 'npm run gate') + } + 'python' { + if (-not (Test-Path $VenvPy)) { + [void](Invoke-Step -Eco 'python' -Phase 'gate' -Name 'venv-create' -WorkDir $PyDir ` + -Command 'python -m venv .venv') + if ($script:Failed) { break } + } + [void](Invoke-Step -Eco 'python' -Phase 'gate' -Name 'pip-install' -WorkDir $PyDir ` + -Command ($VenvPy + ' -m pip install -r requirements.txt')) + if ($script:Failed) { break } + [void](Invoke-Step -Eco 'python' -Phase 'gate' -Name 'selftest' -WorkDir $PyDir ` + -Command ($VenvPy + ' -m runner.selftest')) + if ($script:Failed) { break } + [void](Invoke-Step -Eco 'python' -Phase 'gate' -Name 'gate-all' -WorkDir $PyDir ` + -Command ($VenvPy + ' -m runner.gate_all')) + } + 'go' { + [void](Invoke-Step -Eco 'go' -Phase 'gate' -Name 'gate' -WorkDir $GoDir ` + -Command 'go test ./suites') + } + } + if ($script:Failed) { break } +} + +function Write-Summary { + Write-Host '' + Write-Host '################################################################################' + Write-Host '## SUMMARY' + Write-Host '################################################################################' + $table = $script:Results | Format-Table -AutoSize Ecosystem, Phase, Step, ExitCode, Seconds, Status | Out-String + Write-Host $table + $summaryPath = Join-Path $OutDir 'summary.txt' + $header = @( + ('mode: ' + $mode), + ('budget: ' + $Budget + ' (measurement budget)'), + ('ecosystems: ' + ($Selected -join ', ')), + ('finished: ' + (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')), + '' + ) + ($header + $table) | Out-File -Encoding utf8 $summaryPath + Write-Host ('summary: ' + $summaryPath) + Write-Host ('logs: ' + $LogDir) +} + +if ($script:Failed) { + Write-Host '' + Write-Host 'A GATE IS RED. Stopping before any measurement (triage the gate first).' -ForegroundColor Red + Write-Summary + exit 1 +} + +Write-Host '' +Write-Host 'All selected gates are green.' -ForegroundColor Green + +# --- Phase 2: MEASUREMENT (or smoke) -------------------------------------------------------- +Write-Host '' +Write-Host '################################################################################' -ForegroundColor Yellow +Write-Host '## MACHINE-STATE RULES (read before trusting any number)' -ForegroundColor Yellow +Write-Host '## * Protocol machine only: the AMD Ryzen 9 9950X / Windows 11 box of the' -ForegroundColor Yellow +Write-Host '## published runs. Numbers from any other machine are not comparable' -ForegroundColor Yellow +Write-Host '## and must not be merged into reports.' -ForegroundColor Yellow +Write-Host '## * Quiet machine: close foreground applications, browsers, editors with' -ForegroundColor Yellow +Write-Host '## background indexing, and any other builds/watchers for the duration.' -ForegroundColor Yellow +Write-Host '## * Power: AC power, High Performance power plan; no sleep/hibernate timers' -ForegroundColor Yellow +Write-Host '## that could fire mid-run.' -ForegroundColor Yellow +Write-Host '## * Per-harness stability settings (High priority classes, --affinity=4,' -ForegroundColor Yellow +Write-Host '## elevated shell for pyperf) are applied by the steps below and must be' -ForegroundColor Yellow +Write-Host '## recorded in the run report''s environment block.' -ForegroundColor Yellow +if ($Smoke) { + Write-Host '## SMOKE MODE: the above is informational -- smoke results carry no validity.' -ForegroundColor Yellow +} +Write-Host '################################################################################' -ForegroundColor Yellow +Write-Host '' +Write-Host '################################################################################' +if ($Smoke) { Write-Host '## PHASE 2: SMOKE (functional pass; failures are recorded, run continues)' } +else { Write-Host '## PHASE 2: MEASUREMENT (failures are recorded, run continues)' } +Write-Host '################################################################################' + +$measurePhase = 'measure' +if ($Smoke) { $measurePhase = 'smoke' } + +foreach ($eco in $Selected) { + switch ($eco) { + 'dotnet' { + # Protocol shape: Release, net10.0, the harness's own ShortRun default, + # MemoryDiagnoser via suite attributes; one --filter run per protocol suite. Each suite + # measures BOTH fairness tracks (the Track parameter), which is why the .NET measure + # phase is about twice the length it was when the leg was controlled-track only. + foreach ($suite in $DotnetSuites) { + $bdnCmd = 'dotnet run -c Release -- bench-crossstack --filter *' + $suite + '*' + if ($Smoke) { $bdnCmd = $bdnCmd + ' --job Dry' } + elseif ($dotnetProfileArgs -ne '') { $bdnCmd = $bdnCmd + $dotnetProfileArgs } + [void](Invoke-Step -Eco 'dotnet' -Phase $measurePhase -Name ('suite-' + $suite) -WorkDir $DotnetDir -Command $bdnCmd) + } + # The three sidebars. None of them contributes a cross-stack row -- techniques is Heddle + # against itself, cold measures a different step of the same engines, and internal pins + # engine properties no other ecosystem has an analogue for -- so they run last, where a + # failure in them cannot mask a missing comparison row. + foreach ($sidebar in @('bench-techniques', 'bench-cold', 'bench-internal')) { + $cmd = 'dotnet run -c Release -- ' + $sidebar + if ($Smoke) { $cmd = $cmd + ' --job Dry' } + elseif ($dotnetProfileArgs -ne '') { $cmd = $cmd + $dotnetProfileArgs } + [void](Invoke-Step -Eco 'dotnet' -Phase $measurePhase -Name $sidebar -WorkDir $DotnetDir -Command $cmd) + } + + Copy-Artifacts -Eco 'dotnet' -Name 'copy-bdn-artifacts' ` + -Source (Join-Path $DotnetDir 'BenchmarkDotNet.Artifacts') -Dest (Join-Path $OutDir 'dotnet') + } + 'rust' { + # Mirrored from linux-crosscheck/run-rust.sh: + # the lib target does not set bench = false, so the three Criterion bench + # targets are selected explicitly; sources are untouched. + $benchTargets = '--bench controlled --bench idiomatic --bench cold' + if ($Smoke) { + [void](Invoke-Step -Eco 'rust' -Phase $measurePhase -Name 'criterion-test-pass' -WorkDir $RustDir ` + -Command ('cargo bench ' + $benchTargets + ' -- --test')) + } + else { + [void](Invoke-Step -Eco 'rust' -Phase $measurePhase -Name 'criterion-bench' -WorkDir $RustDir ` + -Command ('cargo bench ' + $benchTargets + ' -- --noplot' + $rustProfileArgs)) + # --out lands the allocation report straight in the run dir: Copy-Artifacts only handles + # directories, and before this the report existed nowhere but the step log. + [void](New-Item -ItemType Directory -Force -Path (Join-Path $OutDir 'rust')) + [void](Invoke-Step -Eco 'rust' -Phase $measurePhase -Name 'alloc-report' -WorkDir $RustDir ` + -Command ('cargo run --release --features alloc-count --bin alloc_report -- --out "' + (Join-Path $OutDir 'rust\alloc-report.txt') + '"')) + # summarize reads heddle-reference.toml; while the Windows reference + # rows are pending it fails loudly by design -- captured, non-fatal. + [void](Invoke-Step -Eco 'rust' -Phase $measurePhase -Name 'summarize' -WorkDir $RustDir -NonFatal ` + -Command 'cargo run --release --bin summarize') + } + Copy-Artifacts -Eco 'rust' -Name 'copy-criterion' ` + -Source (Join-Path $RustDir 'target\criterion') -Dest (Join-Path $OutDir 'rust\criterion') + } + 'jvm' { + $jvmOut = Join-Path $OutDir 'jvm' + New-Item -ItemType Directory -Force -Path $jvmOut | Out-Null + $rff = Join-Path $jvmOut 'jmh-result.json' + if ($Smoke) { + [void](Invoke-Step -Eco 'jvm' -Phase $measurePhase -Name 'jmh-smoke' -WorkDir $JvmDir ` + -Command ('java -jar target\benchmarks.jar -f 1 -wi 1 -i 1 -w 1s -r 1s -foe true -prof gc -rf json -rff ' + $rff)) + } + else { + Write-Host 'NOTE: JMH regime = annotations (Fork 3, 1x2s warmup, 3x1s measure)' -ForegroundColor Yellow + Write-Host (" + budget '" + $Budget + "' overrides:" + $jmhProfileArgs) -ForegroundColor Yellow + Write-Host ' Expect ~9 min (short) / ~23 min (baseline); it was 4.5 h before the uniform budget.' -ForegroundColor Yellow + [void](Invoke-Step -Eco 'jvm' -Phase $measurePhase -Name 'jmh-full' -WorkDir $JvmDir ` + -Command ('java -jar target\benchmarks.jar' + $jmhProfileArgs + ' -prof gc -rf json -rff ' + $rff)) + } + } + 'js' { + # The committed launcher run.ps1 carries the normative shapes (High priority class, + # node --expose-gc --allow-natives-syntax, stdout captured to artifacts/). + # + # The two render tracks run $JsPasses times each and are aggregated. + # mitata exposes no per-cell time budget -- B.run() builds its own options object, so + # min_cpu_time (642 ms) is unreachable from the public API -- which left this + # ecosystem measuring 32 cells in 31 s against 15-31 s/cell everywhere else. Its + # share of the uniform budget is spent on independent processes instead: run.ps1 + # -Repeat N, then bench/aggregate.mjs medians the per-pass avg into + # artifacts/.json and emits the stability verdict. The stability procedure IS the + # measurement now, rather than a separate gate someone has to remember -- which is + # how the withdrawn 2026-07-22 run shipped JS numbers with no RSD verdict at all. + # + # cold-compile stays a single pass: a compile-dominated sidebar, not a protocol + # cell, so repeating it buys a verdict for numbers no ranking consumes. + $runPs1 = 'powershell -NoProfile -ExecutionPolicy Bypass -File run.ps1' + foreach ($jsTrack in @('controlled', 'idiomatic')) { + if ($Smoke) { + [void](Invoke-Step -Eco 'js' -Phase $measurePhase -Name ('bench-' + $jsTrack) -WorkDir $JsDir ` + -Command ($runPs1 + ' bench/' + $jsTrack + '.mjs')) + } + else { + [void](Invoke-Step -Eco 'js' -Phase $measurePhase -Name ('bench-' + $jsTrack + '-x' + $JsPasses) -WorkDir $JsDir ` + -Command ($runPs1 + ' bench/' + $jsTrack + '.mjs -Repeat ' + $JsPasses)) + } + } + [void](Invoke-Step -Eco 'js' -Phase $measurePhase -Name 'bench-cold-compile' -WorkDir $JsDir ` + -Command ($runPs1 + ' bench/cold-compile.mjs')) + Copy-Artifacts -Eco 'js' -Name 'copy-artifacts' ` + -Source (Join-Path $JsDir 'artifacts') -Dest (Join-Path $OutDir 'js') + } + 'python' { + # Five pyperf Runner scripts, library defaults, --affinity=4, JSON + # outputs, from an ELEVATED shell (psutil REALTIME_PRIORITY_CLASS path). + $isElevated = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) + if (-not $isElevated) { + Write-Host 'WARN: shell is NOT elevated -- pyperf''s REALTIME_PRIORITY_CLASS elevation' -ForegroundColor Yellow + Write-Host ' will be silently skipped (AccessDenied swallowed). A measurement run' -ForegroundColor Yellow + Write-Host ' must use an elevated PowerShell.' -ForegroundColor Yellow + } + $pyOut = Join-Path $OutDir 'python' + New-Item -ItemType Directory -Force -Path $pyOut | Out-Null + $pySmokeArgs = '' + if ($Smoke) { $pySmokeArgs = ' --debug-single-value' } + # The four render scripts keep pyperf's default 20x3x1 -- at ~9 min for + # the 32 protocol cells they already sit inside the uniform per-engine budget. The + # cold-compile sidebar does not: at defaults it cost 288 s, a third of the + # ecosystem's time for a non-comparable sidebar, so it runs with 7 processes. + $pyScripts = @('bench_jinja2_controlled', 'bench_jinja2_idiomatic', 'bench_mako_controlled', 'bench_mako_idiomatic', 'bench_cold_compile') + foreach ($s in $pyScripts) { + $pyShapeArgs = '' + if ($s -eq 'bench_cold_compile') { $pyShapeArgs = $pyColdArgs } + else { $pyShapeArgs = $pyValuesArgs } + [void](Invoke-Step -Eco 'python' -Phase $measurePhase -Name $s -WorkDir $PyDir ` + -Command ($VenvPy + ' ' + $s + '.py --affinity=4' + $pyShapeArgs + $pySmokeArgs + ' -o ' + (Join-Path $pyOut ($s + '.json')))) + } + # Memory pass -- tracemalloc, separate from timing. + $memArgs = '' + if ($Smoke) { $memArgs = ' --reps 5' } + [void](Invoke-Step -Eco 'python' -Phase $measurePhase -Name 'mem-tracemalloc' -WorkDir $PyDir ` + -Command ($VenvPy + ' mem_tracemalloc.py' + $memArgs + ' -o ' + (Join-Path $pyOut 'memory.json'))) + } + 'go' { + # Go reproduce path: the committed run-benchmarks.ps1 (version asserts, + # templ freshness, vet, gates, prebuild, High-priority timed runs, benchstat). + $goCmd = 'powershell -NoProfile -ExecutionPolicy Bypass -File run-benchmarks.ps1' + if ($Smoke) { $goCmd = $goCmd + ' -Count 1 -BenchTime 100ms' } + elseif ($goProfileArgs -ne '') { $goCmd = $goCmd + $goProfileArgs } + [void](Invoke-Step -Eco 'go' -Phase $measurePhase -Name 'run-benchmarks' -WorkDir $GoDir -Command $goCmd) + Copy-Artifacts -Eco 'go' -Name 'copy-results' ` + -Source (Join-Path $GoDir 'results') -Dest (Join-Path $OutDir 'go') + } + } +} + +Write-Summary + +# --- consolidated tables ---------------------------------------------------------------------- +# Publishing used to mean copying artifacts into docs/benchmarks// and then running +# consolidate.py by hand. That hand step is exactly where table ORDER and transcribed figures drift +# from the artifacts, so the runner does it here: the out dir gets its own consolidated-tables.md +# and summary-tables.md, generated in tier order, before anyone looks at a number. Publishing is +# then a copy -- no regeneration, no hand-ordered tables, no transcription. +# +# Non-fatal by design: a full sweep is expensive and a table-generation failure must not discard +# it. The step is recorded like any other, so `RESULT: OK` still means every measurement is green +# and a WARN row here says the tables need attention, not the run. +if (-not $Smoke) { + # Stdlib-only and CPython >= 3.12, so the interpreter on PATH is enough -- the harness venv + # under benchmarks/python is pyperf's, and consolidate.py must not depend on it. + $consolidateCmd = 'python benchmarks\report\consolidate.py "' + $OutDir + '"' + [void](Invoke-Step -Eco 'report' -Phase $measurePhase -Name 'consolidate' -WorkDir $RepoRoot ` + -NonFatal -Command $consolidateCmd) + Write-Summary +} + +if ($script:Failed) { + Write-Host 'RESULT: FAILED (one or more steps exited nonzero -- see summary above).' -ForegroundColor Red + exit 1 +} +Write-Host 'RESULT: OK (all steps green; WARN rows, if any, are recorded non-fatal steps).' -ForegroundColor Green +exit 0 diff --git a/benchmarks/run-all.sh b/benchmarks/run-all.sh new file mode 100755 index 00000000..7b9efaba --- /dev/null +++ b/benchmarks/run-all.sh @@ -0,0 +1,810 @@ +#!/usr/bin/env bash +# run-all.sh -- Linux master runner for the cross-stack benchmark program (bare metal). +# +# The twin of run-all.ps1: one command runs every ecosystem's gates and then its measurement +# (or smoke) pass with each harness's normative parameters -- every committed source/script +# default already IS the protocol shape, so this runner only sequences and logs. +# Same phase order as run-all.ps1: gates first, stop on the first red; then +# dotnet -> rust -> jvm -> js -> python -> go. +# +# This is NOT benchmarks/linux-crosscheck/run-all.sh. That one implements the Linux +# cross-check protocol (plain launches with no priority elevation, tuned-state pre-flight +# against a recorded session state, validate.py part-2 tables) and is left untouched; use it for anything +# published as a Linux cross-check. This script is the Windows-parity runner: per-step logs, +# a summary table, ecosystem subsets, and the nice/taskset approximation of the Windows High +# priority classes. The posture delta must be recorded in the run report's environment block. +# +# usage (from anywhere): +# ./benchmarks/run-all.sh # full measurement (tuned bare metal required) +# ./benchmarks/run-all.sh --tune # tune first, untune on exit (needs sudo) +# ./benchmarks/run-all.sh --smoke # short functional pass +# ./benchmarks/run-all.sh --ecosystem rust,go # subset +# ./benchmarks/run-all.sh --out-dir /data/bench-out +# ./benchmarks/run-all.sh --budget baseline # ~30 min/ecosystem instead of the ~10 min default +# ./benchmarks/run-all.sh --js-passes 24 # more JS passes than the profile's default +# ./benchmarks/run-all.sh --no-tune-check # record the bypass and measure anyway +# ./benchmarks/run-all.sh --no-priority # plain launches (the cross-check posture) + +set -uo pipefail + +BENCH_ROOT_SELF="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +. "$BENCH_ROOT_SELF/bench-common.sh" + +usage() { + cat <<'EOF' +usage: run-all.sh [options] + --smoke short functional flags everywhere (no measurement validity) + --ecosystem LIST comma-separated subset of dotnet,rust,jvm,js,python,go + --out-dir PATH artifact/log destination (default benchmarks/out/linux-run-) + --budget NAME measurement budget per engine: + short ~10 min each (default) + baseline ~30 min each (3x capture samples, +1 warmup run) + --js-passes N JS repeat passes per render track; overrides the budget default + --tune sudo linux-crosscheck/tune.sh first, untune.sh on exit + (requires the isolcpus boot entry -- the full protocol state) + --tune-no-isolation no reboot needed: set performance governors + boost off + perf + sample rate here, restore them on exit; the missing CPU isolation + is recorded as a measurement-quality delta + --no-tune-check record a bypass of the bare-metal pre-flight and continue + --no-priority no taskset/nice on the JS and Go timed runs (the cross-check posture) + -h, --help this help +EOF +} + +# --- Arguments ----------------------------------------------------------------------------- +SMOKE=0 +OUT_DIR="" +BUDGET="short" +JS_PASSES="" +DO_TUNE=0 +DO_TUNE_NO_ISOLATION=0 +NO_TUNE_CHECK=0 +ECO_ARG="" +while [ $# -gt 0 ]; do + case "$1" in + --smoke) SMOKE=1 ;; + --ecosystem) ECO_ARG="${2:?--ecosystem requires a list}"; shift ;; + --out-dir) OUT_DIR="${2:?--out-dir requires a path}"; shift ;; + --budget) BUDGET="${2:?--budget requires a name}"; shift ;; + --js-passes) JS_PASSES="${2:?--js-passes requires N}"; shift ;; + --tune) DO_TUNE=1 ;; + --tune-no-isolation) DO_TUNE_NO_ISOLATION=1 ;; + --no-tune-check) NO_TUNE_CHECK=1 ;; + --no-priority) BENCH_NO_PRIORITY=1 ;; + -h|--help) usage; exit 0 ;; + *) usage >&2; bench_die "unknown argument: $1" ;; + esac + shift +done +if [ "$DO_TUNE" = "1" ] && [ "$DO_TUNE_NO_ISOLATION" = "1" ]; then + bench_die "--tune and --tune-no-isolation are mutually exclusive" +fi +# --- Measurement budget ----------------------------------------------------------------------- +# +# Every harness's committed source/script default IS the short profile, so a bare invocation of +# any single harness is the ~10 min shape. `--budget baseline` layers CLI overrides on top -- +# roughly 3x the capture samples and one extra warmup run -- for the ~30 min shape. Nothing +# below changes what is measured, only how many times. +# +# The budget unit is ONE ENGINE, not one ecosystem. An engine +# is 16 cells -- 8 workloads x 2 fairness tracks -- so a leg's budget is 16 x (engines) cells' +# worth of measurement: ~10 min per engine at `short`, ~30 min at `baseline`. Five legs carry two +# engines, .NET carries six, so the .NET leg is about three times the others by construction +# rather than by accident. Every leg's committed source/script default IS its `short` shape. +case "$BUDGET" in + short) + DOTNET_PROFILE_ARGS=() # harness default job: L3/W3/I5 (five-sample floor) + RUST_PROFILE_ARGS=() # source: warm-up 5 s, measure 26 s + JMH_PROFILE_ARGS=() # annotations: F5, W 1x2s, M 5x1s + PY_VALUES_ARGS=(--values 6 --warmups 1) + PY_COLD_ARGS=(--processes 7) + GO_PROFILE_ARGS=() # script default --count 28 + BUDGET_JS_PASSES=38 + ;; + baseline) + # .NET spends its increment on LAUNCHES, and only on launches. It is overhead-bound (one + # process per benchmark case, plus JIT and MemoryDiagnoser), so wall clock is very nearly + # linear in LaunchCount -- which makes the knob predictable -- while raising the iteration + # counts instead runs through BenchmarkDotNet's pilot stage and does not. More to the point, + # a single launch never samples the cross-process term AT ALL: one process, one JIT, one heap + # layout. That is the same gap JMH closes with plural forks and JS with repeat passes, and + # the .NET leg was the one that had never bought it. The launches multiply the harness job's + # five-iteration floor: 10 x 5 = 50 samples per cell here, against short's 3 x 5 = 15. + DOTNET_PROFILE_ARGS=(--launchCount 10) + RUST_PROFILE_ARGS=(--warm-up-time 10 --measurement-time 84) + JMH_PROFILE_ARGS=(-f 5 -wi 2 -i 17) + PY_VALUES_ARGS=(--values 20 --warmups 2) + PY_COLD_ARGS=() # pyperf default 20 processes + GO_PROFILE_ARGS=(--count 84) + BUDGET_JS_PASSES=114 + ;; + *) bench_die "unknown --budget '$BUDGET' (valid: short, baseline)" ;; +esac +[ -n "$JS_PASSES" ] || JS_PASSES="$BUDGET_JS_PASSES" +case "$JS_PASSES" in + ''|*[!0-9]*) bench_die "--js-passes must be an integer" ;; +esac +# 5 is the floor for a stability verdict; bench/aggregate.mjs refuses fewer, so catch +# it here rather than after the passes have already been spent. +[ "$JS_PASSES" -ge 5 ] || bench_die "--js-passes must be at least 5 (the stability-verdict floor)" + +# Fixed program order (anchor-first, then the program's priority order -- same as Windows). +ALL_ORDER=(dotnet rust jvm js python go) +SELECTED=() +if [ -z "$ECO_ARG" ]; then + SELECTED=("${ALL_ORDER[@]}") +else + IFS=',' read -r -a REQUESTED <<< "$ECO_ARG" + for r in "${REQUESTED[@]}"; do + case " ${ALL_ORDER[*]} " in + *" $r "*) : ;; + *) bench_die "unknown ecosystem '$r' (valid: ${ALL_ORDER[*]})" ;; + esac + done + for e in "${ALL_ORDER[@]}"; do + for r in "${REQUESTED[@]}"; do + if [ "$e" = "$r" ]; then SELECTED+=("$e"); break; fi + done + done +fi +[ "${#SELECTED[@]}" -gt 0 ] || bench_die "--ecosystem selected nothing" + +# --- Layout --------------------------------------------------------------------------------- +REPO_ROOT="$BENCH_REPO_ROOT" +if [ -z "$OUT_DIR" ]; then + OUT_DIR="$BENCH_ROOT_SELF/out/linux-run-$(date +%Y%m%d-%H%M%S)" +fi +case "$OUT_DIR" in + /*) : ;; + *) OUT_DIR="$(pwd)/$OUT_DIR" ;; +esac +LOG_DIR="$OUT_DIR/logs" +mkdir -p "$LOG_DIR" || bench_die "cannot create $LOG_DIR" + +DOTNET_DIR="$BENCH_ROOT_SELF/dotnet" +RUST_DIR="$BENCH_ROOT_SELF/rust" +JVM_DIR="$BENCH_ROOT_SELF/jvm" +JS_DIR="$BENCH_ROOT_SELF/js" +PY_DIR="$BENCH_ROOT_SELF/python" +GO_DIR="$BENCH_ROOT_SELF/go" +LCX_DIR="$BENCH_ROOT_SELF/linux-crosscheck" +VENV_PY="$PY_DIR/.venv/bin/python" + +# The eight protocol suites, named after the workloads they measure. Each is one `bench-crossstack --filter` step, so a suite gets +# its own log, its own exit code and its own place to resume from. +DOTNET_SUITES=( + ComposedPageBenchmarks + TrivialSubstitutionBenchmarks + LargeLoopBenchmarks + MixedPageBenchmarks + ConditionalHeavyBenchmarks + FragmentHeavyBenchmarks + FortunesEncodedBenchmarks + EncodedLoopBenchmarks +) + +# The sidebars: measured, published, but never cross-stack rows. +DOTNET_SIDEBARS=(bench-techniques bench-cold bench-internal) + +# --- Step machinery --------------------------------------------------------------------------- +RESULTS=() +FAILED=0 + +if [ -t 1 ]; then + C_RESET=$'\033[0m'; C_CYAN=$'\033[36m'; C_GREEN=$'\033[32m'; C_YELLOW=$'\033[33m'; C_RED=$'\033[31m' +else + C_RESET=""; C_CYAN=""; C_GREEN=""; C_YELLOW=""; C_RED="" +fi + +# run_step [--non-fatal] -- [args...] +run_step() { + local eco="$1" phase="$2" name="$3" workdir="$4"; shift 4 + local nonfatal=0 + if [ "${1:-}" = "--non-fatal" ]; then nonfatal=1; shift; fi + [ "${1:-}" = "--" ] && shift + + local logname logpath start code secs status + logname="$(printf '%s-%s' "$eco" "$name" | tr -c 'A-Za-z0-9._-' '_')" + logpath="$LOG_DIR/$logname.log" + + echo "" + echo "${C_CYAN}== [$eco/$phase] $name${C_RESET}" + echo " dir: $workdir" + echo " cmd: $*" + echo " log: $logpath" + + { + echo "# step: $eco/$name" + echo "# dir: $workdir" + echo "# cmd: $*" + echo "# date: $(date '+%Y-%m-%d %H:%M:%S')" + echo "" + } > "$logpath" + + start=$SECONDS + ( cd "$workdir" && "$@" ) 2>&1 | tee -a "$logpath" + code=${PIPESTATUS[0]} + secs=$(( SECONDS - start )) + { echo ""; echo "# exit: $code"; } >> "$logpath" + + status="OK" + if [ "$code" -ne 0 ]; then + if [ "$nonfatal" = "1" ]; then status="WARN"; else status="FAIL"; FAILED=1; fi + fi + RESULTS+=("$eco|$phase|$name|$code|$secs|$status") + + case "$status" in + FAIL) echo "${C_RED}== FAIL [$eco/$name] exit code $code${C_RESET}" ;; + WARN) echo "${C_YELLOW}== WARN (non-fatal) [$eco/$name] exit code $code${C_RESET}" ;; + *) echo "${C_GREEN}== OK [$eco/$name] ${secs} s${C_RESET}" ;; + esac + return "$code" +} + +copy_artifacts() { # eco name source dest + local eco="$1" name="$2" src="$3" dest="$4" + if [ ! -d "$src" ]; then + echo " (no artifacts at $src -- skipping copy)" + return 0 + fi + if mkdir -p "$dest" && cp -a "$src/." "$dest/"; then + echo " artifacts: $src -> $dest" + RESULTS+=("$eco|copy|$name|0|0|OK") + else + bench_warn "artifact copy failed: $src -> $dest" + RESULTS+=("$eco|copy|$name|1|0|WARN") + fi +} + +tool_version() { # cmd [args...] + local out + command -v "$1" >/dev/null 2>&1 || { echo "NOT FOUND"; return 0; } + out="$("$@" 2>&1)" + [ -n "$out" ] || { echo "NOT FOUND"; return 0; } + printf '%s\n' "$out" | head -n 1 +} + +PREAMBLE_LOG="$LOG_DIR/preamble.log" +note() { echo "$*"; echo "$*" >> "$PREAMBLE_LOG"; } +: > "$PREAMBLE_LOG" + +MODE="MEASUREMENT (spec protocol shapes)" +if [ "$SMOKE" = "1" ]; then + MODE="SMOKE (short functional flags -- results carry NO measurement validity)" +fi + +# --- Summary ---------------------------------------------------------------------------------- +write_summary() { + local summary_path="$OUT_DIR/summary.txt" row + local table + table="$( + printf '%-10s %-8s %-36s %-9s %-8s %s\n' Ecosystem Phase Step ExitCode Seconds Status + printf '%-10s %-8s %-36s %-9s %-8s %s\n' '---------' '-------' '-----------------------------------' '--------' '-------' '------' + for row in ${RESULTS[@]+"${RESULTS[@]}"}; do + IFS='|' read -r c1 c2 c3 c4 c5 c6 <<< "$row" + printf '%-10s %-8s %-36s %-9s %-8s %s\n' "$c1" "$c2" "$c3" "$c4" "$c5" "$c6" + done + )" + echo "" + echo "################################################################################" + echo "## SUMMARY" + echo "################################################################################" + printf '%s\n' "$table" + { + echo "mode: $MODE" +echo "budget: $BUDGET (measurement budget)" + echo "ecosystems: ${SELECTED[*]}" + echo "finished: $(date '+%Y-%m-%d %H:%M:%S')" + echo "" + printf '%s\n' "$table" + } > "$summary_path" + echo "" + echo "summary: $summary_path" + echo "logs: $LOG_DIR" +} + +# --- Preamble: toolchain versions, pin deltas (warn, never fail) ------------------------------- +note '==============================================================================' +note ' Heddle cross-stack benchmarks -- Linux master runner (bare metal)' +note " date: $(date '+%Y-%m-%d %H:%M:%S')" +note " mode: $MODE" +note " ecosystems: ${SELECTED[*]}" +note " out dir: $OUT_DIR" +note '==============================================================================' +note '' +note '-- Toolchain versions (pins in parentheses; deltas WARN, never fail) --' + +V_DOTNET="$(tool_version dotnet --version)" +note " dotnet SDK : $V_DOTNET (protocol records the exact SDK; 10.0.302 was the observed line)" + +V_CARGO="$(tool_version cargo --version)" +V_RUSTC="$(tool_version rustc --version)" +note " cargo : $V_CARGO" +note " rustc : $V_RUSTC (pin: 1.97.1)" +case "$V_RUSTC" in + *1.97.1*) : ;; + *) note " WARN: rustc differs from the pinned 1.97.1 (record as a version delta)." ;; +esac + +V_JAVA="$(tool_version java -version)" +note " java : $V_JAVA (pin: Temurin 25)" +JDK_MAJOR=0 +if [[ "$V_JAVA" =~ version\ \"([0-9]+) ]]; then JDK_MAJOR="${BASH_REMATCH[1]}"; fi +if [ "$JDK_MAJOR" != "25" ]; then + note " WARN: installed JDK major is $JDK_MAJOR, pin is Temurin 25 (record as a version delta)." +fi +V_MVN="$(tool_version mvn --version)" +note " maven : $V_MVN (harness builds use its own mvnw wrapper)" + +V_NODE="$(tool_version node --version)" +V_NPM="$(tool_version npm --version)" +note " node : $V_NODE (pin: v24.x)" +note " npm : $V_NPM" +NODE_IS_PINNED=0 +case "$V_NODE" in v24.*) NODE_IS_PINNED=1 ;; esac +if [ "$NODE_IS_PINNED" = "0" ]; then + note " WARN: node differs from the pinned major v24.x (npm ci will run with --engine-strict=false; record as a version delta)." +fi + +if [ -x "$VENV_PY" ]; then + V_PY="$(tool_version "$VENV_PY" --version)" +else + V_PY="$(tool_version python3 --version)" +fi +note " python : $V_PY (pin: CPython 3.14.x; harness venv at benchmarks/python/.venv)" +case "$V_PY" in + *3.14.*) : ;; + *) note " WARN: python differs from the pinned minor CPython 3.14.x (record as a version delta)." ;; +esac + +V_GO="$(tool_version go version)" +note " go : $V_GO (pin: go1.26.x; run-benchmarks.sh hard-asserts go1.26.5)" +case "$V_GO" in + *go1.26.*) : ;; + *) note " WARN: go differs from the pinned 1.26.x line (record as a version delta)." ;; +esac +# `go tool` may emit "go: downloading ..." first; the version is the last line. +V_TEMPL="$( cd "$GO_DIR" && go tool templ version 2>&1 | tail -n 1 )" +[ -n "$V_TEMPL" ] || V_TEMPL="NOT FOUND" +note " templ : $V_TEMPL (pin: v0.3.1020, via go tool)" + +# --- toolchain.json: the pin deltas, machine-readable ----------------------------------------- +# The notes above are for a human reading the step log. A published report also needs the deltas +# in its environment block, and reconstructing them by hand from artifact metadata after the fact +# is error-prone -- an earlier report had to do exactly that. benchmarks/report/consolidate.py +# reads this file and generates the pin-drift table from it. The posture is unchanged: drift is +# recorded, never fatal. +write_toolchain_json() { + local path="$OUT_DIR/toolchain.json" + # json_row + json_row() { + printf ' "%s": { "pin": %s, "actual": %s, "drift": %s }' \ + "$1" "$(json_str "$2")" "$(json_str "$3")" "$4" + } + json_str() { printf '%s' "$1" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))'; } + local drift_rustc drift_jdk drift_node drift_py drift_go drift_templ + case "$V_RUSTC" in *1.97.1*) drift_rustc=false ;; *) drift_rustc=true ;; esac + [ "$JDK_MAJOR" = "25" ] && drift_jdk=false || drift_jdk=true + [ "$NODE_IS_PINNED" = "1" ] && drift_node=false || drift_node=true + case "$V_PY" in *3.14.*) drift_py=false ;; *) drift_py=true ;; esac + case "$V_GO" in *go1.26.*) drift_go=false ;; *) drift_go=true ;; esac + case "$V_TEMPL" in *v0.3.1020*) drift_templ=false ;; *) drift_templ=true ;; esac + { + echo '{' + json_row ".NET SDK" "(protocol records the observed line)" "$V_DOTNET" false; echo ',' + json_row "Rust" "1.97.1" "$V_RUSTC" "$drift_rustc"; echo ',' + json_row "JDK" "Temurin 25" "$V_JAVA" "$drift_jdk"; echo ',' + json_row "Node.js" "v24.x" "$V_NODE" "$drift_node"; echo ',' + json_row "CPython" "3.14.x" "$V_PY" "$drift_py"; echo ',' + json_row "Go" "go1.26.x" "$V_GO" "$drift_go"; echo ',' + json_row "templ" "v0.3.1020" "$V_TEMPL" "$drift_templ"; echo + echo '}' + } > "$path" + note " toolchain.json written to $path (pin deltas, machine-readable)" +} +write_toolchain_json + +# Goldens-rewrite hazard: a stray dotnet-hosted watcher (Heddle demo/docs tooling) touching +# the working tree during export/verify would dirty the corpus manifest. Best-effort check. +# Running the whole matrix as root leaves every build output (jvm/target, rust/target, +# go/results, BenchmarkDotNet.Artifacts, benchmarks/out/...) owned by root, after which a +# later run as a normal user fails -- typically at `mvnw clean`, which cannot delete the +# root-owned jar. Pick one identity and stay with it. +if [ "$(id -u)" = "0" ]; then + note '' + note ' WARN: running as root. Every build output this run creates will be root-owned,' + note ' so a later run as a normal user will fail (mvnw clean, cargo, npm ci).' + note ' Either keep using root for benchmark runs, or run as your normal user and let' + note ' the script sudo only where it must (tuning, nice) -- do not alternate.' +fi + +DOTNET_PIDS="$(pgrep -x dotnet 2>/dev/null | tr '\n' ' ')" +if [ -n "${DOTNET_PIDS// /}" ]; then + note '' + note " WARN: dotnet process(es) are running (PIDs: ${DOTNET_PIDS% })." + note ' If any is a Heddle file-watcher (demo/docs tooling), stop it before measuring:' + note ' a watcher rewriting goldens mid-run is a corpus-freshness hazard (verify-corpus would go red).' +fi +note '' + +# --- Bare-metal state: pre-flight, optional tune/untune --------------------------------------- +UNTUNE_ON_EXIT=0 +UNTUNE_NO_ISOLATION_ON_EXIT=0 +PRIOR_STATE_FILE="$LOG_DIR/tune-prior-state.txt" +on_exit() { + if [ "$UNTUNE_ON_EXIT" = "1" ]; then + echo "" + echo "== restoring the machine: sudo $LCX_DIR/untune.sh" + sudo "$LCX_DIR/untune.sh" || bench_warn "untune.sh failed -- restore the machine manually" + fi + if [ "$UNTUNE_NO_ISOLATION_ON_EXIT" = "1" ]; then + echo "" + echo "== restoring the machine (governors, boost, perf sample rate)" + bench_untune_no_isolation "$PRIOR_STATE_FILE" || \ + bench_warn "restore failed -- see $PRIOR_STATE_FILE and restore manually" + fi +} +trap on_exit EXIT + +if [ "$SMOKE" = "1" ]; then + note 'RECORDED: --smoke -- bare-metal pre-flight skipped; results carry no measurement validity.' + if [ "$DO_TUNE" = "1" ] || [ "$DO_TUNE_NO_ISOLATION" = "1" ]; then + note 'NOTE: tuning with --smoke still tunes and restores (useful for rehearsing the flow).' + fi +fi + +if [ "$SMOKE" != "1" ] && bench_is_wsl; then + if [ "$NO_TUNE_CHECK" = "1" ]; then + note 'RECORDED: WSL2 detected and --no-tune-check passed -- measuring anyway; the numbers' + note 'RECORDED: are NOT publishable (no cpufreq control, no isolcpus boot under WSL).' + else + bench_die "WSL2 detected: a measurement run needs the bare-metal boot of the protocol box. + For a WSL functional pass use the cross-check tooling instead: + benchmarks/linux-crosscheck/run-all.sh --smoke --no-tune-check + or run this script with --smoke (or --no-tune-check to record a bypass)." + fi +fi + +if [ "$DO_TUNE" = "1" ]; then + [ -x "$LCX_DIR/tune.sh" ] || bench_die "not found or not executable: $LCX_DIR/tune.sh" + note "== tuning the machine: sudo $LCX_DIR/tune.sh (committed cross-check tooling, unmodified)" + sudo "$LCX_DIR/tune.sh" 2>&1 | tee "$LOG_DIR/tune.log" + if [ "${PIPESTATUS[0]}" -eq 0 ]; then + UNTUNE_ON_EXIT=1 + else + bench_die "tune.sh failed -- see $LOG_DIR/tune.log (the machine was left as found). + Without the 'Ubuntu -- benchmark isolation' boot entry, use --tune-no-isolation: + it sets performance governors + boost off here (no reboot) and records the missing + CPU isolation as a measurement-quality delta." + fi +elif [ "$DO_TUNE_NO_ISOLATION" = "1" ]; then + note '== tuning the machine WITHOUT CPU isolation (governors, boost, perf sample rate)' + bench_tune_no_isolation "$PRIOR_STATE_FILE" 2>&1 | tee "$LOG_DIR/tune.log" + if [ "${PIPESTATUS[0]}" -eq 0 ]; then + UNTUNE_NO_ISOLATION_ON_EXIT=1 + else + bench_untune_no_isolation "$PRIOR_STATE_FILE" >/dev/null 2>&1 || true + bench_die "--tune-no-isolation failed -- see $LOG_DIR/tune.log (prior state restored)" + fi + bench_tuned_preflight 1 2>&1 | tee -a "$PREAMBLE_LOG" + [ "${PIPESTATUS[0]}" -eq 0 ] || exit 1 +elif [ "$SMOKE" != "1" ]; then + if [ "$NO_TUNE_CHECK" = "1" ]; then + note 'RECORDED: --no-tune-check -- the bare-metal pre-flight was BYPASSED. A publishable' + note 'RECORDED: measurement run must not bypass it (governors, boost, isolated set).' + else + bench_tuned_preflight 2>&1 | tee -a "$PREAMBLE_LOG" + [ "${PIPESTATUS[0]}" -eq 0 ] || exit 1 + fi +fi + +# --- Phase 1: GATES (all selected ecosystems, stop on first red) ------------------------------- +echo '################################################################################' +echo '## PHASE 1: GATES (stop on first red -- a red gate must be triaged before' +echo '## anything later runs; same rule as linux-crosscheck/run-all.sh)' +echo '################################################################################' + +MVN_ARGS=() +if [ "$JDK_MAJOR" != "0" ] && [ "$JDK_MAJOR" -lt 25 ] 2>/dev/null; then + MVN_ARGS=(-Dmaven.compiler.release=23) + echo "${C_YELLOW}NOTE: JDK $JDK_MAJOR < 25 -- passing ${MVN_ARGS[*]} to the JVM build (pom pins release=25).${C_RESET}" +fi + +NPM_CI_ARGS=() +[ "$NODE_IS_PINNED" = "0" ] && NPM_CI_ARGS=(--engine-strict=false) + +for eco in "${SELECTED[@]}"; do + case "$eco" in + dotnet) + # The full cell registry: byte gate on the controlled track, functional verifier on the + # idiomatic one, security floor on the encoded workloads, plus the materialisation trailer + # and the precompiled-coverage statement. + run_step dotnet gate gate "$DOTNET_DIR" -- dotnet run -c Release -- gate + [ "$FAILED" = "1" ] && break + # The gate itself, gated: harness self-checks including the six-technique differential. + run_step dotnet gate gate-selftest "$DOTNET_DIR" -- dotnet run -c Release -- selftest + [ "$FAILED" = "1" ] && break + run_step dotnet gate gate-verify-corpus "$DOTNET_DIR" -- dotnet run -c Release -- verify-corpus + ;; + rust) + run_step rust gate gate "$RUST_DIR" -- cargo run --release --bin gate + ;; + jvm) + # The committed mvnw wrapper often lacks the executable bit in a Windows-authored + # checkout; it is a POSIX sh script, so fall back to `sh ./mvnw` rather than + # changing the tracked file mode. + MVNW=(./mvnw) + [ -x "$JVM_DIR/mvnw" ] || MVNW=(sh ./mvnw) + run_step jvm gate gate-build-verify "$JVM_DIR" -- \ + "${MVNW[@]}" -q clean verify ${MVN_ARGS[@]+"${MVN_ARGS[@]}"} + ;; + js) + run_step js gate npm-ci "$JS_DIR" -- npm ci ${NPM_CI_ARGS[@]+"${NPM_CI_ARGS[@]}"} + [ "$FAILED" = "1" ] && break + run_step js gate selftest "$JS_DIR" -- npm run selftest + [ "$FAILED" = "1" ] && break + run_step js gate gate "$JS_DIR" -- npm run gate + ;; + python) + if [ ! -x "$VENV_PY" ]; then + run_step python gate venv-create "$PY_DIR" -- python3 -m venv .venv + [ "$FAILED" = "1" ] && break + fi + run_step python gate pip-install "$PY_DIR" -- "$VENV_PY" -m pip install -r requirements.txt + [ "$FAILED" = "1" ] && break + run_step python gate selftest "$PY_DIR" -- "$VENV_PY" -m runner.selftest + [ "$FAILED" = "1" ] && break + run_step python gate gate-all "$PY_DIR" -- "$VENV_PY" -m runner.gate_all + ;; + go) + run_step go gate gate "$GO_DIR" -- go test ./suites + ;; + esac + [ "$FAILED" = "1" ] && break +done + +if [ "$FAILED" = "1" ]; then + echo "" + echo "${C_RED}A GATE IS RED. Stopping before any measurement (triage the gate first).${C_RESET}" + write_summary + exit 1 +fi + +echo "" +echo "${C_GREEN}All selected gates are green.${C_RESET}" + +# --- Phase 2: MEASUREMENT (or smoke) ----------------------------------------------------------- +cat <. That differs +## from linux-crosscheck/run-*.sh, which launch plain by design -- +## record the posture delta in the run report's environment block. +EOF +if [ "$UNTUNE_NO_ISOLATION_ON_EXIT" = "1" ]; then + echo "## RECORDED: --tune-no-isolation -- performance governors and boost=0 are set," + echo "## but this boot has NO isolated SMT pair: the timed runs are not pinned and" + echo "## pyperf falls back to --affinity=4. Disclose this delta in the run report." +fi +if [ "$SMOKE" = "1" ]; then + echo "## SMOKE MODE: the above is informational -- smoke results carry no validity." +fi +echo "################################################################################${C_RESET}" +echo "" +echo '################################################################################' +if [ "$SMOKE" = "1" ]; then + echo '## PHASE 2: SMOKE (functional pass; failures are recorded, run continues)' +else + echo '## PHASE 2: MEASUREMENT (failures are recorded, run continues)' +fi +echo '################################################################################' + +MEASURE_PHASE="measure" +[ "$SMOKE" = "1" ] && MEASURE_PHASE="smoke" + +# Priority-posture pass-through for the two per-harness launchers. +PRIORITY_ARGS=() +[ "$BENCH_NO_PRIORITY" = "1" ] && PRIORITY_ARGS=(--no-priority) + +for eco in "${SELECTED[@]}"; do + case "$eco" in + dotnet) + # Protocol shape: Release, net10.0, the harness's own ShortRun default, + # MemoryDiagnoser via suite attributes; one --filter run per protocol suite. Each suite + # measures BOTH fairness tracks (the Track parameter), which is why the .NET measure phase is + # about twice the length it was when the leg was controlled-track only. + for suite in "${DOTNET_SUITES[@]}"; do + BDN_ARGS=(dotnet run -c Release -- bench-crossstack --filter "*$suite*") + if [ "$SMOKE" = "1" ]; then + BDN_ARGS+=(--job Dry) + else + BDN_ARGS+=(${DOTNET_PROFILE_ARGS[@]+"${DOTNET_PROFILE_ARGS[@]}"}) + fi + run_step dotnet "$MEASURE_PHASE" "suite-$suite" "$DOTNET_DIR" -- "${BDN_ARGS[@]}" + done + # The sidebars run last, where a failure in them cannot mask a missing comparison row. + for sidebar in "${DOTNET_SIDEBARS[@]}"; do + BDN_ARGS=(dotnet run -c Release -- "$sidebar") + if [ "$SMOKE" = "1" ]; then + BDN_ARGS+=(--job Dry) + else + BDN_ARGS+=(${DOTNET_PROFILE_ARGS[@]+"${DOTNET_PROFILE_ARGS[@]}"}) + fi + run_step dotnet "$MEASURE_PHASE" "$sidebar" "$DOTNET_DIR" -- "${BDN_ARGS[@]}" + done + copy_artifacts dotnet copy-bdn-artifacts "$DOTNET_DIR/BenchmarkDotNet.Artifacts" "$OUT_DIR/dotnet" + ;; + rust) + # As in linux-crosscheck/run-rust.sh: the lib target + # does not set bench = false, so the three Criterion bench targets are selected + # explicitly; sources are untouched. + if [ "$SMOKE" = "1" ]; then + run_step rust "$MEASURE_PHASE" criterion-test-pass "$RUST_DIR" -- \ + cargo bench --bench controlled --bench idiomatic --bench cold -- --test + else + run_step rust "$MEASURE_PHASE" criterion-bench "$RUST_DIR" -- \ + cargo bench --bench controlled --bench idiomatic --bench cold -- --noplot \ + ${RUST_PROFILE_ARGS[@]+"${RUST_PROFILE_ARGS[@]}"} + # --out lands the allocation report straight in the run dir: copy_artifacts only handles + # directories, and before this the report existed nowhere but the step log. + mkdir -p "$OUT_DIR/rust" + run_step rust "$MEASURE_PHASE" alloc-report "$RUST_DIR" -- \ + cargo run --release --features alloc-count --bin alloc_report -- \ + --out "$OUT_DIR/rust/alloc-report.txt" + # summarize reads heddle-reference.toml; while the Windows reference rows + # are pending it fails loudly by design -- captured, non-fatal. + run_step rust "$MEASURE_PHASE" summarize "$RUST_DIR" --non-fatal -- \ + cargo run --release --bin summarize + fi + copy_artifacts rust copy-criterion "$RUST_DIR/target/criterion" "$OUT_DIR/rust/criterion" + ;; + jvm) + mkdir -p "$OUT_DIR/jvm" + RFF="$OUT_DIR/jvm/jmh-result.json" + # JMH takes a machine-wide lock at ${TMPDIR:-/tmp}/jmh.lock, created by whoever runs + # first. When this runner is used both as root and as a normal user, a leftover lock + # owned by the other user kills every later run instantly: fs.protected_regular (=2 on + # Ubuntu) stops even root from opening a world-writable file it does not own in a + # sticky /tmp. Clear a stale lock -- but never while a JMH process is actually running, + # since that is the lock doing its job (two concurrent JMH runs invalidate both). + JMH_LOCK="${TMPDIR:-/tmp}/jmh.lock" + if [ -e "$JMH_LOCK" ]; then + if pgrep -f 'benchmarks\.jar' >/dev/null 2>&1; then + bench_warn "a JMH run appears to be in progress; leaving $JMH_LOCK alone (this run will refuse to start)" + elif rm -f "$JMH_LOCK" 2>/dev/null; then + echo " cleared stale JMH lock: $JMH_LOCK" + else + bench_warn "stale JMH lock $JMH_LOCK owned by $(stat -c %U "$JMH_LOCK" 2>/dev/null || echo '?') and not removable here -- remove it (sudo rm -f $JMH_LOCK) or the JMH step will fail instantly" + fi + fi + if [ "$SMOKE" = "1" ]; then + run_step jvm "$MEASURE_PHASE" jmh-smoke "$JVM_DIR" -- \ + java -jar target/benchmarks.jar -f 1 -wi 1 -i 1 -w 1s -r 1s -foe true -prof gc -rf json -rff "$RFF" + else + echo "${C_YELLOW}NOTE: JMH regime = annotations (Fork 3, 1x2s warmup, 3x1s measure)${C_RESET}" + echo "${C_YELLOW} + budget '$BUDGET' overrides ${JMH_PROFILE_ARGS[*]:-(none)}.${C_RESET}" + echo "${C_YELLOW} Expect ~9 min (short) / ~23 min (baseline); it was 4.5 h before the uniform budget.${C_RESET}" + run_step jvm "$MEASURE_PHASE" jmh-full "$JVM_DIR" -- \ + java -jar target/benchmarks.jar ${JMH_PROFILE_ARGS[@]+"${JMH_PROFILE_ARGS[@]}"} \ + -prof gc -rf json -rff "$RFF" + fi + ;; + js) + # The committed launcher js/run.sh carries the normative shapes (taskset + nice, node + # --expose-gc --allow-natives-syntax, stdout captured to artifacts/). + # + # The two render tracks run JS_PASSES times each and are aggregated. mitata + # exposes no per-cell time budget -- `B.run()` builds its own options object, so + # min_cpu_time (642 ms) is unreachable from the public API -- which left this ecosystem + # measuring 32 cells in 31 s against 15-31 s/cell everywhere else. Its share of the uniform + # budget is therefore spent on independent processes: run.sh --repeat N, then + # bench/aggregate.mjs medians the per-pass avg into artifacts/.json and emits the + # stability verdict. That makes the stability procedure the measurement rather than a separate + # publication-gating step someone has to remember, which is how the withdrawn 2026-07-22 run + # JS numbers with no RSD verdict at all. + # + # cold-compile stays a single pass: it is a compile-dominated sidebar, not a protocol + # cell, so repeating it buys a stability verdict for numbers no ranking consumes. + for js_script in controlled idiomatic; do + if [ "$SMOKE" = "1" ]; then + run_step js "$MEASURE_PHASE" "bench-$js_script" "$JS_DIR" -- \ + ./run.sh "bench/$js_script.mjs" ${PRIORITY_ARGS[@]+"${PRIORITY_ARGS[@]}"} + else + run_step js "$MEASURE_PHASE" "bench-$js_script-x$JS_PASSES" "$JS_DIR" -- \ + ./run.sh "bench/$js_script.mjs" --repeat "$JS_PASSES" ${PRIORITY_ARGS[@]+"${PRIORITY_ARGS[@]}"} + fi + done + run_step js "$MEASURE_PHASE" bench-cold-compile "$JS_DIR" -- \ + ./run.sh bench/cold-compile.mjs ${PRIORITY_ARGS[@]+"${PRIORITY_ARGS[@]}"} + copy_artifacts js copy-artifacts "$JS_DIR/artifacts" "$OUT_DIR/js" + ;; + python) + # Five pyperf Runner scripts, library defaults, explicit --affinity, JSON + # outputs. The Windows counterpart of the elevated shell is root/passwordless sudo + # (pyperf raises the process priority where it can). + if [ "$(id -u)" != "0" ] && ! sudo -n true 2>/dev/null; then + echo "${C_YELLOW}WARN: not root and no passwordless sudo -- pyperf's priority elevation${C_RESET}" + echo "${C_YELLOW} is skipped silently. A measurement run should provide it.${C_RESET}" + fi + PY_AFFINITY="" + if PY_PAIR="$(bench_smt_pair)" && [ -n "$(bench_isolated_set)" ]; then + PY_AFFINITY="$PY_PAIR" + echo " pyperf affinity: --affinity=$PY_AFFINITY (isolated pair, read from topology)" + else + PY_AFFINITY="4" + echo "${C_YELLOW} RECORDED: no isolated SMT pair -- falling back to --affinity=4 (the Windows value).${C_RESET}" + fi + mkdir -p "$OUT_DIR/python" + PY_SMOKE_ARGS=() + [ "$SMOKE" = "1" ] && PY_SMOKE_ARGS=(--debug-single-value) + # The four render scripts keep pyperf's default 20x3x1 -- at ~9 min for the + # 32 protocol cells they already sit inside the uniform per-engine budget. The cold-compile + # sidebar does not: at defaults it cost 288 s, a third of the ecosystem's time for a + # non-comparable sidebar, so it runs with 7 processes. + for s in bench_jinja2_controlled bench_jinja2_idiomatic bench_mako_controlled bench_mako_idiomatic bench_cold_compile; do + if [ "$s" = "bench_cold_compile" ]; then + PY_SHAPE_ARGS=(${PY_COLD_ARGS[@]+"${PY_COLD_ARGS[@]}"}) + else + PY_SHAPE_ARGS=(${PY_VALUES_ARGS[@]+"${PY_VALUES_ARGS[@]}"}) + fi + run_step python "$MEASURE_PHASE" "$s" "$PY_DIR" -- \ + "$VENV_PY" "$s.py" "--affinity=$PY_AFFINITY" \ + ${PY_SHAPE_ARGS[@]+"${PY_SHAPE_ARGS[@]}"} ${PY_SMOKE_ARGS[@]+"${PY_SMOKE_ARGS[@]}"} \ + -o "$OUT_DIR/python/$s.json" + done + # Memory pass -- tracemalloc, separate from timing. + MEM_ARGS=() + [ "$SMOKE" = "1" ] && MEM_ARGS=(--reps 5) + run_step python "$MEASURE_PHASE" mem-tracemalloc "$PY_DIR" -- \ + "$VENV_PY" mem_tracemalloc.py ${MEM_ARGS[@]+"${MEM_ARGS[@]}"} -o "$OUT_DIR/python/memory.json" + ;; + go) + # Go reproduce path: the committed run-benchmarks.sh (version asserts, templ + # freshness, vet, gates, prebuild, timed runs, benchstat). + GO_ARGS=(./run-benchmarks.sh) + if [ "$SMOKE" = "1" ]; then + GO_ARGS+=(--count 1 --benchtime 100ms) + else + GO_ARGS+=(${GO_PROFILE_ARGS[@]+"${GO_PROFILE_ARGS[@]}"}) + fi + GO_ARGS+=(${PRIORITY_ARGS[@]+"${PRIORITY_ARGS[@]}"}) + run_step go "$MEASURE_PHASE" run-benchmarks "$GO_DIR" -- "${GO_ARGS[@]}" + copy_artifacts go copy-results "$GO_DIR/results" "$OUT_DIR/go" + ;; + esac +done + +write_summary + +# --- consolidated tables ---------------------------------------------------------------------- +# Publishing used to mean copying artifacts into docs/benchmarks// and then running +# consolidate.py by hand. That hand step is exactly where table ORDER and transcribed figures drift +# from the artifacts, so the runner does it here: the out dir gets its own consolidated-tables.md +# and summary-tables.md, generated in tier order, before anyone looks at a number. Publishing is +# then a copy -- no regeneration, no hand-ordered tables, no transcription. +# +# Non-fatal by design: a full sweep is expensive and a table-generation failure must not discard +# it. The step is recorded like any other, so `RESULT: OK` still means every measurement is green +# and a WARN row here says the tables need attention, not the run. +if [ "$SMOKE" != "1" ]; then + run_step report "$MEASURE_PHASE" consolidate "$REPO_ROOT" --non-fatal -- \ + python3 benchmarks/report/consolidate.py "$OUT_DIR" + write_summary +fi + +if [ "$FAILED" = "1" ]; then + echo "${C_RED}RESULT: FAILED (one or more steps exited nonzero -- see summary above).${C_RESET}" + exit 1 +fi +echo "${C_GREEN}RESULT: OK (all steps green; WARN rows, if any, are recorded non-fatal steps).${C_RESET}" +exit 0 diff --git a/benchmarks/rust/.gitignore b/benchmarks/rust/.gitignore new file mode 100644 index 00000000..ea5d4fbe --- /dev/null +++ b/benchmarks/rust/.gitignore @@ -0,0 +1,5 @@ +# Cargo build artifacts (Cargo.lock IS committed — a reproducibility pin). +/target +# alloc_report's per-run measurement output. The master runners copy it into the +# run directory, and the published copy lives there — never here. +/alloc-report.txt diff --git a/benchmarks/rust/Cargo.lock b/benchmarks/rust/Cargo.lock new file mode 100644 index 00000000..7a6439ce --- /dev/null +++ b/benchmarks/rust/Cargo.lock @@ -0,0 +1,763 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloca" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + +[[package]] +name = "allocation-counter" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beb9e990c0a33699f1984d85a6abead615ccc72dd8130bf3e15dcabe2ca149c9" + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "askama" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf825125edd887a019d0a3a837dcc5499a68b0d034cc3eb594070c3e18addc" +dependencies = [ + "askama_macros", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1c7065972a130eafa84215f21352ae15b4a7393da48c1f5e103904490736738" +dependencies = [ + "askama_parser", + "basic-toml", + "glob", + "memchr", + "proc-macro2", + "quote", + "rustc-hash", + "serde", + "serde_derive", + "syn 2.0.119", +] + +[[package]] +name = "askama_macros" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e23b1d2c4bd39a41971f6124cef4cc6fd0540913ecb90919b69ab3bbe44ae1a" +dependencies = [ + "askama_derive", +] + +[[package]] +name = "askama_parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7db09fde9143e7ac4513358fb32ee32847125b63b18ea715afd487956da715da" +dependencies = [ + "rustc-hash", + "serde", + "serde_derive", + "unicode-ident", + "winnow", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89588d05638b5b4594a3348a2d6c20277e43a7f5c5202b05cc56888475a47b8" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fb99565819980999fb7b4a1796046a5c949e6d4ff132cf5fadf5a641e20d776" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "criterion" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3" +dependencies = [ + "alloca", + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "itertools", + "num-traits", + "oorandom", + "page_size", + "plotters", + "rayon", + "regex", + "serde", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "futures-core" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" + +[[package]] +name = "futures-task" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" + +[[package]] +name = "futures-util" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "heddle-bench-rust" +version = "0.1.0" +dependencies = [ + "allocation-counter", + "askama", + "criterion", + "serde", + "serde_json", + "tera", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.187" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7743783ea728ef5c31194c6590797eed286449b4a4e87d626d8a51f0a94e732" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "regex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "rustc-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustversion" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.2", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "syn" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a207d6d6a2b7fc470b80443726053f18a2481b7e1eee970597051596567987a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tera" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ea62bd58771b570262e11ffa274fa9eda9986bd886e6e3a1f7f42afef8024c" +dependencies = [ + "serde", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.119", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.8.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/benchmarks/rust/Cargo.toml b/benchmarks/rust/Cargo.toml new file mode 100644 index 00000000..84b8cf56 --- /dev/null +++ b/benchmarks/rust/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "heddle-bench-rust" +version = "0.1.0" +edition = "2024" +publish = false +description = "Cross-stack benchmark harness (Rust): Askama and Tera vs the Heddle golden corpus" + +[lib] +bench = false + +[dependencies] +askama = "=0.16.0" +tera = { version = "=2.0.0", default-features = false } +serde = { version = "=1.0.229", features = ["derive"] } +serde_json = "=1.0.151" +allocation-counter = { version = "=0.8.1", optional = true } + +[dev-dependencies] +criterion = "=0.8.2" + +[features] +alloc-count = ["dep:allocation-counter"] + +[[bench]] +name = "controlled" +harness = false + +[[bench]] +name = "idiomatic" +harness = false + +[[bench]] +name = "cold" +harness = false + +[[bin]] +name = "gate" +path = "src/bin/gate.rs" +bench = false + +[[bin]] +name = "summarize" +path = "src/bin/summarize.rs" +bench = false + +[[bin]] +name = "alloc_report" +path = "src/bin/alloc_report.rs" +required-features = ["alloc-count"] +bench = false diff --git a/benchmarks/rust/askama.toml b/benchmarks/rust/askama.toml new file mode 100644 index 00000000..6661c6ce --- /dev/null +++ b/benchmarks/rust/askama.toml @@ -0,0 +1,2 @@ +[general] +dirs = ["templates"] diff --git a/benchmarks/rust/benches/cold.rs b/benchmarks/rust/benches/cold.rs new file mode 100644 index 00000000..2698e6cc --- /dev/null +++ b/benchmarks/rust/benches/cold.rs @@ -0,0 +1,43 @@ +//! Tera cold-parse bench. Custom main (`harness = false`): calls +//! `assert_all()` first (cold numbers are also numbers — no number without a green gate), +//! then times exactly one thing: +//! constructing fresh `Tera` instances and registering the same template sets the three +//! runtime instances hold (all 21 Tera template files across both tracks — the full parse +//! set). Reported as "Tera cold parse (all templates)" in the per-ecosystem report section, +//! labeled non-comparable; Askama (like Heddle) has no runtime parse step and is disclosed as +//! build-time in the report. Artifact path: `target/criterion/cold/tera-parse-all-templates/`. + +use std::time::Duration; + +use criterion::Criterion; +use heddle_bench_rust::engines::{tera_controlled, tera_idiomatic}; +use heddle_bench_rust::gates; + +fn main() { + // Parity before timing — all 32 cells, before any Criterion construction. + gates::assert_all(); + + // The shared pinned config; the trailing `.configure_from_args()` is mandatory and last. + let mut criterion = Criterion::default() + .warm_up_time(Duration::from_secs(5)) + .measurement_time(Duration::from_secs(26)) + .sample_size(100) + .confidence_level(0.95) + .configure_from_args(); + + let mut group = criterion.benchmark_group("cold"); + group.bench_function("tera-parse-all-templates", |b| { + b.iter(|| { + // The same three instances the runtime holds: controlled-raw (8 files), + // controlled-encoded (2), idiomatic (11) — 21 template files parsed fresh. + ( + tera_controlled::build_fresh_raw(), + tera_controlled::build_fresh_encoded(), + tera_idiomatic::build_fresh(), + ) + }) + }); + group.finish(); + + criterion.final_summary(); +} diff --git a/benchmarks/rust/benches/controlled.rs b/benchmarks/rust/benches/controlled.rs new file mode 100644 index 00000000..7331f1ab --- /dev/null +++ b/benchmarks/rust/benches/controlled.rs @@ -0,0 +1,44 @@ +//! Controlled-track Criterion bench. Custom main (`harness = false`): gates all 16 +//! controlled cells **before** constructing `Criterion` (a failed gate produces +//! no `target/criterion` output), then times each cell under the shared pinned config. +//! Groups are `controlled-`, functions `askama` / `tera`, so artifacts land at +//! `target/criterion/controlled-//new/estimates.json`. + +use std::time::Duration; + +use criterion::Criterion; +use heddle_bench_rust::{corpus, gates}; + +fn main() { + // Parity before timing — panic with the diagnostic message before any Criterion + // construction. + for cell in gates::CELLS.iter().filter(|c| c.track == "controlled") { + gates::assert_controlled(cell); + } + + // Pinned per-engine budget: Criterion defaults except warm_up_time 3 s + // -> 5 s and measurement_time 5 s -> 26 s; the trailing `.configure_from_args()` + // is mandatory and last, so `--test` / `--noplot` / name filters take effect while the + // pinned settings survive when no CLI flag overrides them. + let mut criterion = Criterion::default() + .warm_up_time(Duration::from_secs(5)) + .measurement_time(Duration::from_secs(26)) + .sample_size(100) + .confidence_level(0.95) + .configure_from_args(); + + for workload in corpus::WORKLOADS { + let mut group = criterion.benchmark_group(format!("controlled-{workload}")); + for cell in gates::CELLS + .iter() + .filter(|c| c.track == "controlled" && c.workload == workload) + { + // The rendered String is returned into Criterion's sink: drop cost is inside the + // measurement for every engine equally. + group.bench_function(cell.engine, |b| b.iter(|| (cell.render)())); + } + group.finish(); + } + + criterion.final_summary(); +} diff --git a/benchmarks/rust/benches/idiomatic.rs b/benchmarks/rust/benches/idiomatic.rs new file mode 100644 index 00000000..cd57ee0a --- /dev/null +++ b/benchmarks/rust/benches/idiomatic.rs @@ -0,0 +1,38 @@ +//! Idiomatic-track Criterion bench. Custom main (`harness = false`): gates all 16 +//! idiomatic cells (verifier semantics) **before** constructing `Criterion`, then +//! times each cell under the shared pinned config. Groups are `idiomatic-`, +//! functions `askama` / `tera`. + +use std::time::Duration; + +use criterion::Criterion; +use heddle_bench_rust::{corpus, gates}; + +fn main() { + // Parity before timing — panic with the diagnostic message before any Criterion + // construction. + for cell in gates::CELLS.iter().filter(|c| c.track == "idiomatic") { + gates::assert_idiomatic(cell); + } + + // The shared pinned config; the trailing `.configure_from_args()` is mandatory and last. + let mut criterion = Criterion::default() + .warm_up_time(Duration::from_secs(5)) + .measurement_time(Duration::from_secs(26)) + .sample_size(100) + .confidence_level(0.95) + .configure_from_args(); + + for workload in corpus::WORKLOADS { + let mut group = criterion.benchmark_group(format!("idiomatic-{workload}")); + for cell in gates::CELLS + .iter() + .filter(|c| c.track == "idiomatic" && c.workload == workload) + { + group.bench_function(cell.engine, |b| b.iter(|| (cell.render)())); + } + group.finish(); + } + + criterion.final_summary(); +} diff --git a/benchmarks/rust/heddle-reference.toml b/benchmarks/rust/heddle-reference.toml new file mode 100644 index 00000000..aab6d909 --- /dev/null +++ b/benchmarks/rust/heddle-reference.toml @@ -0,0 +1,41 @@ +# Heddle reference wall-time values for the `summarize` tool. +# +# Schema (normative): +# pending = bool # true while no published run exists to transcribe from +# source-run = string # date of the published run these values come from +# [workloads] # workload id -> Heddle wall time in ns/render, transcribed once +# = # from the published run and reviewed in diff +# +# A standing ruling (2026-07-21, since discharged) held while no run was published: this file +# carried the schema but no values, and `pending = true` made `summarize` fail loudly +# ("no published Heddle reference run exists yet") rather than emit tables with fabricated +# Heddle numbers. +# +# SOURCE RUN CAVEAT (2026-07-25). These values come from +# `docs/benchmarks/2026-07-25/`, which is a **Linux, off-protocol validation run** — not a run on +# the pinned Windows protocol machine. It is used because it is the +# published run: its .NET anchor measured all eight workloads in the same session, on the same +# machine and in the same tuned state as the Rust figures `summarize` compares against, which is +# the property the ratio column actually needs. When a protocol-machine run is published, repoint +# `source-run` and re-transcribe — and note that the absolute values will move materially (this +# run had CPU boost off), even though ordering has so far proved stable. +# +# Provenance: each value is the BenchmarkDotNet `Mean` of `RenderHeddle` from +# `docs/benchmarks/2026-07-25/dotnet/results/`, +# converted to ns/render (the only arithmetic applied). The harness dispersion published +# alongside these figures is BDN's `Error` and `StdDev`, quoted in the comments below. +# Suite mapping is pinned; do not re-derive it here — the mapping is the contract, not a +# convenience. + +pending = false +source-run = "2026-07-25" + +[workloads] +composed-page = 30520.0 # 30.52 μs (Error 1.151 μs, StdDev 1.076 μs) TextRenderBenchmarks +trivial-substitution = 164.6 # 164.6 ns (Error 0.27 ns, StdDev 0.21 ns) SubstitutionRenderBenchmarks +large-loop = 379300.0 # 379.3 μs (Error 3.66 μs, StdDev 3.42 μs) LoopRenderBenchmarks +mixed-page = 3591.0 # 3.591 μs (Error 0.0026 μs, StdDev 0.0025 μs) MixedRenderBenchmarks +conditional-heavy = 19780.0 # 19.78 μs (Error 0.021 μs, StdDev 0.017 μs) ConditionalRenderBenchmarks +fragment-heavy = 3907.0 # 3.907 μs (Error 0.0031 μs, StdDev 0.0029 μs) FragmentRenderBenchmarks +fortunes-encoded = 938.7 # 938.7 ns (Error 4.77 ns, StdDev 4.46 ns) FortunesRenderBenchmarks +encoded-loop = 1882000.0 # 1.882 ms (Error 0.0122 ms, StdDev 0.0102 ms) EncodedLoopRenderBenchmarks diff --git a/benchmarks/rust/rust-toolchain.toml b/benchmarks/rust/rust-toolchain.toml new file mode 100644 index 00000000..72436043 --- /dev/null +++ b/benchmarks/rust/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.97.1" diff --git a/benchmarks/rust/src/bin/alloc_report.rs b/benchmarks/rust/src/bin/alloc_report.rs new file mode 100644 index 00000000..2d8b2b83 --- /dev/null +++ b/benchmarks/rust/src/bin/alloc_report.rs @@ -0,0 +1,85 @@ +//! `alloc_report` binary — the separate, non-timed allocation pass. +//! +//! Built only with `--features alloc-count` (`required-features` in Cargo.toml), so the timed +//! Criterion binaries never link the counting global allocator. For each of the 32 +//! registered cells this binary renders once as an uncounted warm-up and then reports +//! `count_total` / `bytes_total` for a single counted render. Gates run first — no +//! number without a green gate, allocation numbers included. +//! +//! Usage: `cargo run --release --features alloc-count --bin alloc_report [-- --out ]` +//! +//! Report artifact: `alloc-report.txt`, written next to the crate by default. +//! Until 2026-07-25 this binary only printed to stdout despite documenting that artifact, so the +//! master runners — which copy `target/criterion` and nothing else — had nothing to collect and +//! every published report carried a "Rust allocation report absent" note. It now writes the file +//! *and* keeps stdout, so the step log still shows the table. + +use std::io::Write; +use std::path::PathBuf; + +use heddle_bench_rust::gates; + +fn out_path() -> PathBuf { + // `--out ` overrides; default is alongside the crate so `cargo run` from any cwd lands + // in a predictable place the runners can copy from. + let mut args = std::env::args().skip(1); + while let Some(arg) = args.next() { + if arg == "--out" { + match args.next() { + Some(p) => return PathBuf::from(p), + None => { + eprintln!("alloc_report: --out requires a path"); + std::process::exit(2); + } + } + } + } + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("alloc-report.txt") +} + +fn main() { + // Parity before any number. Panics with the diagnostic message on a red cell. + gates::assert_all(); + + let mut out = String::new(); + out.push_str("# alloc-report — allocation-counter 0.8.1, one counted render per cell\n"); + out.push_str("# Per-ecosystem figures only; Tera is the baseline. Allocation counts are NOT\n"); + out.push_str("# comparable across ecosystems.\n\n"); + out.push_str(&format!( + "{:<11} {:<7} {:<21} {:>12} {:>14}\n", + "track", "engine", "workload", "count_total", "bytes_total" + )); + out.push_str(&"-".repeat(11 + 1 + 7 + 1 + 21 + 1 + 12 + 1 + 14)); + out.push('\n'); + + for cell in gates::CELLS { + // Warm-up render, deliberately outside the measured closure (lazy one-time work such + // as Tera's instance construction must not land in the per-render figure). + let warm = (cell.render)(); + std::hint::black_box(&warm); + drop(warm); + + let info = allocation_counter::measure(|| { + let output = (cell.render)(); + std::hint::black_box(&output); + }); + + out.push_str(&format!( + "{:<11} {:<7} {:<21} {:>12} {:>14}\n", + cell.track, cell.engine, cell.workload, info.count_total, info.bytes_total + )); + } + + // stdout keeps the step log readable; the file is what the runners copy into the run dir. + print!("{out}"); + let _ = std::io::stdout().flush(); + + let path = out_path(); + match std::fs::write(&path, out.as_bytes()) { + Ok(()) => println!("\nalloc-report written to {}", path.display()), + Err(err) => { + eprintln!("alloc_report: could not write {}: {err}", path.display()); + std::process::exit(1); + } + } +} diff --git a/benchmarks/rust/src/bin/gate.rs b/benchmarks/rust/src/bin/gate.rs new file mode 100644 index 00000000..92b0f666 --- /dev/null +++ b/benchmarks/rust/src/bin/gate.rs @@ -0,0 +1,42 @@ +//! `gate` binary — the standalone parity gate. +//! +//! Runs the same 32-cell registry the bench binaries gate against, but iterates +//! `gates::CELLS` / `gates::check_cell` itself so that one `[PASS]`/`[FAIL]` line is printed +//! per cell instead of stopping at the first failure (`gates::assert_all` panics on cell one). +//! Exits 0 iff all cells pass — the reproduce command's first step, the CI hook, and the +//! source of the report's `gate-report.txt` artifact. +//! +//! Usage: `cargo run --release --bin gate` + +use std::process::ExitCode; + +use heddle_bench_rust::gates; + +fn main() -> ExitCode { + let total = gates::CELLS.len(); + let mut failed = 0usize; + + for cell in gates::CELLS { + match gates::check_cell(cell) { + Ok(()) => println!( + "[PASS] {} {}/{}", + cell.track, cell.engine, cell.workload + ), + Err(message) => { + failed += 1; + // The Result already carries the `[FAIL] ...` diagnostic message shape. + println!("{message}"); + } + } + } + + println!(); + println!("gate: {}/{} cells passed", total - failed, total); + + if failed == 0 { + ExitCode::SUCCESS + } else { + eprintln!("gate: {failed} cell(s) FAILED — no number may be published from this tree"); + ExitCode::FAILURE + } +} diff --git a/benchmarks/rust/src/bin/summarize.rs b/benchmarks/rust/src/bin/summarize.rs new file mode 100644 index 00000000..c45ef858 --- /dev/null +++ b/benchmarks/rust/src/bin/summarize.rs @@ -0,0 +1,275 @@ +//! `summarize` binary — generates the report's two wall-time tables. +//! +//! Reads every `target/criterion///new/estimates.json` written by the three +//! bench targets, takes `mean.point_estimate` plus the 95% CI bounds, joins the Heddle +//! reference values from the checked-in `heddle-reference.toml`, and prints GitHub-flavored +//! Markdown rows for `docs/benchmarks//index.md`. Generation (rather than hand +//! transcription) is what makes the tables mechanically faithful to the committed JSON. +//! +//! Two deliberate loud failures, both exit nonzero and print nothing pasteable: +//! * `pending = true` in `heddle-reference.toml` — no published run supplies the Heddle +//! reference rows yet, so no table may be emitted. +//! * any expected cell missing its `estimates.json` — a partial table pasted into a report +//! reads as a complete one. +//! +//! Usage: `cargo run --release --bin summarize` + +use std::collections::BTreeMap; +use std::fs; +use std::path::PathBuf; +use std::process::ExitCode; + +use heddle_bench_rust::corpus::WORKLOADS; + +const TRACKS: [&str; 2] = ["controlled", "idiomatic"]; +const ENGINES: [&str; 2] = ["askama", "tera"]; + +/// The Tera cold-parse sidebar — one aggregate number, per-ecosystem only. +const COLD_GROUP: &str = "cold"; +const COLD_FUNCTION: &str = "tera-parse-all-templates"; + +// ---- heddle-reference.toml --------------------------------------------------------------- + +/// The reference file's schema is fixed and tiny (`pending`, `source-run`, `[workloads]` of +/// `id = `), so it is parsed here rather than adding a TOML crate to the pinned +/// dependency set. +struct Reference { + pending: bool, + source_run: String, + workloads: BTreeMap, +} + +fn parse_reference(text: &str) -> Result { + let mut pending = true; + let mut source_run = String::new(); + let mut workloads = BTreeMap::new(); + let mut in_workloads = false; + + for (lineno, raw) in text.lines().enumerate() { + let line = raw.split('#').next().unwrap_or("").trim(); + if line.is_empty() { + continue; + } + if line.starts_with('[') { + in_workloads = line == "[workloads]"; + continue; + } + let (key, value) = line + .split_once('=') + .ok_or_else(|| format!("heddle-reference.toml:{}: not a key = value line", lineno + 1))?; + let key = key.trim(); + let value = value.trim().trim_matches('"'); + + if in_workloads { + let ns: f64 = value.parse().map_err(|_| { + format!("heddle-reference.toml:{}: '{key}' is not a number", lineno + 1) + })?; + workloads.insert(key.to_string(), ns); + } else { + match key { + "pending" => pending = value == "true", + "source-run" => source_run = value.to_string(), + _ => {} + } + } + } + Ok(Reference { + pending, + source_run, + workloads, + }) +} + +// ---- criterion estimates ------------------------------------------------------------------ + +struct Estimate { + mean_ns: f64, + lower_ns: f64, + upper_ns: f64, +} + +fn criterion_dir() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("target") + .join("criterion") +} + +fn read_estimate(group: &str, function: &str) -> Option { + let path = criterion_dir() + .join(group) + .join(function) + .join("new") + .join("estimates.json"); + let text = fs::read_to_string(path).ok()?; + let value: serde_json::Value = serde_json::from_str(&text).ok()?; + let mean = value.get("mean")?; + Some(Estimate { + mean_ns: mean.get("point_estimate")?.as_f64()?, + lower_ns: mean + .get("confidence_interval")? + .get("lower_bound")? + .as_f64()?, + upper_ns: mean + .get("confidence_interval")? + .get("upper_bound")? + .as_f64()?, + }) +} + +/// Criterion-native display: the unit Criterion itself would print for that magnitude. +fn fmt_time(ns: f64) -> String { + if ns < 1_000.0 { + format!("{ns:.2} ns") + } else if ns < 1_000_000.0 { + format!("{:.2} us", ns / 1_000.0) + } else { + format!("{:.2} ms", ns / 1_000_000.0) + } +} + +fn fmt_native(e: &Estimate) -> String { + format!( + "{} [{}, {}]", + fmt_time(e.mean_ns), + fmt_time(e.lower_ns), + fmt_time(e.upper_ns) + ) +} + +fn engine_label(engine: &str) -> &'static str { + match engine { + "askama" => "Askama", + "tera" => "Tera", + _ => "?", + } +} + +// ---- tables -------------------------------------------------------------------------------- + +fn render_table(track: &str, reference: &Reference, missing: &mut Vec) -> String { + let mut out = String::new(); + out.push_str(&format!( + "### Wall time - {track} track (Criterion mean, 95% CI)\n\n" + )); + out.push_str(&format!( + "Heddle rows are the labeled excerpt from the published run of {} named by \ + `heddle-reference.toml`; they are not re-measured here. Whether \ + that run is on the protocol machine is stated in that file's header - as of 2026-07-25 \ + it is not, and the Windows protocol run is pending a re-test. Ratios are engine / \ + Heddle.\n\n", + reference.source_run + )); + out.push_str("| Workload | Engine | Criterion mean (95% CI) | ns/render | Ratio vs Heddle |\n"); + out.push_str("|---|---|---|---|---|\n"); + + for workload in WORKLOADS { + let heddle_ns = reference.workloads.get(workload).copied(); + match heddle_ns { + Some(ns) => out.push_str(&format!( + "| {workload} | Heddle (reference - .NET 10, same machine, from {} run) | - | {ns:.2} | - |\n", + reference.source_run + )), + None => { + missing.push(format!("heddle-reference.toml: no value for '{workload}'")); + out.push_str(&format!( + "| {workload} | Heddle (reference - .NET 10, same machine) | - | MISSING | - |\n" + )); + } + } + + for engine in ENGINES { + let group = format!("{track}-{workload}"); + match read_estimate(&group, engine) { + Some(estimate) => { + let ratio = match heddle_ns { + Some(ns) if ns > 0.0 => format!("{:.2}x", estimate.mean_ns / ns), + _ => "-".to_string(), + }; + out.push_str(&format!( + "| {workload} | {} | {} | {:.2} | {ratio} |\n", + engine_label(engine), + fmt_native(&estimate), + estimate.mean_ns + )); + } + None => { + missing.push(format!("target/criterion/{group}/{engine}/new/estimates.json")); + out.push_str(&format!( + "| {workload} | {} | MISSING | MISSING | - |\n", + engine_label(engine) + )); + } + } + } + } + out.push('\n'); + out +} + +fn main() -> ExitCode { + let reference_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("heddle-reference.toml"); + let text = match fs::read_to_string(&reference_path) { + Ok(text) => text, + Err(err) => { + eprintln!("summarize: cannot read {}: {err}", reference_path.display()); + return ExitCode::FAILURE; + } + }; + let reference = match parse_reference(&text) { + Ok(reference) => reference, + Err(message) => { + eprintln!("summarize: {message}"); + return ExitCode::FAILURE; + } + }; + + if reference.pending { + eprintln!("summarize: no published Heddle reference run exists yet."); + eprintln!( + "summarize: {} carries pending = true, so the Heddle reference rows do not exist yet", + reference_path.display() + ); + eprintln!("summarize: and NO table is emitted - tables without the anchor row would be"); + eprintln!("summarize: unpublishable, and inventing Heddle numbers is forbidden."); + eprintln!("summarize: when that run is published: set pending = false, fill source-run"); + eprintln!("summarize: and the eight [workloads] entries from its report, then re-run."); + return ExitCode::FAILURE; + } + + let mut missing = Vec::new(); + let mut document = String::new(); + for track in TRACKS { + document.push_str(&render_table(track, &reference, &mut missing)); + } + + // Cold-parse sidebar: one aggregate Tera number, per-ecosystem only, non-comparable. + match read_estimate(COLD_GROUP, COLD_FUNCTION) { + Some(estimate) => { + document.push_str("### Tera cold parse (all templates)\n\n"); + document.push_str(&format!( + "{} - one aggregate parse of all 21 Tera template files. Per-ecosystem only, \ + not comparable across ecosystems or engines: Askama (like Heddle) has no \ + runtime parse step, it is compiled into the binary at build time.\n\n", + fmt_native(&estimate) + )); + } + None => eprintln!( + "summarize: note - no cold-parse estimate at target/criterion/{COLD_GROUP}/{COLD_FUNCTION}/new/estimates.json \ + (run `cargo bench --bench cold`); the cold-parse sidebar is omitted." + ), + } + + if !missing.is_empty() { + eprintln!("summarize: {} required input(s) missing:", missing.len()); + for item in &missing { + eprintln!("summarize: {item}"); + } + eprintln!("summarize: run the full `cargo bench --bench controlled --bench idiomatic --bench cold`"); + eprintln!("summarize: (and fill heddle-reference.toml) before pasting any table."); + print!("{document}"); + return ExitCode::FAILURE; + } + + print!("{document}"); + ExitCode::SUCCESS +} diff --git a/benchmarks/rust/src/corpus.rs b/benchmarks/rust/src/corpus.rs new file mode 100644 index 00000000..1677790a --- /dev/null +++ b/benchmarks/rust/src/corpus.rs @@ -0,0 +1,206 @@ +//! Read-only access to the golden corpus at `benchmarks/dotnet/GoldenCorpus/`, resolved +//! repo-relative from `CARGO_MANIFEST_DIR` — the corpus is committed alongside the +//! harness, so no environment configuration is needed to find it. + +use std::path::{Path, PathBuf}; + +use serde::Deserialize; + +use crate::verifier::VerifyDef; + +/// `benchmarks/rust/../dotnet/GoldenCorpus/`. +pub fn corpus_dir() -> PathBuf { + Path::new(env!("CARGO_MANIFEST_DIR")).join("../dotnet/GoldenCorpus") +} + +/// Loads `.golden.html` — the normalized oracle (stored N1–N5 form, UTF-8 no BOM, no +/// trailing newline). Error strings carry the Diagnostics table's corpus-failure shapes. +pub fn load_golden(workload: &str) -> Result { + let path = corpus_dir().join(format!("{workload}.golden.html")); + let bytes = std::fs::read(&path).map_err(|e| { + format!( + "[FAIL] corpus {workload}: cannot read {}: {e} (regenerate via the \ + export-corpus tool: dotnet run -c Release --project benchmarks/dotnet \ + -f net10.0 -- export-corpus)", + path.display() + ) + })?; + String::from_utf8(bytes) + .map_err(|_| format!("[FAIL] corpus {workload}: golden is not valid UTF-8")) +} + +/// Loads and parses `fixtures/composed-page/nav.json` — the structured nav model fixture +/// (the single composed-page data fixture, hash-recorded in the manifest's `fixtures` +/// section and exported by the same export-corpus tool). +pub fn load_nav() -> Result { + let path = corpus_dir().join("fixtures/composed-page/nav.json"); + let bytes = std::fs::read(&path).map_err(|e| { + format!( + "[FAIL] corpus composed-page: cannot read {}: {e} (regenerate via the \ + export-corpus tool: dotnet run -c Release --project benchmarks/dotnet \ + -f net10.0 -- export-corpus)", + path.display() + ) + })?; + serde_json::from_slice(&bytes) + .map_err(|e| format!("[FAIL] corpus composed-page: cannot parse nav.json: {e}")) +} + +/// Loads and parses `.verify.json` — the idiomatic-verifier definition. +pub fn load_verify(workload: &str) -> Result { + let path = corpus_dir().join(format!("{workload}.verify.json")); + let bytes = std::fs::read(&path).map_err(|e| { + format!( + "[FAIL] corpus {workload}: cannot read {}: {e} (regenerate via the \ + export-corpus tool: dotnet run -c Release --project benchmarks/dotnet \ + -f net10.0 -- export-corpus)", + path.display() + ) + })?; + serde_json::from_slice(&bytes) + .map_err(|e| format!("[FAIL] corpus {workload}: cannot parse verify.json: {e}")) +} + +// ---- manifest -------------------------------------------------------------------------------- + +#[derive(Deserialize)] +pub struct Manifest { + #[serde(rename = "$schema")] + pub schema: String, + pub generator: String, + pub entries: Vec, + /// The `fixtures` section: golden-grade hash + length rows for data fixtures — + /// currently the single composed-page `nav.json` entry. + #[serde(default)] + pub fixtures: Vec, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FixtureEntry { + pub workload: String, + pub file: String, + pub byte_length: u64, + pub hash: String, + pub generating_commit: String, + pub generated_utc: String, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ManifestEntry { + pub workload: String, + pub suite: String, + pub file: String, + pub byte_length: u64, + pub hash: String, + pub generating_commit: String, + pub generated_utc: String, +} + +/// Loads and parses `manifest.json`. +pub fn load_manifest() -> Result { + let path = corpus_dir().join("manifest.json"); + let bytes = std::fs::read(&path).map_err(|e| { + format!( + "[FAIL] corpus manifest: cannot read {}: {e}", + path.display() + ) + })?; + serde_json::from_slice(&bytes) + .map_err(|e| format!("[FAIL] corpus manifest: cannot parse manifest.json: {e}")) +} + +/// The eight workload ids in workload-number order. +pub const WORKLOADS: [&str; 8] = [ + "composed-page", + "trivial-substitution", + "large-loop", + "mixed-page", + "conditional-heavy", + "fragment-heavy", + "fortunes-encoded", + "encoded-loop", +]; + +// ---- tests ----------------------------------------------------------------------------------- + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn all_eight_goldens_load_as_utf8() { + for id in WORKLOADS { + let golden = load_golden(id).unwrap_or_else(|e| panic!("{e}")); + assert!(!golden.is_empty(), "{id} golden must be non-empty"); + } + } + + #[test] + fn all_eight_verify_definitions_load() { + for id in WORKLOADS { + let def = load_verify(id).unwrap_or_else(|e| panic!("{e}")); + assert_eq!(def.workload, id); + assert!( + def.suite == "raw" || def.suite == "encoded", + "{id}: unexpected suite {}", + def.suite + ); + assert!(!def.values.is_empty(), "{id}: values must be non-empty"); + assert!(!def.markers.is_empty(), "{id}: markers must be non-empty"); + } + } + + #[test] + fn manifest_matches_committed_files() { + let manifest = load_manifest().unwrap_or_else(|e| panic!("{e}")); + assert_eq!(manifest.entries.len(), 8); + let ordered: Vec<&str> = manifest + .entries + .iter() + .map(|e| e.workload.as_str()) + .collect(); + assert_eq!(ordered, WORKLOADS); + for entry in &manifest.entries { + let bytes = std::fs::read(corpus_dir().join(&entry.file)) + .unwrap_or_else(|e| panic!("{}: {e}", entry.file)); + assert_eq!( + bytes.len() as u64, + entry.byte_length, + "{}: byteLength mismatch", + entry.workload + ); + assert!( + entry.hash.starts_with("sha256:"), + "{}: hash shape", + entry.workload + ); + } + } + + #[test] + fn nav_fixture_loads_and_matches_its_manifest_row() { + let nav = load_nav().unwrap_or_else(|e| panic!("{e}")); + assert!(!nav.menus.is_empty(), "nav.json: menus must be non-empty"); + assert!( + !nav.footer_columns.is_empty(), + "nav.json: footer_columns must be non-empty" + ); + let manifest = load_manifest().unwrap_or_else(|e| panic!("{e}")); + let entry = manifest + .fixtures + .iter() + .find(|f| f.workload == "composed-page") + .expect("manifest fixtures: composed-page nav.json row"); + assert_eq!(entry.file, "fixtures/composed-page/nav.json"); + let bytes = std::fs::read(corpus_dir().join(&entry.file)) + .unwrap_or_else(|e| panic!("{}: {e}", entry.file)); + assert_eq!( + bytes.len() as u64, + entry.byte_length, + "nav.json: byteLength mismatch (stale fixture — re-run export-corpus)" + ); + assert!(entry.hash.starts_with("sha256:"), "nav.json: hash shape"); + } +} diff --git a/benchmarks/rust/src/engines/askama_controlled.rs b/benchmarks/rust/src/engines/askama_controlled.rs new file mode 100644 index 00000000..f90d2d5d --- /dev/null +++ b/benchmarks/rust/src/engines/askama_controlled.rs @@ -0,0 +1,231 @@ +//! Controlled-track Askama runners. Template texts are normative ports — the golden gate +//! defines their bytes, so do not re-derive or reformat them here. Escaping modes: +//! raw cells carry `escape = "none"`, encoded cells use the default `Html` +//! escaper inferred from the `.html` extension (entity spellings reconciled by N5 in the gate). +//! Askama compiles every template into the binary at build time, so "parse/compile outside +//! `render()`" holds by construction; the template structs themselves are `OnceLock` +//! singletons borrowing the shared models. + +use std::sync::OnceLock; + +use askama::Template; + +use crate::models; +use crate::models::{ + ConditionalRow, EncodedLoopRow, FortuneRow, FragmentRow, LoopRow, MixedProduct, NavModel, +}; + +// ---- composed-page (raw) --------------------------------------------------------------------- + +/// Model shape: the structured nav only — all chrome/blob text lives in the +/// templates (`composed-page-layout.html` + the `chrome/` fragment includes), and the +/// page fills the layout's live `{% block body %}` with the slider. +#[derive(Template)] +#[template(path = "controlled/askama/composed-page.html", escape = "none")] +pub struct ComposedControlled<'a> { + pub nav: &'a NavModel, +} + +pub fn composed() -> &'static ComposedControlled<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| ComposedControlled { + nav: &models::composed().nav, + }) +} + +pub fn render_composed_page() -> String { + composed() + .render() + .expect("askama controlled composed-page render") +} + +// ---- trivial-substitution (raw) -------------------------------------------------------------- + +#[derive(Template)] +#[template(path = "controlled/askama/trivial-substitution.html", escape = "none")] +pub struct SubstitutionControlled<'a> { + pub title: &'a str, + pub sku: &'a str, + pub price: i32, + pub brand: &'a str, + pub category: &'a str, + pub availability: &'a str, + pub url: &'a str, + pub image_url: &'a str, + pub summary: &'a str, + pub rating: &'a str, +} + +pub fn substitution() -> &'static SubstitutionControlled<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| { + let m = models::substitution(); + SubstitutionControlled { + title: m.title, + sku: m.sku, + price: m.price, + brand: m.brand, + category: m.category, + availability: m.availability, + url: m.url, + image_url: m.image_url, + summary: m.summary, + rating: m.rating, + } + }) +} + +pub fn render_trivial_substitution() -> String { + substitution() + .render() + .expect("askama controlled trivial-substitution render") +} + +// ---- large-loop (raw) ------------------------------------------------------------------------ + +#[derive(Template)] +#[template(path = "controlled/askama/large-loop.html", escape = "none")] +pub struct LargeLoopControlled<'a> { + pub items: &'a [LoopRow], +} + +pub fn large_loop() -> &'static LargeLoopControlled<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| LargeLoopControlled { + items: models::large_loop(), + }) +} + +pub fn render_large_loop() -> String { + large_loop() + .render() + .expect("askama controlled large-loop render") +} + +// ---- mixed-page (raw) ------------------------------------------------------------------------ + +#[derive(Template)] +#[template(path = "controlled/askama/mixed-page.html", escape = "none")] +pub struct MixedControlled<'a> { + pub page_title: &'a str, + pub store_name: &'a str, + pub hero_heading: &'a str, + pub hero_tagline: &'a str, + pub show_banner: bool, + pub banner_text: &'a str, + pub show_debug_panel: bool, + pub footer_note: &'a str, + pub year: i32, + pub support_email: &'a str, + pub products: &'a [MixedProduct], +} + +pub fn mixed() -> &'static MixedControlled<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| { + let m = models::mixed(); + MixedControlled { + page_title: m.page_title, + store_name: m.store_name, + hero_heading: m.hero_heading, + hero_tagline: m.hero_tagline, + show_banner: m.show_banner, + banner_text: m.banner_text, + show_debug_panel: m.show_debug_panel, + footer_note: m.footer_note, + year: m.year, + support_email: m.support_email, + products: &m.products, + } + }) +} + +pub fn render_mixed_page() -> String { + mixed() + .render() + .expect("askama controlled mixed-page render") +} + +// ---- conditional-heavy (raw) ----------------------------------------------------------------- + +#[derive(Template)] +#[template(path = "controlled/askama/conditional-heavy.html", escape = "none")] +pub struct ConditionalControlled<'a> { + pub rows: &'a [ConditionalRow], +} + +pub fn conditional() -> &'static ConditionalControlled<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| ConditionalControlled { + rows: models::conditional(), + }) +} + +pub fn render_conditional_heavy() -> String { + conditional() + .render() + .expect("askama controlled conditional-heavy render") +} + +// ---- fragment-heavy (raw) -------------------------------------------------------------------- + +#[derive(Template)] +#[template(path = "controlled/askama/fragment-heavy.html", escape = "none")] +pub struct FragmentControlled<'a> { + pub items: &'a [FragmentRow], +} + +pub fn fragment() -> &'static FragmentControlled<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| FragmentControlled { + items: models::fragment(), + }) +} + +pub fn render_fragment_heavy() -> String { + fragment() + .render() + .expect("askama controlled fragment-heavy render") +} + +// ---- fortunes-encoded (encoded — default Html escaper, no `escape` override) ----------------- + +#[derive(Template)] +#[template(path = "controlled/askama/fortunes-encoded.html")] +pub struct FortunesControlled<'a> { + pub rows: &'a [FortuneRow], +} + +pub fn fortunes() -> &'static FortunesControlled<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| FortunesControlled { + rows: models::fortunes(), + }) +} + +pub fn render_fortunes_encoded() -> String { + fortunes() + .render() + .expect("askama controlled fortunes-encoded render") +} + +// ---- encoded-loop (encoded — default Html escaper, no `escape` override) --------------------- + +#[derive(Template)] +#[template(path = "controlled/askama/encoded-loop.html")] +pub struct EncodedLoopControlled<'a> { + pub items: &'a [EncodedLoopRow], +} + +pub fn encoded_loop() -> &'static EncodedLoopControlled<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| EncodedLoopControlled { + items: models::encoded_loop(), + }) +} + +pub fn render_encoded_loop() -> String { + encoded_loop() + .render() + .expect("askama controlled encoded-loop render") +} diff --git a/benchmarks/rust/src/engines/askama_idiomatic.rs b/benchmarks/rust/src/engines/askama_idiomatic.rs new file mode 100644 index 00000000..0b06a839 --- /dev/null +++ b/benchmarks/rust/src/engines/askama_idiomatic.rs @@ -0,0 +1,248 @@ +//! Idiomatic-track Askama runners. Every template file carries a header comment citing +//! the official Askama 0.16 book pages its patterns follow: *Getting started* / +//! *Creating templates* (derive structs with `#[template(path = …)]`), *Template syntax — +//! Template inheritance* (composed-page's layout + live body block), *Template syntax — +//! For / If / Include*, and *Filters — escape* (default `Html` escaper everywhere — no +//! `escape` override on any struct). No `|safe` filter appears +//! anywhere: the inert chrome is literal template text, which Askama trusts +//! natively, and every raw-suite model value contains no characters HTML escaping +//! rewrites, so default escaping is a byte-level no-op. Askama compiles templates at +//! build time, so parse/compile sits outside every `render()`; the structs are +//! `OnceLock` singletons borrowing the shared models. + +use std::sync::OnceLock; + +use askama::Template; + +use crate::models; +use crate::models::{ + ConditionalRow, EncodedLoopRow, FortuneRow, FragmentRow, LoopRow, MixedProduct, NavModel, +}; + +// ---- composed-page (raw; native inheritance layout with a live body block) ------------------- +// Doc citations: Askama book *Template syntax — Template inheritance* (the page extends +// `composed-page-layout.html` and fills `{% block body %}` with the slider), *Include* +// (the ten chrome-fragment partials + the nested nav-family partials), *For* / *If* +// (nav loops over menus/tabs/columns/sections/links; `has_dropdown` / `title_linked`). + +/// Model shape: the structured nav only — the chrome and the spliced body are +/// literal template text. +#[derive(Template)] +#[template(path = "idiomatic/askama/composed-page.html")] +pub struct ComposedIdiomatic<'a> { + pub nav: &'a NavModel, +} + +pub fn composed() -> &'static ComposedIdiomatic<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| ComposedIdiomatic { + nav: &models::composed().nav, + }) +} + +pub fn render_composed_page() -> String { + composed() + .render() + .expect("askama idiomatic composed-page render") +} + +// ---- trivial-substitution (raw) -------------------------------------------------------------- +// Doc citations: Askama book *Getting started*, *Creating templates*. + +#[derive(Template)] +#[template(path = "idiomatic/askama/trivial-substitution.html")] +pub struct SubstitutionIdiomatic<'a> { + pub title: &'a str, + pub sku: &'a str, + pub price: i32, + pub brand: &'a str, + pub category: &'a str, + pub availability: &'a str, + pub url: &'a str, + pub image_url: &'a str, + pub summary: &'a str, + pub rating: &'a str, +} + +pub fn substitution() -> &'static SubstitutionIdiomatic<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| { + let m = models::substitution(); + SubstitutionIdiomatic { + title: m.title, + sku: m.sku, + price: m.price, + brand: m.brand, + category: m.category, + availability: m.availability, + url: m.url, + image_url: m.image_url, + summary: m.summary, + rating: m.rating, + } + }) +} + +pub fn render_trivial_substitution() -> String { + substitution() + .render() + .expect("askama idiomatic trivial-substitution render") +} + +// ---- large-loop (raw) ------------------------------------------------------------------------ +// Doc citations: Askama book *Template syntax — For*. + +#[derive(Template)] +#[template(path = "idiomatic/askama/large-loop.html")] +pub struct LargeLoopIdiomatic<'a> { + pub items: &'a [LoopRow], +} + +pub fn large_loop() -> &'static LargeLoopIdiomatic<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| LargeLoopIdiomatic { + items: models::large_loop(), + }) +} + +pub fn render_large_loop() -> String { + large_loop() + .render() + .expect("askama idiomatic large-loop render") +} + +// ---- mixed-page (raw; SINGLE-FILE by rule — layout composition is +// composed-page's dimension) ------------------------------------------------------------------- +// Doc citations: Askama book *Creating templates*, *Template syntax — For*, *If*. + +#[derive(Template)] +#[template(path = "idiomatic/askama/mixed-page.html")] +pub struct MixedIdiomatic<'a> { + pub page_title: &'a str, + pub store_name: &'a str, + pub hero_heading: &'a str, + pub hero_tagline: &'a str, + pub show_banner: bool, + pub banner_text: &'a str, + pub show_debug_panel: bool, + pub footer_note: &'a str, + pub year: i32, + pub support_email: &'a str, + pub products: &'a [MixedProduct], +} + +pub fn mixed() -> &'static MixedIdiomatic<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| { + let m = models::mixed(); + MixedIdiomatic { + page_title: m.page_title, + store_name: m.store_name, + hero_heading: m.hero_heading, + hero_tagline: m.hero_tagline, + show_banner: m.show_banner, + banner_text: m.banner_text, + show_debug_panel: m.show_debug_panel, + footer_note: m.footer_note, + year: m.year, + support_email: m.support_email, + products: &m.products, + } + }) +} + +pub fn render_mixed_page() -> String { + mixed() + .render() + .expect("askama idiomatic mixed-page render") +} + +// ---- conditional-heavy (raw) ----------------------------------------------------------------- +// Doc citations: Askama book *Template syntax — If*, *For*. + +#[derive(Template)] +#[template(path = "idiomatic/askama/conditional-heavy.html")] +pub struct ConditionalIdiomatic<'a> { + pub rows: &'a [ConditionalRow], +} + +pub fn conditional() -> &'static ConditionalIdiomatic<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| ConditionalIdiomatic { + rows: models::conditional(), + }) +} + +pub fn render_conditional_heavy() -> String { + conditional() + .render() + .expect("askama idiomatic conditional-heavy render") +} + +// ---- fragment-heavy (raw; per-row four-way dispatch to per-kind partials, one nesting +// level: card -> badge + price against the row's promo) ---------------------------------------- +// Doc citations: Askama book *Template syntax — If* (if/elif/else dispatch chain), +// *Include*, *For*. + +#[derive(Template)] +#[template(path = "idiomatic/askama/fragment-heavy.html")] +pub struct FragmentIdiomatic<'a> { + pub items: &'a [FragmentRow], +} + +pub fn fragment() -> &'static FragmentIdiomatic<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| FragmentIdiomatic { + items: models::fragment(), + }) +} + +pub fn render_fragment_heavy() -> String { + fragment() + .render() + .expect("askama idiomatic fragment-heavy render") +} + +// ---- fortunes-encoded (encoded — default Html escaper, no filters) --------------------------- +// Doc citations: Askama book *Filters — escape*, *Template syntax — For*. + +#[derive(Template)] +#[template(path = "idiomatic/askama/fortunes-encoded.html")] +pub struct FortunesIdiomatic<'a> { + pub rows: &'a [FortuneRow], +} + +pub fn fortunes() -> &'static FortunesIdiomatic<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| FortunesIdiomatic { + rows: models::fortunes(), + }) +} + +pub fn render_fortunes_encoded() -> String { + fortunes() + .render() + .expect("askama idiomatic fortunes-encoded render") +} + +// ---- encoded-loop (encoded — default Html escaper, no filters) ------------------------------- +// Doc citations: Askama book *Filters — escape*, *Template syntax — For*. + +#[derive(Template)] +#[template(path = "idiomatic/askama/encoded-loop.html")] +pub struct EncodedLoopIdiomatic<'a> { + pub items: &'a [EncodedLoopRow], +} + +pub fn encoded_loop() -> &'static EncodedLoopIdiomatic<'static> { + static RUNNER: OnceLock> = OnceLock::new(); + RUNNER.get_or_init(|| EncodedLoopIdiomatic { + items: models::encoded_loop(), + }) +} + +pub fn render_encoded_loop() -> String { + encoded_loop() + .render() + .expect("askama idiomatic encoded-loop render") +} diff --git a/benchmarks/rust/src/engines/mod.rs b/benchmarks/rust/src/engines/mod.rs new file mode 100644 index 00000000..b8c304aa --- /dev/null +++ b/benchmarks/rust/src/engines/mod.rs @@ -0,0 +1,4 @@ +pub mod askama_controlled; +pub mod askama_idiomatic; +pub mod tera_controlled; +pub mod tera_idiomatic; diff --git a/benchmarks/rust/src/engines/tera_controlled.rs b/benchmarks/rust/src/engines/tera_controlled.rs new file mode 100644 index 00000000..5c0a6ca3 --- /dev/null +++ b/benchmarks/rust/src/engines/tera_controlled.rs @@ -0,0 +1,210 @@ +//! Controlled-track Tera runners. Template texts are normative ports — the golden gate +//! defines their bytes, so do not re-derive or reformat them here. Escaping modes are +//! split across TWO `OnceLock` instances: `tera_controlled_raw` with +//! `autoescape_on(std::iter::empty::<&str>())` (the documented disable form) and +//! `tera_controlled_encoded` with default autoescape (template names end `.html`). +//! Templates are registered with `add_template_file` and contexts are built once, so +//! parse/compile sits outside every `render()`. + +use std::path::Path; +use std::sync::OnceLock; + +use tera::{Context, Tera}; + +use crate::models; + +// ---- instances ------------------------------------------------------------------------------- + +const RAW_TEMPLATES: [&str; 27] = [ + // composed-page: chrome-fragment includes, the nested nav partial chain, + // the base layout with the live body block, and the extending child page. + "controlled/tera/chrome/alert-top.html", + "controlled/tera/chrome/secondary-wholesale-menu.html", + "controlled/tera/chrome/secondary-retail-menu.html", + "controlled/tera/chrome/alert-below.html", + "controlled/tera/chrome/assets-styles.html", + "controlled/tera/chrome/assets-scripts.html", + "controlled/tera/chrome/custom-styles.html", + "controlled/tera/chrome/head-scripts.html", + "controlled/tera/chrome/body-scripts.html", + "controlled/tera/chrome/body-end-scripts.html", + "controlled/tera/nav/link.html", + "controlled/tera/nav/section.html", + "controlled/tera/nav/column.html", + "controlled/tera/nav/mega-menu.html", + "controlled/tera/shared/composed-page-layout.html", + "controlled/tera/composed-page.html", + "controlled/tera/trivial-substitution.html", + "controlled/tera/large-loop.html", + "controlled/tera/mixed-page.html", + "controlled/tera/conditional-heavy.html", + // fragment-heavy: four dispatched per-kind partials plus the card's two + // sub-partials, then the dispatching main template. + "controlled/tera/shared/fragment-heavy-tile.html", + "controlled/tera/shared/fragment-heavy-badge.html", + "controlled/tera/shared/fragment-heavy-price.html", + "controlled/tera/shared/fragment-heavy-card.html", + "controlled/tera/shared/fragment-heavy-media-row.html", + "controlled/tera/shared/fragment-heavy-stat.html", + "controlled/tera/fragment-heavy.html", +]; + +const ENCODED_TEMPLATES: [&str; 2] = [ + "controlled/tera/fortunes-encoded.html", + "controlled/tera/encoded-loop.html", +]; + +fn build_instance(names: &[&str], autoescape_off: bool) -> Tera { + let mut tera = Tera::default(); + if autoescape_off { + tera.autoescape_on(std::iter::empty::<&str>()); + } + let base = Path::new(env!("CARGO_MANIFEST_DIR")).join("templates"); + for name in names { + tera.add_template_file(base.join(name), Some(name)) + .unwrap_or_else(|e| panic!("tera controlled: cannot register {name}: {e}")); + } + tera +} + +/// Cold-parse support: a fresh raw instance parsing the same 27 template files +/// the runtime `tera_controlled_raw` instance holds. +pub fn build_fresh_raw() -> Tera { + build_instance(&RAW_TEMPLATES, true) +} + +/// Cold-parse support: a fresh encoded instance parsing the same 2 template +/// files the runtime `tera_controlled_encoded` instance holds. +pub fn build_fresh_encoded() -> Tera { + build_instance(&ENCODED_TEMPLATES, false) +} + +/// The controlled-raw instance — autoescape fully off. +pub fn tera_controlled_raw() -> &'static Tera { + static TERA: OnceLock = OnceLock::new(); + TERA.get_or_init(|| build_instance(&RAW_TEMPLATES, true)) +} + +/// The controlled-encoded instance — default autoescape on `.html` names. +pub fn tera_controlled_encoded() -> &'static Tera { + static TERA: OnceLock = OnceLock::new(); + TERA.get_or_init(|| build_instance(&ENCODED_TEMPLATES, false)) +} + +// ---- contexts (built once from the shared models) -------------------------------------------- + +fn composed_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + Context::from_serialize(models::composed()).expect("tera composed-page context") + }) +} + +fn substitution_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + Context::from_serialize(models::substitution()).expect("tera trivial-substitution context") + }) +} + +fn large_loop_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + let mut ctx = Context::new(); + ctx.insert("items", models::large_loop()); + ctx + }) +} + +fn mixed_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| Context::from_serialize(models::mixed()).expect("tera mixed-page context")) +} + +fn conditional_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + let mut ctx = Context::new(); + ctx.insert("rows", models::conditional()); + ctx + }) +} + +fn fragment_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + let mut ctx = Context::new(); + ctx.insert("items", models::fragment()); + ctx + }) +} + +fn fortunes_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + let mut ctx = Context::new(); + ctx.insert("rows", models::fortunes()); + ctx + }) +} + +fn encoded_loop_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + let mut ctx = Context::new(); + ctx.insert("items", models::encoded_loop()); + ctx + }) +} + +// ---- render fns ------------------------------------------------------------------------------ + +fn render_raw(name: &str, ctx: &Context) -> String { + tera_controlled_raw() + .render(name, ctx) + .unwrap_or_else(|e| panic!("tera controlled raw {name} render: {e}")) +} + +fn render_encoded(name: &str, ctx: &Context) -> String { + tera_controlled_encoded() + .render(name, ctx) + .unwrap_or_else(|e| panic!("tera controlled encoded {name} render: {e}")) +} + +pub fn render_composed_page() -> String { + render_raw("controlled/tera/composed-page.html", composed_context()) +} + +pub fn render_trivial_substitution() -> String { + render_raw( + "controlled/tera/trivial-substitution.html", + substitution_context(), + ) +} + +pub fn render_large_loop() -> String { + render_raw("controlled/tera/large-loop.html", large_loop_context()) +} + +pub fn render_mixed_page() -> String { + render_raw("controlled/tera/mixed-page.html", mixed_context()) +} + +pub fn render_conditional_heavy() -> String { + render_raw( + "controlled/tera/conditional-heavy.html", + conditional_context(), + ) +} + +pub fn render_fragment_heavy() -> String { + render_raw("controlled/tera/fragment-heavy.html", fragment_context()) +} + +pub fn render_fortunes_encoded() -> String { + render_encoded("controlled/tera/fortunes-encoded.html", fortunes_context()) +} + +pub fn render_encoded_loop() -> String { + render_encoded("controlled/tera/encoded-loop.html", encoded_loop_context()) +} diff --git a/benchmarks/rust/src/engines/tera_idiomatic.rs b/benchmarks/rust/src/engines/tera_idiomatic.rs new file mode 100644 index 00000000..1026e9e5 --- /dev/null +++ b/benchmarks/rust/src/engines/tera_idiomatic.rs @@ -0,0 +1,193 @@ +//! Idiomatic-track Tera runners. Every template file carries a header comment citing the +//! official Tera docs (keats.github.io/tera) pages its patterns follow: *Getting +//! started* (one `Tera` instance holding the parsed template set), *Inheritance* +//! (composed-page — base with a live body block; mixed-page is single-file by rule — +//! layout composition is composed-page's dimension), *Control structures* (for / if), +//! *Include* (composed-page chrome fragments + nested nav partials, fragment-heavy +//! per-kind partials) and *Auto-escaping* (ONE default-escaping instance — `.html` names +//! keep autoescape on; no `safe` filter anywhere — the inert chrome is literal template +//! text, and every raw-suite substitution contains no characters HTML escaping rewrites, +//! so default escaping is byte-neutral). +//! Templates are registered with `add_template_file` and contexts built once, so +//! parse/compile sits outside every `render()`. + +use std::path::Path; +use std::sync::OnceLock; + +use tera::{Context, Tera}; + +use crate::models; + +// ---- the single default-escaping idiomatic instance ------------------------------------------ + +const IDIOMATIC_TEMPLATES: [&str; 29] = [ + // composed-page: chrome-fragment includes, the nested nav partial chain, + // the base layout with the live body block, and the extending child page. + "idiomatic/tera/chrome/alert-top.html", + "idiomatic/tera/chrome/secondary-wholesale-menu.html", + "idiomatic/tera/chrome/secondary-retail-menu.html", + "idiomatic/tera/chrome/alert-below.html", + "idiomatic/tera/chrome/assets-styles.html", + "idiomatic/tera/chrome/assets-scripts.html", + "idiomatic/tera/chrome/custom-styles.html", + "idiomatic/tera/chrome/head-scripts.html", + "idiomatic/tera/chrome/body-scripts.html", + "idiomatic/tera/chrome/body-end-scripts.html", + "idiomatic/tera/nav/link.html", + "idiomatic/tera/nav/section.html", + "idiomatic/tera/nav/column.html", + "idiomatic/tera/nav/mega-menu.html", + "idiomatic/tera/shared/composed-page-base.html", + "idiomatic/tera/composed-page.html", + "idiomatic/tera/trivial-substitution.html", + "idiomatic/tera/large-loop.html", + // mixed-page is single-file by rule — layout composition is + // composed-page's dimension. + "idiomatic/tera/mixed-page.html", + "idiomatic/tera/conditional-heavy.html", + // fragment-heavy: four dispatched per-kind partials plus the card's two + // sub-partials, then the dispatching main template. + "idiomatic/tera/shared/fragment-heavy-tile.html", + "idiomatic/tera/shared/fragment-heavy-badge.html", + "idiomatic/tera/shared/fragment-heavy-price.html", + "idiomatic/tera/shared/fragment-heavy-card.html", + "idiomatic/tera/shared/fragment-heavy-media-row.html", + "idiomatic/tera/shared/fragment-heavy-stat.html", + "idiomatic/tera/fragment-heavy.html", + "idiomatic/tera/fortunes-encoded.html", + "idiomatic/tera/encoded-loop.html", +]; + +/// The idiomatic instance — default autoescape (on for `.html` names — the documented +/// practitioner posture). +pub fn tera_idiomatic() -> &'static Tera { + static TERA: OnceLock = OnceLock::new(); + TERA.get_or_init(build_fresh) +} + +/// Cold-parse support: a fresh instance parsing the same 29 template files the +/// runtime `tera_idiomatic` instance holds. +pub fn build_fresh() -> Tera { + let mut tera = Tera::default(); + let base = Path::new(env!("CARGO_MANIFEST_DIR")).join("templates"); + for name in IDIOMATIC_TEMPLATES { + tera.add_template_file(base.join(name), Some(name)) + .unwrap_or_else(|e| panic!("tera idiomatic: cannot register {name}: {e}")); + } + tera +} + +// ---- contexts (built once from the shared models) -------------------------------------------- + +fn composed_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + Context::from_serialize(models::composed()).expect("tera idiomatic composed-page context") + }) +} + +fn substitution_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + Context::from_serialize(models::substitution()) + .expect("tera idiomatic trivial-substitution context") + }) +} + +fn large_loop_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + let mut ctx = Context::new(); + ctx.insert("items", models::large_loop()); + ctx + }) +} + +fn mixed_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + Context::from_serialize(models::mixed()).expect("tera idiomatic mixed-page context") + }) +} + +fn conditional_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + let mut ctx = Context::new(); + ctx.insert("rows", models::conditional()); + ctx + }) +} + +fn fragment_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + let mut ctx = Context::new(); + ctx.insert("items", models::fragment()); + ctx + }) +} + +fn fortunes_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + let mut ctx = Context::new(); + ctx.insert("rows", models::fortunes()); + ctx + }) +} + +fn encoded_loop_context() -> &'static Context { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + let mut ctx = Context::new(); + ctx.insert("items", models::encoded_loop()); + ctx + }) +} + +// ---- render fns ------------------------------------------------------------------------------ + +fn render(name: &str, ctx: &Context) -> String { + tera_idiomatic() + .render(name, ctx) + .unwrap_or_else(|e| panic!("tera idiomatic {name} render: {e}")) +} + +pub fn render_composed_page() -> String { + render("idiomatic/tera/composed-page.html", composed_context()) +} + +pub fn render_trivial_substitution() -> String { + render( + "idiomatic/tera/trivial-substitution.html", + substitution_context(), + ) +} + +pub fn render_large_loop() -> String { + render("idiomatic/tera/large-loop.html", large_loop_context()) +} + +pub fn render_mixed_page() -> String { + render("idiomatic/tera/mixed-page.html", mixed_context()) +} + +pub fn render_conditional_heavy() -> String { + render( + "idiomatic/tera/conditional-heavy.html", + conditional_context(), + ) +} + +pub fn render_fragment_heavy() -> String { + render("idiomatic/tera/fragment-heavy.html", fragment_context()) +} + +pub fn render_fortunes_encoded() -> String { + render("idiomatic/tera/fortunes-encoded.html", fortunes_context()) +} + +pub fn render_encoded_loop() -> String { + render("idiomatic/tera/encoded-loop.html", encoded_loop_context()) +} diff --git a/benchmarks/rust/src/gates.rs b/benchmarks/rust/src/gates.rs new file mode 100644 index 00000000..743cdf60 --- /dev/null +++ b/benchmarks/rust/src/gates.rs @@ -0,0 +1,463 @@ +//! Parity gates — the cell registry and the `assert_controlled` / `assert_idiomatic` / +//! `assert_all` surface. The controlled gate per cell: load the golden → +//! render → normalize (N1–N4, +N5 for encoded) → N3b-strip both sides → byte compare; +//! encoded cells additionally assert the security floor (raw `", + "フレームワークのベンチマーク", +]; + +#[derive(Serialize)] +pub struct FortuneRow { + pub id: i32, + pub message: &'static str, +} + +pub fn fortunes() -> &'static Vec { + static MODEL: OnceLock> = OnceLock::new(); + MODEL.get_or_init(|| { + FORTUNE_MESSAGES + .iter() + .enumerate() + .map(|(i, message)| FortuneRow { + id: i as i32 + 1, + message, + }) + .collect() + }) +} + +// ---- encoded-loop ---------------------------------------------------------------------------- + +#[derive(Serialize)] +pub struct EncodedLoopRow { + pub tag: String, + pub name: String, + pub comment: String, +} + +pub fn encoded_loop() -> &'static Vec { + static MODEL: OnceLock> = OnceLock::new(); + MODEL.get_or_init(|| { + (0..5000) + .map(|i: i32| EncodedLoopRow { + tag: format!("tag-{i}&'{}'", i % 7), + name: format!("item <{i}> & \"co\""), + comment: format!("'q' & \"d\" こんにちは {i}"), + }) + .collect() + }) +} + +// ---- tests (model pins; expected counts restated as literals) -------------------------------- + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn large_loop_has_5000_rows_with_pinned_edges() { + let rows = large_loop(); + assert_eq!(rows.len(), 5000); + // Value only — the display name `row-{i}` is template-composed. + assert_eq!(rows[0].value, 0); + assert_eq!(rows[2500].value, 2500); + assert_eq!(rows[4999].value, 4999); + } + + #[test] + fn conditional_has_200_rows_with_pinned_distributions() { + let rows = conditional(); + assert_eq!(rows.len(), 200); + assert_eq!(rows.iter().filter(|r| r.is_bronze).count(), 50); + assert_eq!(rows.iter().filter(|r| r.is_silver).count(), 50); + assert_eq!(rows.iter().filter(|r| r.is_gold).count(), 50); + assert_eq!( + rows.iter() + .filter(|r| !r.is_bronze && !r.is_silver && !r.is_gold) + .count(), + 50 + ); + assert_eq!(rows.iter().filter(|r| r.has_note).count(), 100); + assert_eq!(rows.iter().filter(|r| r.is_active).count(), 160); + assert_eq!(rows[0].name, "unit-000"); + assert_eq!(rows[199].name, "unit-199"); + // The int seq replaces the note string (`note {i}` is template-composed). + assert_eq!(rows[7].seq, 7); + assert_eq!(rows[199].seq, 199); + } + + #[test] + fn fragment_has_48_rows_with_pinned_dispatch_and_nesting() { + let rows = fragment(); + assert_eq!(rows.len(), 48); + // Identity/value pins. + assert_eq!(rows[0].name, "item-00"); + assert_eq!(rows[47].name, "item-47"); + assert_eq!(rows[47].value, 47 * 11); + assert_eq!(rows.iter().filter(|r| r.badge == "new").count(), 12); + assert_eq!(rows[1].badge, "hot"); + // Dispatch cycle: 12 of each kind, booleans precomputed and consistent with `kind`. + for k in ["tile", "card", "media", "stat"] { + assert_eq!(rows.iter().filter(|r| r.kind == k).count(), 12); + } + assert!(rows[0].is_tile && rows[1].is_card && rows[2].is_media && rows[3].is_stat); + for r in rows { + let flags = [r.is_tile, r.is_card, r.is_media, r.is_stat] + .iter() + .filter(|&&b| b) + .count(); + assert_eq!(flags, 1, "{}: exactly one kind boolean", r.name); + let expected = + [r.is_tile, r.is_card, r.is_media, r.is_stat][["tile", "card", "media", "stat"] + .iter() + .position(|k| *k == r.kind) + .unwrap()]; + assert!(expected, "{}: kind/boolean mismatch", r.name); + // The one nesting level: promo on EVERY row, label == badge, price = 9 + i. + assert_eq!(r.promo.label, r.badge); + } + // Delta and promo-price pins: i = 0 → -3 / 9; i = 47 → 47 % 7 - 3 = 2 / 56. + assert_eq!(rows[0].delta, -3); + assert_eq!(rows[0].promo.price, 9); + assert_eq!(rows[47].delta, 2); + assert_eq!(rows[47].promo.price, 56); + } + + #[test] + fn mixed_has_36_products_with_12_on_sale() { + let model = mixed(); + assert_eq!(model.products.len(), 36); + assert_eq!(model.products.iter().filter(|p| p.on_sale).count(), 12); + assert_eq!(model.page_title, "Mercantile - Catalog"); + assert_eq!(model.support_email, "support at mercantile.example"); + assert!(model.show_banner); + assert!(!model.show_debug_panel); + assert_eq!(model.year, 2026); + assert_eq!(model.products[0].name, "Product 01"); + // Ints replace the sku/blurb strings (`MX-{n}` / the blurb sentence are + // template-composed). + assert_eq!(model.products[0].sku_number, 1001); + assert_eq!(model.products[0].batch, 1); + assert_eq!(model.products[35].name, "Product 36"); + assert_eq!(model.products[35].sku_number, 1036); + assert_eq!(model.products[35].batch, 36); + assert_eq!(model.products[35].price, 950 + 36 * 7); + } + + #[test] + fn fortunes_has_12_pinned_rows() { + let rows = fortunes(); + assert_eq!(rows.len(), 12); + assert_eq!(rows[0].id, 1); + assert_eq!(rows[11].id, 12); + // Row 11: the exact XSS payload string. + assert_eq!( + rows[10].message, + "" + ); + // Row 12: the Japanese string. + assert_eq!(rows[11].message, "フレームワークのベンチマーク"); + // Rows 4/8 em dashes are U+2014. + assert!(rows[3].message.contains('\u{2014}')); + assert!(rows[7].message.contains('\u{2014}')); + assert_eq!(rows[2].message.matches('\'').count(), 1); + } + + #[test] + fn encoded_loop_has_5000_rows_with_pinned_row_0() { + let rows = encoded_loop(); + assert_eq!(rows.len(), 5000); + assert_eq!(rows[0].tag, "tag-0&'0'"); + assert_eq!(rows[0].name, "item <0> & \"co\""); + assert_eq!(rows[0].comment, "'q' & \"d\" こんにちは 0"); + assert_eq!(rows[4999].tag, "tag-4999&'1'"); + } + + #[test] + fn substitution_pins() { + let model = substitution(); + assert_eq!(model.title, "Heddle Handbook"); + assert_eq!(model.sku, "HB-2001"); + assert_eq!(model.price, 4200); + assert_eq!(model.summary, "A concise field guide to the engine."); + assert_eq!(model.rating, "4.8"); + } + + #[test] + fn composed_nav_loads_from_the_corpus_fixture_with_pinned_counts() { + let nav = &composed().nav; + // Two mega menus of six tabs each; four footer columns. + assert_eq!(nav.menus.len(), 2); + for menu in &nav.menus { + assert_eq!(menu.tabs.len(), 6); + } + assert_eq!(nav.footer_columns.len(), 4); + // 12 dropdown tabs; 32 menu columns + 4 footer columns = 36; 220 + 25 = 245 links — + // the counts the verifier derives from this same model. + assert_eq!( + nav.menus + .iter() + .flat_map(|m| &m.tabs) + .filter(|t| t.has_dropdown) + .count(), + 12 + ); + let menu_columns: usize = nav + .menus + .iter() + .flat_map(|m| &m.tabs) + .map(|t| t.columns.len()) + .sum(); + assert_eq!(menu_columns + nav.footer_columns.len(), 36); + let menu_links: usize = nav + .menus + .iter() + .flat_map(|m| &m.tabs) + .flat_map(|t| &t.columns) + .flat_map(|c| &c.sections) + .map(|s| s.links.len()) + .sum(); + let footer_links: usize = nav + .footer_columns + .iter() + .flat_map(|c| &c.sections) + .map(|s| s.links.len()) + .sum(); + assert_eq!(menu_links + footer_links, 245); + // Pinned entries: the first tab and the footer's unique privacy deep link. + let tab0 = &nav.menus[0].tabs[0]; + assert_eq!(tab0.label, "Shop All Products"); + assert_eq!(tab0.css, "shop-all-products"); + assert!(tab0.has_dropdown); + assert_eq!(tab0.dropdown_css, "dropdown_2columns"); + assert_eq!(nav.footer_columns[0].sections[0].title, "Need Help?"); + let privacy: Vec<&NavLink> = nav + .footer_columns + .iter() + .flat_map(|c| &c.sections) + .flat_map(|s| &s.links) + .filter(|l| l.href == "/content/privacy-policy") + .collect(); + assert_eq!(privacy.len(), 1); + assert_eq!(privacy[0].label, "Privacy Policy"); + } + + #[test] + fn composed_nav_values_are_escaping_neutral() { + // Sanitization pin: every nav text value is ASCII with none of + // `& < > " '` — raw and would-be-escaped renderings coincide on every engine. + fn assert_clean(context: &str, s: &str) { + assert!( + s.is_ascii() && !s.contains(['&', '<', '>', '"', '\'']), + "sanitization violation in {context}: {s:?}" + ); + } + fn check_column(col: &NavColumn) { + for s in &col.sections { + assert_clean("section title", &s.title); + assert_clean("section href", &s.href); + for l in &s.links { + assert_clean("link label", &l.label); + assert_clean("link href", &l.href); + } + } + } + let nav = &composed().nav; + for tab in nav.menus.iter().flat_map(|m| &m.tabs) { + assert_clean("tab label", &tab.label); + assert_clean("tab href", &tab.href); + assert_clean("tab css", &tab.css); + assert_clean("tab dropdown_css", &tab.dropdown_css); + tab.columns.iter().for_each(check_column); + } + nav.footer_columns.iter().for_each(check_column); + } +} diff --git a/benchmarks/rust/src/normalize.rs b/benchmarks/rust/src/normalize.rs new file mode 100644 index 00000000..061980ae --- /dev/null +++ b/benchmarks/rust/src/normalize.rs @@ -0,0 +1,267 @@ +//! Parity-contract normalization pipeline (N1–N5), hand-rolled deliberately — no regex +//! dependency. *Whitespace* is exactly the six-character set +//! `{ TAB, LF, VT, FF, CR, SPACE }` (the contract's closed, portable definition — never a +//! language `\s`). N1 (UTF-8 decode) is inherent: engine output is a Rust `String`, and the +//! corpus loader fails on invalid UTF-8 (`corpus.rs`). + +/// The contract's six-character whitespace set — TAB, LF, VT, FF, CR, SPACE. +#[inline] +pub fn is_contract_whitespace(byte: u8) -> bool { + matches!(byte, b'\t' | b'\n' | 0x0B | 0x0C | b'\r' | b' ') +} + +/// N2 — line endings: every `\r\n` becomes `\n`, then every remaining `\r` becomes `\n`. +pub fn n2_line_endings(s: &str) -> String { + s.replace("\r\n", "\n").replace('\r', "\n") +} + +/// N3 — inter-tag whitespace: collapse every run of one-or-more whitespace characters that +/// sits between `>` and `<` to nothing. Single left-to-right scan; equivalent to the +/// contract's repeated-regex definition because the replacement `><` contains no whitespace. +pub fn n3_inter_tag(s: &str) -> String { + let bytes = s.as_bytes(); + let mut out = Vec::with_capacity(bytes.len()); + let mut i = 0; + while i < bytes.len() { + let b = bytes[i]; + out.push(b); + i += 1; + if b == b'>' { + let mut j = i; + while j < bytes.len() && is_contract_whitespace(bytes[j]) { + j += 1; + } + if j > i && j < bytes.len() && bytes[j] == b'<' { + i = j; // erase the run; the `<` is copied on the next iteration + } + } + } + // Only ASCII whitespace bytes were removed, so the result is valid UTF-8. + String::from_utf8(out).expect("N3 removes only ASCII bytes") +} + +/// N3b — comparison-time whitespace-run collapse: remove **every** run of one-or-more +/// whitespace characters, anywhere in the text, to **nothing** (not to a space). Applied +/// symmetrically to both sides of every comparison and to every verifier needle; never baked +/// into the stored oracle (2026-07-20 maintainer step). +pub fn n3b_strip(s: &str) -> String { + // Removing every whitespace character removes every run entirely. + let bytes: Vec = s.bytes().filter(|&b| !is_contract_whitespace(b)).collect(); + String::from_utf8(bytes).expect("N3b removes only ASCII bytes") +} + +/// N4 — trim: remove leading and trailing whitespace of exactly the six-character set +/// (**not** Rust's Unicode `str::trim` — a leading U+00A0 must survive). +pub fn n4_trim(s: &str) -> &str { + s.trim_matches(|c: char| c.is_ascii() && is_contract_whitespace(c as u8)) +} + +/// N5 — entity canonicalization (encoded suite only): map every recognized spelling of the +/// five markup-significant characters to the canonical spelling, in a single left-to-right +/// scan with non-overlapping matches whose replacements are never rescanned. Numeric +/// references match with any number of leading zeros and case-insensitive hex digits/`x`; +/// named entities match case-sensitively. The spelling of any other character (e.g. `+`) +/// is not canonicalized. +pub fn n5_canonicalize(s: &str) -> String { + let bytes = s.as_bytes(); + let mut out: Vec = Vec::with_capacity(bytes.len()); + let mut i = 0; + while i < bytes.len() { + if bytes[i] == b'&' + && let Some((len, replacement)) = match_entity(&bytes[i..]) + { + match replacement { + // Recognized spelling of one of the five characters -> canonical. + Some(canonical) => out.extend_from_slice(canonical.as_bytes()), + // Recognized numeric reference outside the five-character set: copied + // untouched (N5 is scoped to exactly the five characters). + None => out.extend_from_slice(&bytes[i..i + len]), + } + i += len; + continue; + } + out.push(bytes[i]); + i += 1; + } + String::from_utf8(out).expect("N5 replaces ASCII entities with ASCII entities") +} + +/// Canonical spelling for one of the five markup-significant characters, if `code` is one. +fn canonical_for(code: u32) -> Option<&'static str> { + match code { + 0x26 => Some("&"), + 0x3C => Some("<"), + 0x3E => Some(">"), + 0x22 => Some("""), + 0x27 => Some("'"), + _ => None, + } +} + +/// Attempts to match an entity at the start of `rest` (which begins with `&`). Returns the +/// matched length and the canonical replacement (`None` = recognized numeric reference left +/// untouched); returns `None` overall when no entity is recognized at this position. +fn match_entity(rest: &[u8]) -> Option<(usize, Option<&'static str>)> { + // Named spellings, matched case-sensitively (the contract's recognized set only). + const NAMED: [(&[u8], &str); 5] = [ + (b"&", "&"), + (b"<", "<"), + (b">", ">"), + (b""", """), + (b"'", "'"), + ]; + for (spelling, canonical) in NAMED { + if rest.starts_with(spelling) { + return Some((spelling.len(), Some(canonical))); + } + } + + // Numeric references: `&#digits;` or `&#x/Xhexdigits;`. + if rest.len() < 4 || rest[1] != b'#' { + return None; + } + let (radix, digits_start) = if rest[2] == b'x' || rest[2] == b'X' { + (16u32, 3usize) + } else { + (10u32, 2usize) + }; + let mut code: u32 = 0; + let mut j = digits_start; + while j < rest.len() { + let d = (rest[j] as char).to_digit(radix); + match d { + Some(d) => { + code = code.saturating_mul(radix).saturating_add(d); + j += 1; + } + None => break, + } + } + if j == digits_start || j >= rest.len() || rest[j] != b';' { + return None; // no digits, or unterminated — not a numeric reference + } + Some((j + 1, canonical_for(code))) +} + +/// The stored-form pipeline for a raw-suite candidate: N2 → N3 → N4 (N1 is inherent). +pub fn normalize_raw(s: &str) -> String { + n4_trim(&n3_inter_tag(&n2_line_endings(s))).to_string() +} + +/// The stored-form pipeline for an encoded-suite candidate: N2 → N3 → N4 → N5. +pub fn normalize_encoded(s: &str) -> String { + n5_canonicalize(&normalize_raw(s)) +} + +/// Normalizes per suite (`"encoded"` applies N5; anything else is the raw pipeline). +pub fn normalize_for_suite(s: &str, suite: &str) -> String { + if suite == "encoded" { + normalize_encoded(s) + } else { + normalize_raw(s) + } +} + +// ---- tests (spec Testing plan — contract-derived vectors) ------------------------------------ + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn n2_crlf_and_cr_vectors() { + assert_eq!(n2_line_endings("a\r\nb"), "a\nb"); + assert_eq!(n2_line_endings("a\rb"), "a\nb"); + assert_eq!(n2_line_endings("a\r\n\rb\r"), "a\n\nb\n"); + assert_eq!(n2_line_endings("a\nb"), "a\nb"); + } + + #[test] + fn n3_collapses_each_of_the_six_whitespace_chars_between_tags() { + for ws in ['\t', '\n', '\u{0B}', '\u{0C}', '\r', ' '] { + let input = format!("{ws}"); + assert_eq!(n3_inter_tag(&input), "", "char U+{:04X}", ws as u32); + } + } + + #[test] + fn n3_collapses_multi_char_runs_between_tags() { + assert_eq!(n3_inter_tag(" \t\n\u{0B}\u{0C}\r "), ""); + assert_eq!( + n3_inter_tag("
        \n
      • x
      • \n
      "), + "
      • x
      " + ); + } + + #[test] + fn n3_leaves_non_inter_tag_whitespace_alone() { + // Run not between `>` and `<`: N3 territory ends where element text begins. + assert_eq!(n3_inter_tag("

      a b

      "), "

      a b

      "); + // `>`-whitespace-non-`<` (the `>\n/` boundary from composed-page): untouched by N3. + assert_eq!(n3_inter_tag("/> \n/* css */"), "/> \n/* css */"); + assert_eq!(n3_inter_tag("a > b < c"), "a > b < c"); + } + + #[test] + fn n3b_removes_every_whitespace_run_to_nothing() { + assert_eq!(n3b_strip("a b"), "ab"); + assert_eq!(n3b_strip("a \t\n\u{0B}\u{0C}\r b"), "ab"); + // Run inside element text and at a `>\n/` non-tag boundary. + assert_eq!(n3b_strip("

      a b

      "), "

      ab

      "); + assert_eq!(n3b_strip("/>\n/* css */"), "/>/*css*/"); + } + + #[test] + fn n3b_presence_vs_absence_compares_equal() { + // `>␠/` vs `>/` — one side has a run, the other has none; they must compare equal. + assert_eq!(n3b_strip("> /"), n3b_strip(">/")); + } + + #[test] + fn n4_trims_only_the_six_char_set() { + assert_eq!(n4_trim(" \t\n\u{0B}\u{0C}\r x \t\n\u{0B}\u{0C}\r "), "x"); + // A leading U+00A0 (not in the closed set) survives. + assert_eq!(n4_trim("\u{00A0}x"), "\u{00A0}x"); + assert_eq!(n4_trim(" \u{00A0}x "), "\u{00A0}x"); + } + + #[test] + fn n5_contract_table_vectors() { + assert_eq!(n5_canonicalize("'"), "'"); + assert_eq!(n5_canonicalize("""), """); + assert_eq!(n5_canonicalize("<"), "<"); + assert_eq!(n5_canonicalize("'"), "'"); + assert_eq!(n5_canonicalize("&"), "&"); + assert_eq!(n5_canonicalize("<"), "<"); + assert_eq!(n5_canonicalize(">"), ">"); + assert_eq!(n5_canonicalize("""), """); + // Canonical spellings are identity. + assert_eq!( + n5_canonicalize("&<>"'"), + "&<>"'" + ); + } + + #[test] + fn n5_no_rescan_of_replacements() { + // Data that escaped to `&#39;` (a literal `'` in source data) is not + // double-canonicalized. + assert_eq!(n5_canonicalize("&#39;"), "&#39;"); + } + + #[test] + fn n5_leaves_non_five_char_references_untouched() { + assert_eq!(n5_canonicalize("+"), "+"); + assert_eq!(n5_canonicalize("a ` b"), "a ` b"); + // Unrecognized named entity and bare ampersand: untouched. + assert_eq!(n5_canonicalize("© & &#"), "© & &#"); + } + + #[test] + fn n5_full_askama_family_vector() { + assert_eq!( + n5_canonicalize("<script>alert("x");"), + "<script>alert("x");" + ); + } +} diff --git a/benchmarks/rust/src/verifier.rs b/benchmarks/rust/src/verifier.rs new file mode 100644 index 00000000..1c5d9f41 --- /dev/null +++ b/benchmarks/rust/src/verifier.rs @@ -0,0 +1,386 @@ +//! Idiomatic-track verifier — the Rust port of the parity contract's idiomatic-track gate, +//! consuming the exported `.verify.json` definitions. Matching semantics: the candidate +//! is normalized (N1–N4, +N5 for encoded suites), then the N3b whitespace strip is applied +//! to the output AND to every needle before matching; `values` are exact non-overlapping +//! counts, `markers` are strictly ordered, `forbidden` must be absent from both raw and +//! normalized output, `required` is a minimum count. + +use serde::Deserialize; + +use crate::normalize::{n3b_strip, normalize_for_suite}; + +// ---- serde model of `.verify.json` ------------------------------------------------------- + +#[derive(Deserialize)] +pub struct VerifyDef { + pub workload: String, + pub suite: String, + pub values: Vec, + pub markers: Vec, + pub forbidden: Vec, + pub required: Vec, +} + +#[derive(Deserialize)] +pub struct ValueCheck { + pub text: String, + pub count: usize, +} + +#[derive(Deserialize)] +pub struct RequiredCheck { + pub text: String, + #[serde(rename = "minCount")] + pub min_count: usize, +} + +// ---- failure surface ------------------------------------------------------------------------- + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum FailureKind { + Value, + Marker, + Forbidden, + Required, +} + +impl FailureKind { + pub fn label(self) -> &'static str { + match self { + FailureKind::Value => "value", + FailureKind::Marker => "marker", + FailureKind::Forbidden => "forbidden", + FailureKind::Required => "required", + } + } +} + +/// One failed check: its kind plus the Diagnostics-table message tail +/// (`expected of "", found ` / `marker "" not found after index `). +#[derive(Debug)] +pub struct Failure { + pub kind: FailureKind, + pub message: String, +} + +// ---- verifier -------------------------------------------------------------------------------- + +/// Runs the verifier against a candidate's raw output. Empty result = accepted. +pub fn verify(def: &VerifyDef, raw_output: &str) -> Vec { + let normalized = normalize_for_suite(raw_output, &def.suite); + let stripped = n3b_strip(&normalized); + let stripped_raw = n3b_strip(raw_output); + let mut failures = Vec::new(); + + for v in &def.values { + let found = count_occurrences(&stripped, &n3b_strip(&v.text)); + if found != v.count { + failures.push(Failure { + kind: FailureKind::Value, + message: format!( + "expected {} of \"{}\", found {found}", + v.count, + excerpt(&v.text) + ), + }); + } + } + + let mut pos = 0; + for marker in &def.markers { + let needle = n3b_strip(marker); + match find_from(&stripped, &needle, pos) { + Some(at) => pos = at + needle.len(), + None => { + // Keep scanning subsequent markers from the current position so every + // out-of-order/missing marker is reported. + failures.push(Failure { + kind: FailureKind::Marker, + message: format!("marker \"{}\" not found after index {pos}", excerpt(marker)), + }); + } + } + } + + for f in &def.forbidden { + let needle = n3b_strip(f); + let found = + count_occurrences(&stripped_raw, &needle).max(count_occurrences(&stripped, &needle)); + if found != 0 { + failures.push(Failure { + kind: FailureKind::Forbidden, + message: format!("expected 0 of \"{}\", found {found}", excerpt(f)), + }); + } + } + + for r in &def.required { + let found = count_occurrences(&stripped, &n3b_strip(&r.text)); + if found < r.min_count { + failures.push(Failure { + kind: FailureKind::Required, + message: format!( + "expected {} of \"{}\", found {found}", + r.min_count, + excerpt(&r.text) + ), + }); + } + } + + failures +} + +/// Non-overlapping occurrence count (byte-wise; needles and haystack are both stripped). +pub fn count_occurrences(haystack: &str, needle: &str) -> usize { + if needle.is_empty() { + return 0; + } + let mut count = 0; + let mut index = 0; + while let Some(at) = find_from(haystack, needle, index) { + count += 1; + index = at + needle.len(); + } + count +} + +fn find_from(haystack: &str, needle: &str, from: usize) -> Option { + if from > haystack.len() { + return None; + } + haystack + .as_bytes() + .windows(needle.len()) + .skip(from) + .position(|w| w == needle.as_bytes()) + .map(|p| p + from) +} + +fn excerpt(s: &str) -> String { + let truncated: String = if s.chars().count() <= 48 { + s.to_string() + } else { + let mut t: String = s.chars().take(48).collect(); + t.push('\u{2026}'); + t + }; + truncated.replace('\n', "\\n") +} + +// ---- tests ----------------------------------------------------------------------------------- + +#[cfg(test)] +mod tests { + use super::*; + use crate::corpus::{WORKLOADS, load_golden, load_verify}; + + // ---- corruption synthesis ---------------------------------------------------------------- + + /// 'removed row': delete the first occurrence of the workload's pinned segment. + fn remove_first(golden: &str, segment: &str) -> String { + let at = golden + .find(segment) + .unwrap_or_else(|| panic!("removed-segment pin not found: {}", excerpt(segment))); + format!("{}{}", &golden[..at], &golden[at + segment.len()..]) + } + + /// 'reordered section': swap the first occurrences of A and B (A strictly before B). + fn swap_first(golden: &str, a: &str, b: &str) -> String { + let ia = golden + .find(a) + .unwrap_or_else(|| panic!("swap pin A not found: {}", excerpt(a))); + let ib = golden + .find(b) + .unwrap_or_else(|| panic!("swap pin B not found: {}", excerpt(b))); + assert!( + ib >= ia + a.len(), + "swap pins must be ordered and non-overlapping" + ); + format!( + "{}{}{}{}{}", + &golden[..ia], + b, + &golden[ia + a.len()..ib], + a, + &golden[ib + b.len()..] + ) + } + + /// 'unescaped payload' (encoded only): replace the first escaped form with its raw form. + fn unescape_first(golden: &str, escaped: &str, raw: &str) -> String { + assert!( + golden.contains(escaped), + "unescape pin not found: {}", + excerpt(escaped) + ); + golden.replacen(escaped, raw, 1) + } + + /// Per-workload calibration pins — the same corruption rules the .NET `verify-corpus` + /// command uses (`IdiomaticChecks.cs`). + struct Pins { + workload: &'static str, + removed_segment: &'static str, + removed_kind: FailureKind, + swap_a: &'static str, + swap_b: &'static str, + /// (escaped, raw) — encoded workloads only. + unescape: Option<(&'static str, &'static str)>, + } + + const ENCODED_LOOP_ROW_0: &str = "item <0> & "co"'q' & <angle> "d" こんにちは 0"; + + fn pins() -> [Pins; 8] { + [ + Pins { + // Pins mirror `VerifierDefinitions.ComposedPage`: the removed segment is the + // slider fragment composed-page.heddle splices into the layout's body slot — an + // idiomatic page with an EMPTY body must fail; the swap crosses the + // wholesale-only and retail-only mega-menu anchors. + workload: "composed-page", + removed_segment: "", + removed_kind: FailureKind::Marker, + swap_a: "/product/coming-soon-paleo-pork", + swap_b: "/products/paleo-friendly-pork", + unescape: None, + }, + Pins { + workload: "trivial-substitution", + removed_segment: "HB-2001", + removed_kind: FailureKind::Value, + swap_a: "class=\"sku\"", + swap_b: "class=\"rating\"", + unescape: None, + }, + Pins { + workload: "large-loop", + removed_segment: "row-00", + removed_kind: FailureKind::Value, + swap_a: "row-00", + swap_b: "row-25002500", + unescape: None, + }, + Pins { + workload: "mixed-page", + removed_segment: "
      ", + removed_kind: FailureKind::Value, + swap_a: "
      ", + swap_b: "class=\"hero\"", + unescape: None, + }, + Pins { + workload: "conditional-heavy", + removed_segment: "unit-000", + removed_kind: FailureKind::Value, + swap_a: "unit-000", + swap_b: "unit-100", + unescape: None, + }, + Pins { + // Pins mirror `VerifierDefinitions.FragmentHeavy`: row 0's whole tile fragment + // is the removed-row corruption; rows 0 and 24 are both tiles (i % 4 == 0), + // so the swap crosses the dispatch cycle. + workload: "fragment-heavy", + removed_segment: "

      item-00

      0

      new
      ", + removed_kind: FailureKind::Value, + swap_a: "item-00", + swap_b: "item-24", + unescape: None, + }, + Pins { + workload: "fortunes-encoded", + removed_segment: "1A bad random number generator: 1, 1, 1, 1, 1, 4.33e67, 1, 1, 1", + removed_kind: FailureKind::Value, + swap_a: "idmessage", + swap_b: "フレームワークのベンチマーク", + unescape: Some(("<script>alert(", " \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/askama/chrome/assets-styles.html b/benchmarks/rust/templates/controlled/askama/chrome/assets-styles.html new file mode 100644 index 00000000..cb6751d3 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/chrome/assets-styles.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/askama/chrome/body-end-scripts.html b/benchmarks/rust/templates/controlled/askama/chrome/body-end-scripts.html new file mode 100644 index 00000000..4a28491d --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/chrome/body-end-scripts.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/askama/chrome/body-scripts.html b/benchmarks/rust/templates/controlled/askama/chrome/body-scripts.html new file mode 100644 index 00000000..cb28a558 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/chrome/body-scripts.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/askama/chrome/custom-styles.html b/benchmarks/rust/templates/controlled/askama/chrome/custom-styles.html new file mode 100644 index 00000000..f635c77f --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/chrome/custom-styles.html @@ -0,0 +1 @@ +/* CSS Comment Test */ \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/askama/chrome/head-scripts.html b/benchmarks/rust/templates/controlled/askama/chrome/head-scripts.html new file mode 100644 index 00000000..879142ca --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/chrome/head-scripts.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/askama/chrome/secondary-retail-menu.html b/benchmarks/rust/templates/controlled/askama/chrome/secondary-retail-menu.html new file mode 100644 index 00000000..cc0390b5 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/chrome/secondary-retail-menu.html @@ -0,0 +1,116 @@ +
      \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/askama/chrome/secondary-wholesale-menu.html b/benchmarks/rust/templates/controlled/askama/chrome/secondary-wholesale-menu.html new file mode 100644 index 00000000..471ab31c --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/chrome/secondary-wholesale-menu.html @@ -0,0 +1,138 @@ + \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/askama/composed-page.html b/benchmarks/rust/templates/controlled/askama/composed-page.html new file mode 100644 index 00000000..31673f54 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/composed-page.html @@ -0,0 +1,14 @@ +{% extends "controlled/askama/shared/composed-page-layout.html" %} +{% block body %} +
      +
      +
      +
      +
      + + + +
      +
      +
      +{% endblock %} diff --git a/benchmarks/rust/templates/controlled/askama/conditional-heavy.html b/benchmarks/rust/templates/controlled/askama/conditional-heavy.html new file mode 100644 index 00000000..f58c7e1e --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/conditional-heavy.html @@ -0,0 +1 @@ +
        {% for r in rows %}
      • {% if r.is_bronze %}bronze{% elif r.is_silver %}silver{% elif r.is_gold %}gold{% else %}platinum{% endif %}{{ r.name }}{% if r.has_note %}note {{ r.seq }}{% endif %}{% if r.is_active %}active{% endif %}
      • {% endfor %}
      diff --git a/benchmarks/rust/templates/controlled/askama/encoded-loop.html b/benchmarks/rust/templates/controlled/askama/encoded-loop.html new file mode 100644 index 00000000..0679d611 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/encoded-loop.html @@ -0,0 +1 @@ +{% for item in items %}{% endfor %}
      {{ item.name }}{{ item.comment }}
      \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/askama/fortunes-encoded.html b/benchmarks/rust/templates/controlled/askama/fortunes-encoded.html new file mode 100644 index 00000000..42c9acf1 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/fortunes-encoded.html @@ -0,0 +1 @@ +Fortunes{% for r in rows %}{% endfor %}
      idmessage
      {{ r.id }}{{ r.message }}
      \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/askama/fragment-heavy.html b/benchmarks/rust/templates/controlled/askama/fragment-heavy.html new file mode 100644 index 00000000..8ed4d534 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/fragment-heavy.html @@ -0,0 +1 @@ +
      {% for item in items %}{% if item.is_tile %}{% include "controlled/askama/shared/fragment-heavy-tile.html" %}{% elif item.is_card %}{% include "controlled/askama/shared/fragment-heavy-card.html" %}{% elif item.is_media %}{% include "controlled/askama/shared/fragment-heavy-media-row.html" %}{% else %}{% include "controlled/askama/shared/fragment-heavy-stat.html" %}{% endif %}{% endfor %}
      diff --git a/benchmarks/rust/templates/controlled/askama/large-loop.html b/benchmarks/rust/templates/controlled/askama/large-loop.html new file mode 100644 index 00000000..5e6b9a65 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/large-loop.html @@ -0,0 +1 @@ +{% for item in items %}row-{{ item.value }}{{ item.value }}{% endfor %} diff --git a/benchmarks/rust/templates/controlled/askama/mixed-page.html b/benchmarks/rust/templates/controlled/askama/mixed-page.html new file mode 100644 index 00000000..2efd4045 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/mixed-page.html @@ -0,0 +1,29 @@ + + + + +{{ page_title }} + + + +
      +

      {{ store_name }}

      + +
      +
      +{% if show_banner %}{% endif %} +
      +

      {{ hero_heading }}

      +

      {{ hero_tagline }}

      +
      +
      +{% for p in products %}

      {{ p.name }}

      MX-{{ p.sku_number }}

      {{ p.price }}

      {% if p.on_sale %}

      On sale

      {% endif %}

      A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

      {% endfor %} +
      +{% if show_debug_panel %}
      debug
      {% endif %} +
      +
      +

      {{ footer_note }}

      +

      {{ store_name }} {{ year }} {{ support_email }}

      +
      + + diff --git a/benchmarks/rust/templates/controlled/askama/nav/mega-menu.html b/benchmarks/rust/templates/controlled/askama/nav/mega-menu.html new file mode 100644 index 00000000..93bac5bd --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/nav/mega-menu.html @@ -0,0 +1 @@ +
        {% for tab in menu.tabs %}
      • {{ tab.label }}{% if tab.has_dropdown %}
        {% for column in tab.columns %}{% include "controlled/askama/nav/nav-column.html" %}{% endfor %}
        {% endif %}
      • {% endfor %}
      diff --git a/benchmarks/rust/templates/controlled/askama/nav/nav-column.html b/benchmarks/rust/templates/controlled/askama/nav/nav-column.html new file mode 100644 index 00000000..9be506df --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/nav/nav-column.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/askama/nav/nav-link.html b/benchmarks/rust/templates/controlled/askama/nav/nav-link.html new file mode 100644 index 00000000..b07a3c05 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/nav/nav-link.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/askama/nav/nav-section.html b/benchmarks/rust/templates/controlled/askama/nav/nav-section.html new file mode 100644 index 00000000..ad48cb67 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/nav/nav-section.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/askama/shared/composed-page-layout.html b/benchmarks/rust/templates/controlled/askama/shared/composed-page-layout.html new file mode 100644 index 00000000..63dff720 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/shared/composed-page-layout.html @@ -0,0 +1,128 @@ + + + + + + + + + + {% block meta %}Title{% endblock %} + {% block socialmeta %} + + {% endblock %} + + + + + + {% include "controlled/askama/chrome/assets-styles.html" %} + + {% include "controlled/askama/chrome/head-scripts.html" %} + + + {% include "controlled/askama/chrome/body-scripts.html" %} +
      +
      + +
      +
      +
      +
      + {% include "controlled/askama/chrome/alert-top.html" %} +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + {% for menu in nav.menus %}{% include "controlled/askama/nav/mega-menu.html" %}{% endfor %} +
      +
      +
      + {% include "controlled/askama/chrome/alert-below.html" %} +
      +
      + {% block body %}{% endblock %} +
      +
      +
      +
      +
      + +
      +
      + {% include "controlled/askama/chrome/assets-scripts.html" %} + + {% block page_scripts %}{% endblock %} + {% block endpage_scripts %}{% endblock %} + {% include "controlled/askama/chrome/body-end-scripts.html" %} + + diff --git a/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-badge.html b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-badge.html new file mode 100644 index 00000000..9dd928bf --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-badge.html @@ -0,0 +1 @@ +{{ item.promo.label }} diff --git a/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-card.html b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-card.html new file mode 100644 index 00000000..631e5447 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-card.html @@ -0,0 +1 @@ +

      {{ item.name }}

      {% include "controlled/askama/shared/fragment-heavy-badge.html" %}{% include "controlled/askama/shared/fragment-heavy-price.html" %}

      {{ item.value }}

      diff --git a/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-media-row.html b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-media-row.html new file mode 100644 index 00000000..caab49f1 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-media-row.html @@ -0,0 +1 @@ +
      {{ item.name }}

      {{ item.name }}

      Caption for {{ item.name }}

      diff --git a/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-price.html b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-price.html new file mode 100644 index 00000000..bba5bedf --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-price.html @@ -0,0 +1 @@ +

      {{ item.promo.price }}.99

      diff --git a/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-stat.html b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-stat.html new file mode 100644 index 00000000..c7e0e140 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-stat.html @@ -0,0 +1 @@ +
      {{ item.name }}{{ item.value }}{{ item.delta }}
      diff --git a/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-tile.html b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-tile.html new file mode 100644 index 00000000..35a89004 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/shared/fragment-heavy-tile.html @@ -0,0 +1 @@ +

      {{ item.name }}

      {{ item.value }}

      {{ item.badge }}
      diff --git a/benchmarks/rust/templates/controlled/askama/trivial-substitution.html b/benchmarks/rust/templates/controlled/askama/trivial-substitution.html new file mode 100644 index 00000000..372f7f69 --- /dev/null +++ b/benchmarks/rust/templates/controlled/askama/trivial-substitution.html @@ -0,0 +1 @@ +

      {{ title }}

      {{ sku }}

      {{ price }}

      {{ brand }}

      {{ category }}

      {{ availability }}

      {{ summary }}

      {{ rating }}

      \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/tera/chrome/alert-below.html b/benchmarks/rust/templates/controlled/tera/chrome/alert-below.html new file mode 100644 index 00000000..e69de29b diff --git a/benchmarks/rust/templates/controlled/tera/chrome/alert-top.html b/benchmarks/rust/templates/controlled/tera/chrome/alert-top.html new file mode 100644 index 00000000..d889f879 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/chrome/alert-top.html @@ -0,0 +1 @@ +
      holiday shipping
      diff --git a/benchmarks/rust/templates/controlled/tera/chrome/assets-scripts.html b/benchmarks/rust/templates/controlled/tera/chrome/assets-scripts.html new file mode 100644 index 00000000..bf801bb9 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/chrome/assets-scripts.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/tera/chrome/assets-styles.html b/benchmarks/rust/templates/controlled/tera/chrome/assets-styles.html new file mode 100644 index 00000000..28df0356 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/chrome/assets-styles.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/tera/chrome/body-end-scripts.html b/benchmarks/rust/templates/controlled/tera/chrome/body-end-scripts.html new file mode 100644 index 00000000..51c5f27e --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/chrome/body-end-scripts.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/tera/chrome/body-scripts.html b/benchmarks/rust/templates/controlled/tera/chrome/body-scripts.html new file mode 100644 index 00000000..7bcf90f9 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/chrome/body-scripts.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/tera/chrome/custom-styles.html b/benchmarks/rust/templates/controlled/tera/chrome/custom-styles.html new file mode 100644 index 00000000..c03f73c5 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/chrome/custom-styles.html @@ -0,0 +1 @@ +/* CSS Comment Test */ diff --git a/benchmarks/rust/templates/controlled/tera/chrome/head-scripts.html b/benchmarks/rust/templates/controlled/tera/chrome/head-scripts.html new file mode 100644 index 00000000..35f0ac9a --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/chrome/head-scripts.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/tera/chrome/secondary-retail-menu.html b/benchmarks/rust/templates/controlled/tera/chrome/secondary-retail-menu.html new file mode 100644 index 00000000..6c6147b8 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/chrome/secondary-retail-menu.html @@ -0,0 +1,116 @@ + diff --git a/benchmarks/rust/templates/controlled/tera/chrome/secondary-wholesale-menu.html b/benchmarks/rust/templates/controlled/tera/chrome/secondary-wholesale-menu.html new file mode 100644 index 00000000..b80f8830 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/chrome/secondary-wholesale-menu.html @@ -0,0 +1,138 @@ + diff --git a/benchmarks/rust/templates/controlled/tera/composed-page.html b/benchmarks/rust/templates/controlled/tera/composed-page.html new file mode 100644 index 00000000..f5fa26a3 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/composed-page.html @@ -0,0 +1,14 @@ +{% extends "controlled/tera/shared/composed-page-layout.html" %} +{% block body %} +
      +
      +
      +
      +
      + + + +
      +
      +
      +{% endblock %} diff --git a/benchmarks/rust/templates/controlled/tera/conditional-heavy.html b/benchmarks/rust/templates/controlled/tera/conditional-heavy.html new file mode 100644 index 00000000..f58c7e1e --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/conditional-heavy.html @@ -0,0 +1 @@ +
        {% for r in rows %}
      • {% if r.is_bronze %}bronze{% elif r.is_silver %}silver{% elif r.is_gold %}gold{% else %}platinum{% endif %}{{ r.name }}{% if r.has_note %}note {{ r.seq }}{% endif %}{% if r.is_active %}active{% endif %}
      • {% endfor %}
      diff --git a/benchmarks/rust/templates/controlled/tera/encoded-loop.html b/benchmarks/rust/templates/controlled/tera/encoded-loop.html new file mode 100644 index 00000000..0679d611 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/encoded-loop.html @@ -0,0 +1 @@ +{% for item in items %}{% endfor %}
      {{ item.name }}{{ item.comment }}
      \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/tera/fortunes-encoded.html b/benchmarks/rust/templates/controlled/tera/fortunes-encoded.html new file mode 100644 index 00000000..42c9acf1 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/fortunes-encoded.html @@ -0,0 +1 @@ +Fortunes{% for r in rows %}{% endfor %}
      idmessage
      {{ r.id }}{{ r.message }}
      \ No newline at end of file diff --git a/benchmarks/rust/templates/controlled/tera/fragment-heavy.html b/benchmarks/rust/templates/controlled/tera/fragment-heavy.html new file mode 100644 index 00000000..aa80c2df --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/fragment-heavy.html @@ -0,0 +1 @@ +
      {% for item in items %}{% if item.is_tile %}{% include "controlled/tera/shared/fragment-heavy-tile.html" %}{% elif item.is_card %}{% include "controlled/tera/shared/fragment-heavy-card.html" %}{% elif item.is_media %}{% include "controlled/tera/shared/fragment-heavy-media-row.html" %}{% else %}{% include "controlled/tera/shared/fragment-heavy-stat.html" %}{% endif %}{% endfor %}
      diff --git a/benchmarks/rust/templates/controlled/tera/large-loop.html b/benchmarks/rust/templates/controlled/tera/large-loop.html new file mode 100644 index 00000000..5e6b9a65 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/large-loop.html @@ -0,0 +1 @@ +{% for item in items %}row-{{ item.value }}{{ item.value }}{% endfor %} diff --git a/benchmarks/rust/templates/controlled/tera/mixed-page.html b/benchmarks/rust/templates/controlled/tera/mixed-page.html new file mode 100644 index 00000000..2efd4045 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/mixed-page.html @@ -0,0 +1,29 @@ + + + + +{{ page_title }} + + + +
      +

      {{ store_name }}

      + +
      +
      +{% if show_banner %}{% endif %} +
      +

      {{ hero_heading }}

      +

      {{ hero_tagline }}

      +
      +
      +{% for p in products %}

      {{ p.name }}

      MX-{{ p.sku_number }}

      {{ p.price }}

      {% if p.on_sale %}

      On sale

      {% endif %}

      A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

      {% endfor %} +
      +{% if show_debug_panel %}
      debug
      {% endif %} +
      +
      +

      {{ footer_note }}

      +

      {{ store_name }} {{ year }} {{ support_email }}

      +
      + + diff --git a/benchmarks/rust/templates/controlled/tera/nav/column.html b/benchmarks/rust/templates/controlled/tera/nav/column.html new file mode 100644 index 00000000..1fba5ca4 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/nav/column.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/tera/nav/link.html b/benchmarks/rust/templates/controlled/tera/nav/link.html new file mode 100644 index 00000000..b07a3c05 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/nav/link.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/tera/nav/mega-menu.html b/benchmarks/rust/templates/controlled/tera/nav/mega-menu.html new file mode 100644 index 00000000..d1dd642e --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/nav/mega-menu.html @@ -0,0 +1 @@ +
        {% for tab in menu.tabs %}
      • {{ tab.label }}{% if tab.has_dropdown %}
        {% for column in tab.columns %}{% include "controlled/tera/nav/column.html" %}{% endfor %}
        {% endif %}
      • {% endfor %}
      diff --git a/benchmarks/rust/templates/controlled/tera/nav/section.html b/benchmarks/rust/templates/controlled/tera/nav/section.html new file mode 100644 index 00000000..0e00803c --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/nav/section.html @@ -0,0 +1 @@ + diff --git a/benchmarks/rust/templates/controlled/tera/shared/composed-page-layout.html b/benchmarks/rust/templates/controlled/tera/shared/composed-page-layout.html new file mode 100644 index 00000000..ebcaeb30 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/shared/composed-page-layout.html @@ -0,0 +1,128 @@ + + + + + + + + + + {% block meta %}Title{% endblock %} + {% block socialmeta %} + + {% endblock %} + + + + + + {% include "controlled/tera/chrome/assets-styles.html" %} + + {% include "controlled/tera/chrome/head-scripts.html" %} + + + {% include "controlled/tera/chrome/body-scripts.html" %} +
      +
      + +
      +
      +
      +
      + {% include "controlled/tera/chrome/alert-top.html" %} +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + {% for menu in nav.menus %}{% include "controlled/tera/nav/mega-menu.html" %}{% endfor %} +
      +
      +
      + {% include "controlled/tera/chrome/alert-below.html" %} +
      +
      + {% block body %}{% endblock %} +
      +
      +
      +
      +
      + +
      +
      + {% include "controlled/tera/chrome/assets-scripts.html" %} + + {% block page_scripts %}{% endblock %} + {% block endpage_scripts %}{% endblock %} + {% include "controlled/tera/chrome/body-end-scripts.html" %} + + diff --git a/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-badge.html b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-badge.html new file mode 100644 index 00000000..9dd928bf --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-badge.html @@ -0,0 +1 @@ +{{ item.promo.label }} diff --git a/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-card.html b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-card.html new file mode 100644 index 00000000..24d5b66b --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-card.html @@ -0,0 +1 @@ +

      {{ item.name }}

      {% include "controlled/tera/shared/fragment-heavy-badge.html" %}{% include "controlled/tera/shared/fragment-heavy-price.html" %}

      {{ item.value }}

      diff --git a/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-media-row.html b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-media-row.html new file mode 100644 index 00000000..caab49f1 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-media-row.html @@ -0,0 +1 @@ +
      {{ item.name }}

      {{ item.name }}

      Caption for {{ item.name }}

      diff --git a/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-price.html b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-price.html new file mode 100644 index 00000000..bba5bedf --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-price.html @@ -0,0 +1 @@ +

      {{ item.promo.price }}.99

      diff --git a/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-stat.html b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-stat.html new file mode 100644 index 00000000..c7e0e140 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-stat.html @@ -0,0 +1 @@ +
      {{ item.name }}{{ item.value }}{{ item.delta }}
      diff --git a/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-tile.html b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-tile.html new file mode 100644 index 00000000..35a89004 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/shared/fragment-heavy-tile.html @@ -0,0 +1 @@ +

      {{ item.name }}

      {{ item.value }}

      {{ item.badge }}
      diff --git a/benchmarks/rust/templates/controlled/tera/trivial-substitution.html b/benchmarks/rust/templates/controlled/tera/trivial-substitution.html new file mode 100644 index 00000000..372f7f69 --- /dev/null +++ b/benchmarks/rust/templates/controlled/tera/trivial-substitution.html @@ -0,0 +1 @@ +

      {{ title }}

      {{ sku }}

      {{ price }}

      {{ brand }}

      {{ category }}

      {{ availability }}

      {{ summary }}

      {{ rating }}

      \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/chrome/alert-below.html b/benchmarks/rust/templates/idiomatic/askama/chrome/alert-below.html new file mode 100644 index 00000000..66777697 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/chrome/alert-below.html @@ -0,0 +1,6 @@ +{# Idiomatic Askama chrome fragment "alert_below". + Inert chrome is literal template text owned by the template tier, transcribed + verbatim from the Heddle chrome-fragments library; the layout pulls it in with + {% include %} (Askama book: "Template syntax - Include"). #} + + \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/chrome/alert-top.html b/benchmarks/rust/templates/idiomatic/askama/chrome/alert-top.html new file mode 100644 index 00000000..adea5570 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/chrome/alert-top.html @@ -0,0 +1,5 @@ +{# Idiomatic Askama chrome fragment "alert_top". + Inert chrome is literal template text owned by the template tier, transcribed + verbatim from the Heddle chrome-fragments library; the layout pulls it in with + {% include %} (Askama book: "Template syntax - Include"). #} +
      holiday shipping
      \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/chrome/assets-scripts.html b/benchmarks/rust/templates/idiomatic/askama/chrome/assets-scripts.html new file mode 100644 index 00000000..b8599c23 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/chrome/assets-scripts.html @@ -0,0 +1,5 @@ +{# Idiomatic Askama chrome fragment "assets_scripts". + Inert chrome is literal template text owned by the template tier, transcribed + verbatim from the Heddle chrome-fragments library; the layout pulls it in with + {% include %} (Askama book: "Template syntax - Include"). #} + \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/chrome/assets-styles.html b/benchmarks/rust/templates/idiomatic/askama/chrome/assets-styles.html new file mode 100644 index 00000000..ac1f58c4 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/chrome/assets-styles.html @@ -0,0 +1,5 @@ +{# Idiomatic Askama chrome fragment "assets_styles". + Inert chrome is literal template text owned by the template tier, transcribed + verbatim from the Heddle chrome-fragments library; the layout pulls it in with + {% include %} (Askama book: "Template syntax - Include"). #} + \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/chrome/body-end-scripts.html b/benchmarks/rust/templates/idiomatic/askama/chrome/body-end-scripts.html new file mode 100644 index 00000000..1f4f068b --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/chrome/body-end-scripts.html @@ -0,0 +1,5 @@ +{# Idiomatic Askama chrome fragment "body_end_scripts". + Inert chrome is literal template text owned by the template tier, transcribed + verbatim from the Heddle chrome-fragments library; the layout pulls it in with + {% include %} (Askama book: "Template syntax - Include"). #} + \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/chrome/body-scripts.html b/benchmarks/rust/templates/idiomatic/askama/chrome/body-scripts.html new file mode 100644 index 00000000..be37745f --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/chrome/body-scripts.html @@ -0,0 +1,5 @@ +{# Idiomatic Askama chrome fragment "body_scripts". + Inert chrome is literal template text owned by the template tier, transcribed + verbatim from the Heddle chrome-fragments library; the layout pulls it in with + {% include %} (Askama book: "Template syntax - Include"). #} + \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/chrome/custom-styles.html b/benchmarks/rust/templates/idiomatic/askama/chrome/custom-styles.html new file mode 100644 index 00000000..e357e9bb --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/chrome/custom-styles.html @@ -0,0 +1,5 @@ +{# Idiomatic Askama chrome fragment "custom_styles". + Inert chrome is literal template text owned by the template tier, transcribed + verbatim from the Heddle chrome-fragments library; the layout pulls it in with + {% include %} (Askama book: "Template syntax - Include"). #} +/* CSS Comment Test */ \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/chrome/head-scripts.html b/benchmarks/rust/templates/idiomatic/askama/chrome/head-scripts.html new file mode 100644 index 00000000..7585d4a8 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/chrome/head-scripts.html @@ -0,0 +1,5 @@ +{# Idiomatic Askama chrome fragment "head_scripts". + Inert chrome is literal template text owned by the template tier, transcribed + verbatim from the Heddle chrome-fragments library; the layout pulls it in with + {% include %} (Askama book: "Template syntax - Include"). #} + \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/chrome/secondary-retail-menu.html b/benchmarks/rust/templates/idiomatic/askama/chrome/secondary-retail-menu.html new file mode 100644 index 00000000..a6c5cb9b --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/chrome/secondary-retail-menu.html @@ -0,0 +1,120 @@ +{# Idiomatic Askama chrome fragment "secondary_retail_menu". + Inert chrome is literal template text owned by the template tier, transcribed + verbatim from the Heddle chrome-fragments library; the layout pulls it in with + {% include %} (Askama book: "Template syntax - Include"). #} + \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/chrome/secondary-wholesale-menu.html b/benchmarks/rust/templates/idiomatic/askama/chrome/secondary-wholesale-menu.html new file mode 100644 index 00000000..0ad3a1b1 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/chrome/secondary-wholesale-menu.html @@ -0,0 +1,142 @@ +{# Idiomatic Askama chrome fragment "secondary_wholesale_menu". + Inert chrome is literal template text owned by the template tier, transcribed + verbatim from the Heddle chrome-fragments library; the layout pulls it in with + {% include %} (Askama book: "Template syntax - Include"). #} + \ No newline at end of file diff --git a/benchmarks/rust/templates/idiomatic/askama/composed-page.html b/benchmarks/rust/templates/idiomatic/askama/composed-page.html new file mode 100644 index 00000000..240870e0 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/composed-page.html @@ -0,0 +1,19 @@ +{% extends "idiomatic/askama/shared/composed-page-layout.html" %} +{# Idiomatic Askama page template. Patterns follow + the Askama 0.16 book: "Template syntax - Template inheritance" (the page extends the + layout and fills the live body block with the slider markup - both tracks carry the + same slider body, the verifier's removed-segment calibration pin; the layout's + section-default blocks render unoverridden). #} +{% block body %} +
      +
      +
      +
      +
      + + + +
      +
      +
      +{% endblock %} diff --git a/benchmarks/rust/templates/idiomatic/askama/conditional-heavy.html b/benchmarks/rust/templates/idiomatic/askama/conditional-heavy.html new file mode 100644 index 00000000..ef3a3f70 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/conditional-heavy.html @@ -0,0 +1,27 @@ +{# Idiomatic Askama template. Patterns follow the + Askama 0.16 book: "Template syntax - If" (if / elif / else chain) and "Template + syntax - For"; the note text is composed by the template as the literal "note " + the + seq substitution (the model carries data, never display strings). Default HTML + escaping left on. #} +
        + {% for r in rows %} +
      • + {% if r.is_bronze %} + bronze + {% elif r.is_silver %} + silver + {% elif r.is_gold %} + gold + {% else %} + platinum + {% endif %} + {{ r.name }} + {% if r.has_note %} + note {{ r.seq }} + {% endif %} + {% if r.is_active %} + active + {% endif %} +
      • + {% endfor %} +
      diff --git a/benchmarks/rust/templates/idiomatic/askama/encoded-loop.html b/benchmarks/rust/templates/idiomatic/askama/encoded-loop.html new file mode 100644 index 00000000..6ef0ae44 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/encoded-loop.html @@ -0,0 +1,11 @@ +{# Idiomatic Askama template. Patterns follow the Askama 0.16 book: + "Filters - escape" (the default Html escaper covers text and attribute-value positions) + and "Template syntax - For". #} + + {% for item in items %} + + + + + {% endfor %} +
      {{ item.name }}{{ item.comment }}
      diff --git a/benchmarks/rust/templates/idiomatic/askama/fortunes-encoded.html b/benchmarks/rust/templates/idiomatic/askama/fortunes-encoded.html new file mode 100644 index 00000000..1ac3620a --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/fortunes-encoded.html @@ -0,0 +1,17 @@ +{# Idiomatic Askama template. Patterns follow the Askama 0.16 book: + "Filters - escape" (the default Html escaper handles untrusted data - no safe, no raw) + and "Template syntax - For". #} + + + + Fortunes + + + + + {% for r in rows %} + + {% endfor %} +
      idmessage
      {{ r.id }}{{ r.message }}
      + + diff --git a/benchmarks/rust/templates/idiomatic/askama/fragment-heavy.html b/benchmarks/rust/templates/idiomatic/askama/fragment-heavy.html new file mode 100644 index 00000000..941c5c57 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/fragment-heavy.html @@ -0,0 +1,18 @@ +{# Idiomatic Askama template. Per-row four-way fragment + dispatch on the precomputed kind booleans, invoking one per-kind partial per row + (Askama book: "Template syntax - If" - if / elif / else chain - and "Template syntax - + Include"; included partials have full access to the loop variable). Default HTML + escaping left on. #} +
      + {% for item in items %} + {% if item.is_tile %} + {% include "idiomatic/askama/shared/fragment-heavy-tile.html" %} + {% elif item.is_card %} + {% include "idiomatic/askama/shared/fragment-heavy-card.html" %} + {% elif item.is_media %} + {% include "idiomatic/askama/shared/fragment-heavy-media-row.html" %} + {% else %} + {% include "idiomatic/askama/shared/fragment-heavy-stat.html" %} + {% endif %} + {% endfor %} +
      diff --git a/benchmarks/rust/templates/idiomatic/askama/large-loop.html b/benchmarks/rust/templates/idiomatic/askama/large-loop.html new file mode 100644 index 00000000..cf2c961b --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/large-loop.html @@ -0,0 +1,10 @@ +{# Idiomatic Askama template. Patterns follow the + Askama 0.16 book: "Template syntax - For" (loop over a slice); the display name is + composed by the template as the literal "row-" + the value substitution (the model + carries data, never display strings). Default HTML escaping left on. #} +{% for item in items %} + + row-{{ item.value }} + {{ item.value }} + +{% endfor %} diff --git a/benchmarks/rust/templates/idiomatic/askama/mixed-page.html b/benchmarks/rust/templates/idiomatic/askama/mixed-page.html new file mode 100644 index 00000000..00e5a11a --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/mixed-page.html @@ -0,0 +1,50 @@ +{# Idiomatic Askama template. SINGLE-FILE by rule: + the workload rules pin the idiomatic mixed-page to one file in every ecosystem - + layout composition is composed-page's dimension. Patterns follow the Askama 0.16 book: + "Creating templates" (a self-contained page), "Template syntax - For" and "Template + syntax - If"; the display SKU ("MX-" + sku_number) and the blurb sentence (around the + batch substitution) are template-composed (the model carries data, never display + strings). Default HTML escaping left on. #} + + + + + {{ page_title }} + + + +
      +

      {{ store_name }}

      + +
      +
      + {% if show_banner %} + + {% endif %} +
      +

      {{ hero_heading }}

      +

      {{ hero_tagline }}

      +
      +
      + {% for p in products %} +
      +

      {{ p.name }}

      +

      MX-{{ p.sku_number }}

      +

      {{ p.price }}

      + {% if p.on_sale %} +

      On sale

      + {% endif %} +

      A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

      +
      + {% endfor %} +
      + {% if show_debug_panel %} +
      debug
      + {% endif %} +
      +
      +

      {{ footer_note }}

      +

      {{ store_name }} {{ year }} {{ support_email }}

      +
      + + diff --git a/benchmarks/rust/templates/idiomatic/askama/nav/mega-menu.html b/benchmarks/rust/templates/idiomatic/askama/nav/mega-menu.html new file mode 100644 index 00000000..b1f6fde2 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/nav/mega-menu.html @@ -0,0 +1,19 @@ +{# Idiomatic Askama nav partial. One mega menu: the + tab strip with per-tab dropdowns on the precomputed has_dropdown boolean (Askama book: + "Template syntax - For" / "If" + nested "Include" of the column partial). #} +
      +
        + {% for tab in menu.tabs %} +
      • + {{ tab.label }} + {% if tab.has_dropdown %} +
        + {% for column in tab.columns %} + {% include "idiomatic/askama/nav/nav-column.html" %} + {% endfor %} +
        + {% endif %} +
      • + {% endfor %} +
      +
      diff --git a/benchmarks/rust/templates/idiomatic/askama/nav/nav-column.html b/benchmarks/rust/templates/idiomatic/askama/nav/nav-column.html new file mode 100644 index 00000000..49f02730 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/nav/nav-column.html @@ -0,0 +1,8 @@ +{# Idiomatic Askama nav partial. One column of nav + sections; included both from the mega-menu dropdowns and from the footer nav (Askama + book: "Template syntax - For" + "Include"). #} + diff --git a/benchmarks/rust/templates/idiomatic/askama/nav/nav-link.html b/benchmarks/rust/templates/idiomatic/askama/nav/nav-link.html new file mode 100644 index 00000000..54085090 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/nav/nav-link.html @@ -0,0 +1,4 @@ +{# Idiomatic Askama nav partial. One link row; the + innermost of the nested nav partials (Askama book: "Template syntax - Include" - + included templates have full access to the including scope, loop variables included). #} + diff --git a/benchmarks/rust/templates/idiomatic/askama/nav/nav-section.html b/benchmarks/rust/templates/idiomatic/askama/nav/nav-section.html new file mode 100644 index 00000000..d0792d22 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/nav/nav-section.html @@ -0,0 +1,15 @@ +{# Idiomatic Askama nav partial. One section: the + title (linked or plain on the precomputed title_linked boolean - Askama book: + "Template syntax - If") and its link list ("For" + nested "Include"). #} + diff --git a/benchmarks/rust/templates/idiomatic/askama/shared/composed-page-layout.html b/benchmarks/rust/templates/idiomatic/askama/shared/composed-page-layout.html new file mode 100644 index 00000000..629f50d5 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/shared/composed-page-layout.html @@ -0,0 +1,136 @@ +{# Idiomatic Askama layout. Patterns follow the + Askama 0.16 book: "Template syntax - Template inheritance" (a base template carrying + the full literal page chrome, overridable section-default blocks - meta, socialmeta, + page_scripts, endpage_scripts - and the live {% block body %} slot the page fills) and + "Template syntax - Include" / "For" / "If" (the inert chrome fragments as included + literal-text partials; the structured nav rendered by nested loops and the + nav-family partials). Default HTML escaping is left on; nav model values contain no characters + HTML escaping rewrites, so no filter is needed anywhere. #} + + + + + + + + + + {% block meta %}Title{% endblock %} + {% block socialmeta %} + + {% endblock %} + + + + + + {% include "idiomatic/askama/chrome/assets-styles.html" %} + + {% include "idiomatic/askama/chrome/head-scripts.html" %} + + + {% include "idiomatic/askama/chrome/body-scripts.html" %} +
      +
      + +
      +
      +
      +
      + {% include "idiomatic/askama/chrome/alert-top.html" %} +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + {% for menu in nav.menus %}{% include "idiomatic/askama/nav/mega-menu.html" %}{% endfor %} +
      +
      +
      + {% include "idiomatic/askama/chrome/alert-below.html" %} +
      +
      + {% block body %}{% endblock %} +
      +
      +
      +
      +
      + +
      +
      + {% include "idiomatic/askama/chrome/assets-scripts.html" %} + + {% block page_scripts %}{% endblock %} + {% block endpage_scripts %}{% endblock %} + {% include "idiomatic/askama/chrome/body-end-scripts.html" %} + + diff --git a/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-badge.html b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-badge.html new file mode 100644 index 00000000..b3555485 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-badge.html @@ -0,0 +1,3 @@ +{# Idiomatic Askama badge sub-partial. Rendered by the + card partial against the row's promo (Askama book: "Template syntax - Include"). #} +{{ item.promo.label }} diff --git a/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-card.html b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-card.html new file mode 100644 index 00000000..50b3f68e --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-card.html @@ -0,0 +1,9 @@ +{# Idiomatic Askama card partial. The one nested kind: + the card renders the badge and price sub-partials against the row's promo (Askama + book: "Template syntax - Include" - nested includes share the enclosing scope). #} +
      +

      {{ item.name }}

      + {% include "idiomatic/askama/shared/fragment-heavy-badge.html" %} + {% include "idiomatic/askama/shared/fragment-heavy-price.html" %} +

      {{ item.value }}

      +
      diff --git a/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-media-row.html b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-media-row.html new file mode 100644 index 00000000..c88c4e89 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-media-row.html @@ -0,0 +1,10 @@ +{# Idiomatic Askama media-row partial. One of the + four dispatched fragment kinds; the image source ("/img/" + name + ".jpg") and the + caption ("Caption for " + name) are template-composed literal-plus-substitution. #} +
      + {{ item.name }} +
      +

      {{ item.name }}

      +

      Caption for {{ item.name }}

      +
      +
      diff --git a/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-price.html b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-price.html new file mode 100644 index 00000000..4ecb5101 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-price.html @@ -0,0 +1,5 @@ +{# Idiomatic Askama price sub-partial. Rendered by + the card partial against the row's promo; the display price is composed by the template + as the int substitution + the literal ".99" (the model carries data, never display + strings). #} +

      {{ item.promo.price }}.99

      diff --git a/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-stat.html b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-stat.html new file mode 100644 index 00000000..5cd2bbec --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-stat.html @@ -0,0 +1,7 @@ +{# Idiomatic Askama stat partial. One of the four + dispatched fragment kinds (Askama book: "Template syntax - Include"). #} +
      + {{ item.name }} + {{ item.value }} + {{ item.delta }} +
      diff --git a/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-tile.html b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-tile.html new file mode 100644 index 00000000..be71a4ef --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/shared/fragment-heavy-tile.html @@ -0,0 +1,7 @@ +{# Idiomatic Askama tile partial. One of the four + dispatched fragment kinds (Askama book: "Template syntax - Include"). #} +
      +

      {{ item.name }}

      +

      {{ item.value }}

      + {{ item.badge }} +
      diff --git a/benchmarks/rust/templates/idiomatic/askama/trivial-substitution.html b/benchmarks/rust/templates/idiomatic/askama/trivial-substitution.html new file mode 100644 index 00000000..9af4cae1 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/askama/trivial-substitution.html @@ -0,0 +1,16 @@ +{# Idiomatic Askama template. Patterns follow the Askama 0.16 book: + "Getting started" and "Creating templates" (struct-per-template expression substitution, + default HTML escaping left on - the pinned values contain no escapable characters). #} +
      +

      {{ title }}

      +

      {{ sku }}

      +

      {{ price }}

      +

      {{ brand }}

      +

      {{ category }}

      +

      {{ availability }}

      + + + +

      {{ summary }}

      +

      {{ rating }}

      +
      diff --git a/benchmarks/rust/templates/idiomatic/tera/chrome/alert-below.html b/benchmarks/rust/templates/idiomatic/tera/chrome/alert-below.html new file mode 100644 index 00000000..3dbe5721 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/chrome/alert-below.html @@ -0,0 +1,4 @@ +{# Idiomatic Tera chrome fragment the pinned-empty below-header alert slot. + Patterns follow the Tera docs (keats.github.io/tera): "Include" - inert literal + chrome as a per-fragment partial the layout includes at its composition point + (all page text lives in templates); no substitutions. #} diff --git a/benchmarks/rust/templates/idiomatic/tera/chrome/alert-top.html b/benchmarks/rust/templates/idiomatic/tera/chrome/alert-top.html new file mode 100644 index 00000000..3cc2f2de --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/chrome/alert-top.html @@ -0,0 +1,5 @@ +{# Idiomatic Tera chrome fragment the alert banner. + Patterns follow the Tera docs (keats.github.io/tera): "Include" - inert literal + chrome as a per-fragment partial the layout includes at its composition point + (all page text lives in templates); no substitutions. #} +
      holiday shipping
      diff --git a/benchmarks/rust/templates/idiomatic/tera/chrome/assets-scripts.html b/benchmarks/rust/templates/idiomatic/tera/chrome/assets-scripts.html new file mode 100644 index 00000000..7e63ee6a --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/chrome/assets-scripts.html @@ -0,0 +1,5 @@ +{# Idiomatic Tera chrome fragment the main script tag. + Patterns follow the Tera docs (keats.github.io/tera): "Include" - inert literal + chrome as a per-fragment partial the layout includes at its composition point + (all page text lives in templates); no substitutions. #} + diff --git a/benchmarks/rust/templates/idiomatic/tera/chrome/assets-styles.html b/benchmarks/rust/templates/idiomatic/tera/chrome/assets-styles.html new file mode 100644 index 00000000..26addb77 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/chrome/assets-styles.html @@ -0,0 +1,5 @@ +{# Idiomatic Tera chrome fragment the stylesheet link. + Patterns follow the Tera docs (keats.github.io/tera): "Include" - inert literal + chrome as a per-fragment partial the layout includes at its composition point + (all page text lives in templates); no substitutions. #} + diff --git a/benchmarks/rust/templates/idiomatic/tera/chrome/body-end-scripts.html b/benchmarks/rust/templates/idiomatic/tera/chrome/body-end-scripts.html new file mode 100644 index 00000000..978421e4 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/chrome/body-end-scripts.html @@ -0,0 +1,5 @@ +{# Idiomatic Tera chrome fragment the body-end script tag. + Patterns follow the Tera docs (keats.github.io/tera): "Include" - inert literal + chrome as a per-fragment partial the layout includes at its composition point + (all page text lives in templates); no substitutions. #} + diff --git a/benchmarks/rust/templates/idiomatic/tera/chrome/body-scripts.html b/benchmarks/rust/templates/idiomatic/tera/chrome/body-scripts.html new file mode 100644 index 00000000..59882c5c --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/chrome/body-scripts.html @@ -0,0 +1,5 @@ +{# Idiomatic Tera chrome fragment the body-open script tag. + Patterns follow the Tera docs (keats.github.io/tera): "Include" - inert literal + chrome as a per-fragment partial the layout includes at its composition point + (all page text lives in templates); no substitutions. #} + diff --git a/benchmarks/rust/templates/idiomatic/tera/chrome/custom-styles.html b/benchmarks/rust/templates/idiomatic/tera/chrome/custom-styles.html new file mode 100644 index 00000000..032e57a2 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/chrome/custom-styles.html @@ -0,0 +1,5 @@ +{# Idiomatic Tera chrome fragment the custom-styles snippet. + Patterns follow the Tera docs (keats.github.io/tera): "Include" - inert literal + chrome as a per-fragment partial the layout includes at its composition point + (all page text lives in templates); no substitutions. #} +/* CSS Comment Test */ diff --git a/benchmarks/rust/templates/idiomatic/tera/chrome/head-scripts.html b/benchmarks/rust/templates/idiomatic/tera/chrome/head-scripts.html new file mode 100644 index 00000000..72f1df85 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/chrome/head-scripts.html @@ -0,0 +1,5 @@ +{# Idiomatic Tera chrome fragment the head script tag. + Patterns follow the Tera docs (keats.github.io/tera): "Include" - inert literal + chrome as a per-fragment partial the layout includes at its composition point + (all page text lives in templates); no substitutions. #} + diff --git a/benchmarks/rust/templates/idiomatic/tera/chrome/secondary-retail-menu.html b/benchmarks/rust/templates/idiomatic/tera/chrome/secondary-retail-menu.html new file mode 100644 index 00000000..88a85027 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/chrome/secondary-retail-menu.html @@ -0,0 +1,120 @@ +{# Idiomatic Tera chrome fragment the retail secondary menu. + Patterns follow the Tera docs (keats.github.io/tera): "Include" - inert literal + chrome as a per-fragment partial the layout includes at its composition point + (all page text lives in templates); no substitutions. #} + diff --git a/benchmarks/rust/templates/idiomatic/tera/chrome/secondary-wholesale-menu.html b/benchmarks/rust/templates/idiomatic/tera/chrome/secondary-wholesale-menu.html new file mode 100644 index 00000000..0a283b24 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/chrome/secondary-wholesale-menu.html @@ -0,0 +1,142 @@ +{# Idiomatic Tera chrome fragment the wholesale secondary menu. + Patterns follow the Tera docs (keats.github.io/tera): "Include" - inert literal + chrome as a per-fragment partial the layout includes at its composition point + (all page text lives in templates); no substitutions. #} + diff --git a/benchmarks/rust/templates/idiomatic/tera/composed-page.html b/benchmarks/rust/templates/idiomatic/tera/composed-page.html new file mode 100644 index 00000000..b20d5502 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/composed-page.html @@ -0,0 +1,20 @@ +{% extends "idiomatic/tera/shared/composed-page-base.html" %} +{# Idiomatic Tera child template the composed page. Patterns follow + the Tera docs (keats.github.io/tera): "Inheritance" (child extends the base and fills the + live body block; the section-default blocks are left un-overridden, so the base defaults + render - mirroring layout.heddle). The slider body is the SAME as the controlled track's: + the verifier's removed-segment calibration pin is the slider, so an empty body fails, + deliberately. #} +{% block body %} +
      +
      +
      +
      +
      + + + +
      +
      +
      +{% endblock %} diff --git a/benchmarks/rust/templates/idiomatic/tera/conditional-heavy.html b/benchmarks/rust/templates/idiomatic/tera/conditional-heavy.html new file mode 100644 index 00000000..04dee2e9 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/conditional-heavy.html @@ -0,0 +1,26 @@ +{# Idiomatic Tera template. Patterns follow the Tera docs + (keats.github.io/tera): "Control structures - If" (if / elif / else chain) and + "Control structures - For loops"; default auto-escaping left on. The note text is + template-composed as the literal `note ` + the seq substitution. #} +
        + {% for r in rows %} +
      • + {% if r.is_bronze %} + bronze + {% elif r.is_silver %} + silver + {% elif r.is_gold %} + gold + {% else %} + platinum + {% endif %} + {{ r.name }} + {% if r.has_note %} + note {{ r.seq }} + {% endif %} + {% if r.is_active %} + active + {% endif %} +
      • + {% endfor %} +
      diff --git a/benchmarks/rust/templates/idiomatic/tera/encoded-loop.html b/benchmarks/rust/templates/idiomatic/tera/encoded-loop.html new file mode 100644 index 00000000..f0ed7de8 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/encoded-loop.html @@ -0,0 +1,11 @@ +{# Idiomatic Tera template. Patterns follow the Tera docs + (keats.github.io/tera): "Auto-escaping" (default escaping covers text and + attribute-value positions) and "Control structures - For loops". #} + + {% for item in items %} + + + + + {% endfor %} +
      {{ item.name }}{{ item.comment }}
      diff --git a/benchmarks/rust/templates/idiomatic/tera/fortunes-encoded.html b/benchmarks/rust/templates/idiomatic/tera/fortunes-encoded.html new file mode 100644 index 00000000..9ab374b0 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/fortunes-encoded.html @@ -0,0 +1,17 @@ +{# Idiomatic Tera template. Patterns follow the Tera docs + (keats.github.io/tera): "Auto-escaping" (default escaping handles untrusted data - + no safe filter) and "Control structures - For loops". #} + + + + Fortunes + + + + + {% for r in rows %} + + {% endfor %} +
      idmessage
      {{ r.id }}{{ r.message }}
      + + diff --git a/benchmarks/rust/templates/idiomatic/tera/fragment-heavy.html b/benchmarks/rust/templates/idiomatic/tera/fragment-heavy.html new file mode 100644 index 00000000..74aa3812 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/fragment-heavy.html @@ -0,0 +1,18 @@ +{# Idiomatic Tera template per-row fragment dispatch. Patterns follow + the Tera docs (keats.github.io/tera): "Control structures - If" (if / elif / elif / else + chain over the precomputed kind booleans - common-denominator dispatch) and + "Include" (per-kind partial rendered with the current context, loop variable included); + default auto-escaping left on. #} +
      + {% for item in items %} + {% if item.is_tile %} + {% include "idiomatic/tera/shared/fragment-heavy-tile.html" %} + {% elif item.is_card %} + {% include "idiomatic/tera/shared/fragment-heavy-card.html" %} + {% elif item.is_media %} + {% include "idiomatic/tera/shared/fragment-heavy-media-row.html" %} + {% else %} + {% include "idiomatic/tera/shared/fragment-heavy-stat.html" %} + {% endif %} + {% endfor %} +
      diff --git a/benchmarks/rust/templates/idiomatic/tera/large-loop.html b/benchmarks/rust/templates/idiomatic/tera/large-loop.html new file mode 100644 index 00000000..bba78005 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/large-loop.html @@ -0,0 +1,10 @@ +{# Idiomatic Tera template. Patterns follow the Tera docs + (keats.github.io/tera): "Control structures - For loops"; default auto-escaping on. + The display name is template-composed as the literal `row-` + the value substitution + (the model carries data only). #} +{% for item in items %} + + row-{{ item.value }} + {{ item.value }} + +{% endfor %} diff --git a/benchmarks/rust/templates/idiomatic/tera/mixed-page.html b/benchmarks/rust/templates/idiomatic/tera/mixed-page.html new file mode 100644 index 00000000..0ab9c685 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/mixed-page.html @@ -0,0 +1,50 @@ +{# Idiomatic Tera template the realistic mixed page, single-file by + rule - layout composition is composed-page's dimension, so this page deliberately does + NOT extend a base. Patterns follow the Tera docs + (keats.github.io/tera): "Variables", "Control structures - If" and "Control structures - + For loops"; default auto-escaping left on (model values contain no escapables). The + display SKU is template-composed as `MX-` + sku_number and the blurb sentence around the + batch substitution. #} + + + + + {{ page_title }} + + + +
      +

      {{ store_name }}

      + +
      +
      + {% if show_banner %} + + {% endif %} +
      +

      {{ hero_heading }}

      +

      {{ hero_tagline }}

      +
      +
      + {% for p in products %} +
      +

      {{ p.name }}

      +

      MX-{{ p.sku_number }}

      +

      {{ p.price }}

      + {% if p.on_sale %} +

      On sale

      + {% endif %} +

      A dependable workshop staple from batch {{ p.batch }}, checked for daily use and backed by our lifetime guarantee.

      +
      + {% endfor %} +
      + {% if show_debug_panel %} +
      debug
      + {% endif %} +
      +
      +

      {{ footer_note }}

      +

      {{ store_name }} {{ year }} {{ support_email }}

      +
      + + diff --git a/benchmarks/rust/templates/idiomatic/tera/nav/column.html b/benchmarks/rust/templates/idiomatic/tera/nav/column.html new file mode 100644 index 00000000..06451084 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/nav/column.html @@ -0,0 +1,9 @@ +{# Idiomatic Tera nav partial one navigation column - included per + mega-menu dropdown column and per footer column. Patterns follow the Tera docs + (keats.github.io/tera): "Include" and "Control structures - For loops"; default + auto-escaping left on. #} + diff --git a/benchmarks/rust/templates/idiomatic/tera/nav/link.html b/benchmarks/rust/templates/idiomatic/tera/nav/link.html new file mode 100644 index 00000000..4a8a3a75 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/nav/link.html @@ -0,0 +1,5 @@ +{# Idiomatic Tera nav partial one navigation link. Patterns follow + the Tera docs (keats.github.io/tera): "Include" (partial rendered with the including + scope's current context, referencing its loop variable); default auto-escaping left on + (nav values contain no characters HTML escaping rewrites, so escaping is byte-neutral). #} + diff --git a/benchmarks/rust/templates/idiomatic/tera/nav/mega-menu.html b/benchmarks/rust/templates/idiomatic/tera/nav/mega-menu.html new file mode 100644 index 00000000..031725dc --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/nav/mega-menu.html @@ -0,0 +1,21 @@ +{# Idiomatic Tera nav partial one mega menu - its tab bar plus the + per-tab dropdown columns (menu -> column -> section -> link, the nested-partial chain). + Patterns follow the Tera docs (keats.github.io/tera): "Include", "Control structures - + For loops" and "Control structures - If" (precomputed has_dropdown boolean); default + auto-escaping left on. #} +
      +
        + {% for tab in menu.tabs %} +
      • + {{ tab.label }} + {% if tab.has_dropdown %} +
        + {% for column in tab.columns %} + {% include "idiomatic/tera/nav/column.html" %} + {% endfor %} +
        + {% endif %} +
      • + {% endfor %} +
      +
      diff --git a/benchmarks/rust/templates/idiomatic/tera/nav/section.html b/benchmarks/rust/templates/idiomatic/tera/nav/section.html new file mode 100644 index 00000000..2a4c823d --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/nav/section.html @@ -0,0 +1,16 @@ +{# Idiomatic Tera nav partial one navigation section - an optionally + linked title plus its link list. Patterns follow the Tera docs (keats.github.io/tera): + "Include", "Control structures - If" (precomputed title_linked boolean) and + "Control structures - For loops"; default auto-escaping left on. #} + diff --git a/benchmarks/rust/templates/idiomatic/tera/shared/composed-page-base.html b/benchmarks/rust/templates/idiomatic/tera/shared/composed-page-base.html new file mode 100644 index 00000000..a54a2352 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/shared/composed-page-base.html @@ -0,0 +1,142 @@ +{# Idiomatic Tera base template the full-page layout chrome. + Patterns follow the Tera docs (keats.github.io/tera): "Inheritance" (base template with a + live body block and overridable section-default blocks - meta, socialmeta, page_scripts, + endpage_scripts), "Include" (the inert chrome fragments under chrome/ and the nested + nav partial chain under nav/) and "Control structures - For loops" + (the two mega menus from nav.menus, the four footer columns from nav.footer_columns). + Default auto-escaping left on - nav values contain no characters HTML escaping rewrites, so escaping + is byte-neutral, and the chrome is literal template text autoescape never touches. #} + + + + + + + + + + {% block meta %}Title{% endblock %} + {% block socialmeta %} + + + + {% endblock %} + + + + + + {% include "idiomatic/tera/chrome/assets-styles.html" %} + + {% include "idiomatic/tera/chrome/head-scripts.html" %} + + + {% include "idiomatic/tera/chrome/body-scripts.html" %} +
      +
      + +
      +
      +
      +
      + {% include "idiomatic/tera/chrome/alert-top.html" %} +
      +
      +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + +
      +
      + +
      +
      +
      + + {% for menu in nav.menus %} + {% include "idiomatic/tera/nav/mega-menu.html" %} + {% endfor %} +
      +
      +
      + {% include "idiomatic/tera/chrome/alert-below.html" %} +
      +
      + {% block body %}{% endblock %} +
      +
      +
      +
      +
      + +
      +
      + {% include "idiomatic/tera/chrome/assets-scripts.html" %} + + {% block page_scripts %}{% endblock %} + {% block endpage_scripts %}{% endblock %} + {% include "idiomatic/tera/chrome/body-end-scripts.html" %} + + diff --git a/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-badge.html b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-badge.html new file mode 100644 index 00000000..7a5bf833 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-badge.html @@ -0,0 +1,5 @@ +{# Idiomatic Tera badge sub-partial rendered by the card partial + against the row's promo - one of the two nested calls that prove the nesting level ran + . Patterns follow the Tera docs (keats.github.io/tera): "Include" (nested + include reading the current context); default auto-escaping left on. #} +{{ item.promo.label }} diff --git a/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-card.html b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-card.html new file mode 100644 index 00000000..527fde3e --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-card.html @@ -0,0 +1,10 @@ +{# Idiomatic Tera card partial the one fragment kind with nested + composition - it renders the badge and price sub-partials against the row's promo + . Patterns follow the Tera docs (keats.github.io/tera): "Include" (nested + includes rendered with the current context); default auto-escaping left on. #} +
      +

      {{ item.name }}

      + {% include "idiomatic/tera/shared/fragment-heavy-badge.html" %} + {% include "idiomatic/tera/shared/fragment-heavy-price.html" %} +

      {{ item.value }}

      +
      diff --git a/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-media-row.html b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-media-row.html new file mode 100644 index 00000000..898a0ac6 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-media-row.html @@ -0,0 +1,11 @@ +{# Idiomatic Tera media-row partial. The image source and caption are + template-composed as `/img/` + name + `.jpg` and `Caption for ` + name (the + model carries data, never display strings). Patterns follow the Tera docs + (keats.github.io/tera): "Include"; default auto-escaping left on. #} +
      + {{ item.name }} +
      +

      {{ item.name }}

      +

      Caption for {{ item.name }}

      +
      +
      diff --git a/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-price.html b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-price.html new file mode 100644 index 00000000..b7ab4066 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-price.html @@ -0,0 +1,6 @@ +{# Idiomatic Tera price sub-partial rendered by the card partial + against the row's promo. The display price is template-composed as the price substitution + + the literal `.99` (the model carries the int, never the display string). + Patterns follow the Tera docs (keats.github.io/tera): "Include"; default auto-escaping + left on. #} +

      {{ item.promo.price }}.99

      diff --git a/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-stat.html b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-stat.html new file mode 100644 index 00000000..9f5d3bae --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-stat.html @@ -0,0 +1,8 @@ +{# Idiomatic Tera stat partial. Patterns follow the Tera docs + (keats.github.io/tera): "Include" (partial rendered with the including scope's current + context); default auto-escaping left on. #} +
      + {{ item.name }} + {{ item.value }} + {{ item.delta }} +
      diff --git a/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-tile.html b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-tile.html new file mode 100644 index 00000000..0dba2afe --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/shared/fragment-heavy-tile.html @@ -0,0 +1,8 @@ +{# Idiomatic Tera tile partial. Patterns follow the Tera docs + (keats.github.io/tera): "Include" (partial rendered with the including scope's current + context, referencing its loop variable); default auto-escaping left on. #} +
      +

      {{ item.name }}

      +

      {{ item.value }}

      + {{ item.badge }} +
      diff --git a/benchmarks/rust/templates/idiomatic/tera/trivial-substitution.html b/benchmarks/rust/templates/idiomatic/tera/trivial-substitution.html new file mode 100644 index 00000000..37b40167 --- /dev/null +++ b/benchmarks/rust/templates/idiomatic/tera/trivial-substitution.html @@ -0,0 +1,16 @@ +{# Idiomatic Tera template. Patterns follow the Tera docs + (keats.github.io/tera): "Getting started" and "Variables" (expression substitution, + default auto-escaping left on - the pinned values contain no escapable characters). #} +
      +

      {{ title }}

      +

      {{ sku }}

      +

      {{ price }}

      +

      {{ brand }}

      +

      {{ category }}

      +

      {{ availability }}

      + + + +

      {{ summary }}

      +

      {{ rating }}

      +
      diff --git a/src/Heddle.Performance/ThirdParty/.gitattributes b/benchmarks/third-party/.gitattributes similarity index 100% rename from src/Heddle.Performance/ThirdParty/.gitattributes rename to benchmarks/third-party/.gitattributes diff --git a/src/Heddle.Performance/ThirdParty/Heddle.Performance.ThirdParty.csproj b/benchmarks/third-party/Heddle.Benchmarks.ThirdParty.csproj similarity index 96% rename from src/Heddle.Performance/ThirdParty/Heddle.Performance.ThirdParty.csproj rename to benchmarks/third-party/Heddle.Benchmarks.ThirdParty.csproj index c87dc0dc..1bbe0fd9 100644 --- a/src/Heddle.Performance/ThirdParty/Heddle.Performance.ThirdParty.csproj +++ b/benchmarks/third-party/Heddle.Benchmarks.ThirdParty.csproj @@ -27,12 +27,12 @@ feeds; NU5104 is a pack-time advisory and this project never packs (IsPackable=false). --> $(NoWarn);NU5104 Fluid.Benchmarks - Heddle.Performance.ThirdParty + Heddle.Benchmarks.ThirdParty - + diff --git a/src/Heddle.Performance/ThirdParty/HeddleBenchmarks.cs b/benchmarks/third-party/HeddleBenchmarks.cs similarity index 99% rename from src/Heddle.Performance/ThirdParty/HeddleBenchmarks.cs rename to benchmarks/third-party/HeddleBenchmarks.cs index bc661b45..bc42eaed 100644 --- a/src/Heddle.Performance/ThirdParty/HeddleBenchmarks.cs +++ b/benchmarks/third-party/HeddleBenchmarks.cs @@ -8,7 +8,7 @@ using Heddle.Runtime; using Heddle.Runtime.Expressions; -namespace Heddle.Performance.ThirdParty +namespace Heddle.Benchmarks.ThirdParty { /// /// The Heddle entry (D3-R1) for the upstream Fluid product-render scenario. It slots into the diff --git a/src/Heddle.Performance/ThirdParty/HeddleComparisonBenchmarks.cs b/benchmarks/third-party/HeddleComparisonBenchmarks.cs similarity index 84% rename from src/Heddle.Performance/ThirdParty/HeddleComparisonBenchmarks.cs rename to benchmarks/third-party/HeddleComparisonBenchmarks.cs index 08335b20..37934ce0 100644 --- a/src/Heddle.Performance/ThirdParty/HeddleComparisonBenchmarks.cs +++ b/benchmarks/third-party/HeddleComparisonBenchmarks.cs @@ -2,14 +2,16 @@ using BenchmarkDotNet.Configs; using Fluid.Benchmarks; -namespace Heddle.Performance.ThirdParty +namespace Heddle.Benchmarks.ThirdParty { /// /// The head-to-head that adds Heddle to the upstream product-render comparison. It replicates the - /// upstream ComparisonBenchmarks configuration verbatim — , - /// GroupBenchmarksBy(ByCategory), ShortRunJob, Fluid as the Baseline — over the + /// upstream ComparisonBenchmarks configuration — , + /// GroupBenchmarksBy(ByCategory), Fluid as the Baseline — over the /// same Parse and Render categories, and drives each engine through the shared - /// methods (same model, same output oracle). + /// methods (same model, same output oracle). The one budget change + /// from upstream's ShortRunJob: five measurement iterations instead of three, the + /// repo-wide per-run sample floor; warmup and launch counts stay ShortRun's. /// /// Two deliberate differences from upstream ComparisonBenchmarks, both documented in /// ThirdParty/README.md: (1) it adds the Heddle_* rows; (2) it omits Liquid.NET, which @@ -18,7 +20,8 @@ namespace Heddle.Performance.ThirdParty /// ParseBig category is dropped because Heddle (like Handlebars upstream) carries no big-template /// twin. Nothing else about the methodology changes. /// - [MemoryDiagnoser, GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory), ShortRunJob] + [MemoryDiagnoser, GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] + [SimpleJob(launchCount: 1, warmupCount: 3, iterationCount: 5)] public class HeddleComparisonBenchmarks { private readonly FluidBenchmarks _fluidBenchmarks = new FluidBenchmarks(); diff --git a/src/Heddle.Performance/ThirdParty/HeddleFilters.cs b/benchmarks/third-party/HeddleFilters.cs similarity index 96% rename from src/Heddle.Performance/ThirdParty/HeddleFilters.cs rename to benchmarks/third-party/HeddleFilters.cs index 7b635276..1281409c 100644 --- a/src/Heddle.Performance/ThirdParty/HeddleFilters.cs +++ b/benchmarks/third-party/HeddleFilters.cs @@ -1,6 +1,6 @@ using System; -namespace Heddle.Performance.ThirdParty +namespace Heddle.Benchmarks.ThirdParty { /// /// Host functions the Heddle entry registers on its FunctionRegistry (the whole trust diff --git a/src/Heddle.Performance/ThirdParty/HeddleProductModel.cs b/benchmarks/third-party/HeddleProductModel.cs similarity index 95% rename from src/Heddle.Performance/ThirdParty/HeddleProductModel.cs rename to benchmarks/third-party/HeddleProductModel.cs index 125d69ac..ab10f084 100644 --- a/src/Heddle.Performance/ThirdParty/HeddleProductModel.cs +++ b/benchmarks/third-party/HeddleProductModel.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Fluid.Benchmarks; -namespace Heddle.Performance.ThirdParty +namespace Heddle.Benchmarks.ThirdParty { /// /// Typed root model for the Heddle entry. It carries the exact same diff --git a/src/Heddle.Performance/ThirdParty/PREP-UPSTREAM-PR.md b/benchmarks/third-party/PREP-UPSTREAM-PR.md similarity index 100% rename from src/Heddle.Performance/ThirdParty/PREP-UPSTREAM-PR.md rename to benchmarks/third-party/PREP-UPSTREAM-PR.md diff --git a/src/Heddle.Performance/ThirdParty/Parity.cs b/benchmarks/third-party/Parity.cs similarity index 99% rename from src/Heddle.Performance/ThirdParty/Parity.cs rename to benchmarks/third-party/Parity.cs index 5bd735db..65d475dc 100644 --- a/src/Heddle.Performance/ThirdParty/Parity.cs +++ b/benchmarks/third-party/Parity.cs @@ -3,7 +3,7 @@ using System.Text.RegularExpressions; using Fluid.Benchmarks; -namespace Heddle.Performance.ThirdParty +namespace Heddle.Benchmarks.ThirdParty { /// /// D3-R3 parity gate, mirroring D1's discipline: before any numbers are published, the Heddle diff --git a/src/Heddle.Performance/ThirdParty/Program.cs b/benchmarks/third-party/Program.cs similarity index 80% rename from src/Heddle.Performance/ThirdParty/Program.cs rename to benchmarks/third-party/Program.cs index aee001b8..97e442ce 100644 --- a/src/Heddle.Performance/ThirdParty/Program.cs +++ b/benchmarks/third-party/Program.cs @@ -2,7 +2,7 @@ using System.Globalization; using BenchmarkDotNet.Running; -namespace Heddle.Performance.ThirdParty +namespace Heddle.Benchmarks.ThirdParty { internal static class Program { @@ -14,7 +14,7 @@ private static int Main(string[] args) // Fast, host-free parity self-test (D3-R3): confirms the Heddle entry renders the scenario's // expected output (matched against Fluid rendering the unmodified product.liquid, and against // every engine's CheckBenchmark oracle) without spinning up the full BenchmarkDotNet run. - // dotnet run -c Release --project src/Heddle.Performance/ThirdParty -- parity + // dotnet run -c Release --project benchmarks/third-party -- parity if (args != null && args.Length > 0 && string.Equals(args[0], "parity", StringComparison.OrdinalIgnoreCase)) { @@ -24,7 +24,7 @@ private static int Main(string[] args) } // Prints the Heddle entry's rendered output (for eyeballing the scenario shape). - // dotnet run -c Release --project src/Heddle.Performance/ThirdParty -- dump + // dotnet run -c Release --project benchmarks/third-party -- dump if (args != null && args.Length > 0 && string.Equals(args[0], "dump", StringComparison.OrdinalIgnoreCase)) { @@ -33,7 +33,7 @@ private static int Main(string[] args) } // Otherwise defer to BenchmarkDotNet, e.g.: - // dotnet run -c Release --project src/Heddle.Performance/ThirdParty -- --filter *HeddleComparisonBenchmarks* + // dotnet run -c Release --project benchmarks/third-party -- --filter *HeddleComparisonBenchmarks* BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); return 0; } diff --git a/src/Heddle.Performance/ThirdParty/README.md b/benchmarks/third-party/README.md similarity index 94% rename from src/Heddle.Performance/ThirdParty/README.md rename to benchmarks/third-party/README.md index f7b6441e..01e5acd8 100644 --- a/src/Heddle.Performance/ThirdParty/README.md +++ b/benchmarks/third-party/README.md @@ -14,7 +14,7 @@ PR (the D3-R1 deliverable) is prepared-but-not-submitted. See | Benchmark project | `Fluid.Benchmarks/` (at the repo root) | | **Commit SHA** | `1fa7c0bc0d86b51279272da4438a802650b8a89b` | | Commit date | 2026-06-22 | -| Methodology | BenchmarkDotNet `0.15.8`, `[MemoryDiagnoser]`, `ShortRunJob`, `GroupBenchmarksBy(ByCategory)` | +| Methodology | BenchmarkDotNet `0.15.8`, `[MemoryDiagnoser]`, `SimpleJob(launchCount: 1, warmupCount: 3, iterationCount: 5)` (upstream's `ShortRunJob` with the repo-wide five-sample floor, E28), `GroupBenchmarksBy(ByCategory)` | ## Tracking status (D3-R4) @@ -152,16 +152,16 @@ repo-root change outside this work item's scope). Build and run it directly: ```bash # build (warning-clean) -dotnet build src/Heddle.Performance/ThirdParty/Heddle.Performance.ThirdParty.csproj -c Release +dotnet build benchmarks/third-party/Heddle.Benchmarks.ThirdParty.csproj -c Release # fast, host-free parity self-test (proves the Heddle entry renders the scenario's expected output) -dotnet run -c Release --project src/Heddle.Performance/ThirdParty -- parity +dotnet run -c Release --project benchmarks/third-party -- parity # eyeball the Heddle-rendered scenario -dotnet run -c Release --project src/Heddle.Performance/ThirdParty -- dump +dotnet run -c Release --project benchmarks/third-party -- dump # the full head-to-head (BenchmarkDotNet; writes to ./BenchmarkDotNet.Artifacts under this folder) -dotnet run -c Release --project src/Heddle.Performance/ThirdParty -- --filter *HeddleComparisonBenchmarks* +dotnet run -c Release --project benchmarks/third-party -- --filter *HeddleComparisonBenchmarks* ``` ## Re-syncing the vendored files diff --git a/src/Heddle.Performance/ThirdParty/THIRD-PARTY-NOTICES.md b/benchmarks/third-party/THIRD-PARTY-NOTICES.md similarity index 100% rename from src/Heddle.Performance/ThirdParty/THIRD-PARTY-NOTICES.md rename to benchmarks/third-party/THIRD-PARTY-NOTICES.md diff --git a/src/Heddle.Performance/ThirdParty/Vendor/BaseBenchmarks.cs b/benchmarks/third-party/Vendor/BaseBenchmarks.cs similarity index 100% rename from src/Heddle.Performance/ThirdParty/Vendor/BaseBenchmarks.cs rename to benchmarks/third-party/Vendor/BaseBenchmarks.cs diff --git a/src/Heddle.Performance/ThirdParty/Vendor/DotLiquidBenchmarks.cs b/benchmarks/third-party/Vendor/DotLiquidBenchmarks.cs similarity index 100% rename from src/Heddle.Performance/ThirdParty/Vendor/DotLiquidBenchmarks.cs rename to benchmarks/third-party/Vendor/DotLiquidBenchmarks.cs diff --git a/src/Heddle.Performance/ThirdParty/Vendor/FluidBenchmarks.cs b/benchmarks/third-party/Vendor/FluidBenchmarks.cs similarity index 100% rename from src/Heddle.Performance/ThirdParty/Vendor/FluidBenchmarks.cs rename to benchmarks/third-party/Vendor/FluidBenchmarks.cs diff --git a/src/Heddle.Performance/ThirdParty/Vendor/HandlebarsBenchmarks.cs b/benchmarks/third-party/Vendor/HandlebarsBenchmarks.cs similarity index 100% rename from src/Heddle.Performance/ThirdParty/Vendor/HandlebarsBenchmarks.cs rename to benchmarks/third-party/Vendor/HandlebarsBenchmarks.cs diff --git a/src/Heddle.Performance/ThirdParty/Vendor/Product.cs b/benchmarks/third-party/Vendor/Product.cs similarity index 100% rename from src/Heddle.Performance/ThirdParty/Vendor/Product.cs rename to benchmarks/third-party/Vendor/Product.cs diff --git a/src/Heddle.Performance/ThirdParty/Vendor/ScribanBenchmarks.cs b/benchmarks/third-party/Vendor/ScribanBenchmarks.cs similarity index 100% rename from src/Heddle.Performance/ThirdParty/Vendor/ScribanBenchmarks.cs rename to benchmarks/third-party/Vendor/ScribanBenchmarks.cs diff --git a/src/Heddle.Performance/ThirdParty/Vendor/blogpost.liquid b/benchmarks/third-party/Vendor/blogpost.liquid similarity index 100% rename from src/Heddle.Performance/ThirdParty/Vendor/blogpost.liquid rename to benchmarks/third-party/Vendor/blogpost.liquid diff --git a/src/Heddle.Performance/ThirdParty/Vendor/product.liquid b/benchmarks/third-party/Vendor/product.liquid similarity index 100% rename from src/Heddle.Performance/ThirdParty/Vendor/product.liquid rename to benchmarks/third-party/Vendor/product.liquid diff --git a/src/Heddle.Performance/ThirdParty/Vendor/product.mustache b/benchmarks/third-party/Vendor/product.mustache similarity index 100% rename from src/Heddle.Performance/ThirdParty/Vendor/product.mustache rename to benchmarks/third-party/Vendor/product.mustache diff --git a/src/Heddle.Performance/ThirdParty/product.heddle b/benchmarks/third-party/product.heddle similarity index 100% rename from src/Heddle.Performance/ThirdParty/product.heddle rename to benchmarks/third-party/product.heddle diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 7e0f05ed..52e8f0de 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -47,7 +47,15 @@ export default withMermaid( // any legacy contributor material that may return. srcExclude: [ 'archive/**', - 'spec/**' + 'spec/**', + // Raw harness artifacts committed alongside the benchmark reports. They are markdown + // (BenchmarkDotNet's `-report-github.md` export) but they are evidence, not pages: + // publishing them adds a dozen near-identical routes and floods local search. The + // reports' own index.md links them, and GitHub renders them at the source path. + 'benchmarks/*/dotnet/**' + // summary-tables.md is generated by benchmarks/report/consolidate.py and embedded into the + // report's index.md with ``, but it is NOT excluded here: the Benchmarks + // sidebar links it as its own page, and an excluded source would turn that entry into a 404. ], markdown: { @@ -137,6 +145,17 @@ export default withMermaid( { text: 'Syntax Highlighting', link: '/syntax-highlighting' }, { text: 'Building & Testing', link: '/building' } ] + }, + { + text: 'Benchmarks', + collapsed: true, + items: [ + // docs/benchmarks keeps the latest run only, so this group always + // lists exactly one report: the index plus its two generated table pages. + { text: '2026-08-08 (Windows protocol run)', link: '/benchmarks/2026-08-08/' }, + { text: '· consolidated tables', link: '/benchmarks/2026-08-08/consolidated-tables' }, + { text: '· summary tables', link: '/benchmarks/2026-08-08/summary-tables' } + ] } ], search: { provider: 'local' }, diff --git a/docs/README.md b/docs/README.md index 18108377..207910a1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,7 +16,7 @@ The engine is published as a set of NuGet packages: | `Heddle.LanguageServer` | [src/Heddle.LanguageServer](../src/Heddle.LanguageServer) | LSP server for editors, shipped as a `dotnet tool` (`heddle-lsp`). | | `Heddle.Tool` | [src/Heddle.Tool](../src/Heddle.Tool) | The `heddle` CLI — a `dotnet tool` for rendering templates and build‑time code generation (the T4 successor). | -Current release line: **2.0.0**. The published version is set from the latest +Current release line: **2.1.0**. The published version is set from the latest [release tag](https://github.com/multiarc/Heddle/releases) (`vX.Y.Z`) at publish time — see [nuget.org](https://www.nuget.org/packages/Heddle) — so the version in the source tree is just a placeholder. @@ -35,7 +35,7 @@ tree is just a placeholder. like‑for‑like comparison is against the four parity‑checked Liquid/Handlebars engines, which Heddle leads on render time and where it allocates the least or tied‑least memory — Handlebars.Net is within ~0.3 KB). See [Architecture → Performance](architecture.md#performance-characteristics) - and the [benchmark project](../src/Heddle.Performance). + and the [benchmark harnesses](../benchmarks/README.md). - **Composable without coupling.** Reusable templates are declarative extension points, so a page can be split into independent pieces recombined by a layout — at no runtime cost — and any page can serve as a base for another. See @@ -108,7 +108,7 @@ Roslyn code generation, lexer modes) and **[Building & Testing](building.md)**. ``` ```csharp -HeddleTemplate.Configure(typeof(Program).Assembly); +HeddleTemplate.Register(typeof(Program).Assembly); var source = "@model(){{dynamic}}\n

      Hi @(Name) — you have @int(Count) new comments.

      "; using var template = new HeddleTemplate(source, new CompileContext(new TemplateOptions())); diff --git a/docs/architecture.md b/docs/architecture.md index 5969b76a..943189e8 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -155,8 +155,9 @@ DLR call sites (see below). ([`CompiledParameter`](../src/Heddle/Runtime/Parameters/CompiledParameter.cs)). This is also where C# expressions are **bound to the model's types**; the [`CompileScope`](../src/Heddle/Runtime)/`CSharpContext` track imported namespaces - (`@using`) and the model type (`@model`, `:: Type`). `CompileScope.Compile()` runs that - Roslyn pass. + (`@using`) and the model type (`@model`, `:: Type`). The Roslyn pass is run by + `ContextCompilation.Compile`, an internal extension method over `CompileScope` — not a member of + `CompileScope`, which exposes no compile entry point of its own. - Errors from either path are collected as `HeddleCompileError`s rather than thrown, and surfaced through [`HeddleCompileResult`](../src/Heddle/Data/HeddleCompileResult.cs). @@ -186,16 +187,21 @@ length‑based on net8+ and count‑based on older targets). ## Performance characteristics -The repository's [BenchmarkDotNet suite](../src/Heddle.Performance) measures Heddle against four -other .NET template engines (Fluid, Scriban, DotLiquid, Handlebars.Net) — all four rendering -byte‑identical parity‑checked output over a component‑heavy composition workload — plus ASP.NET Core -Razor, which renders a larger, different page and is **not** under the parity assertion -(`[MemoryDiagnoser]` enabled). In the run of **2026‑07‑11** (commit `8341bb67`; AMD Ryzen 9 9950X, +The repository's [BenchmarkDotNet suite](../benchmarks/dotnet) measures Heddle against five +other .NET template engines (Fluid, Scriban, DotLiquid, Handlebars.Net and ASP.NET Core Razor) over +a component‑heavy composition workload, every one of them rendering byte‑identical parity‑checked +output (`[MemoryDiagnoser]` enabled). Razor joined the parity assertion on 2026‑07‑25 +(benchmarks amendment E5); before that it rendered a larger, +different page outside every gate. The published +2026‑07‑25 cross‑stack run is the first to measure it under parity: +**Heddle 30.52 μs vs Razor 41.66 μs**, with Heddle fastest of all six .NET engines on that +workload. The 2026‑07‑11 figures below are the older intra‑.NET record, and their Razor pairing +describes the pre‑parity workload. In the run of **2026‑07‑11** (commit `8341bb67`; AMD Ryzen 9 9950X, .NET 10.0.9, BenchmarkDotNet 0.15.8) Heddle rendered that page in **32.50 μs / 227.86 KB** — the fastest of the six and tied‑least on allocation (within 0.3 KB of Handlebars.Net); the next engine (Fluid) took 2.0× as long and Scriban 11.7× with 5.07× the allocation. The full render and compile‑cost tables, environment header, and raw artifacts live in the [README Performance section](../README.md#performance) and -[docs/benchmarks/2026-07-11](benchmarks/2026-07-11/). The reasons Heddle leads on the render path are +docs/benchmarks/2026-07-11. The reasons Heddle leads on the render path are structural, not incidental: - **Execution‑ready document, not per‑call activation.** Each template becomes a @@ -214,7 +220,7 @@ structural, not incidental: `[MethodImpl(AggressiveInlining)]` transforms, avoiding per‑scope heap allocation as the renderer descends into elements and subtemplates. - **Composition is near‑free at run time.** Splitting a page into independent reusable templates - recombined by a layout (see the benchmark's `@<<{{layout.heddle}}` import + `` + recombined by a layout (see the benchmark's `@<<{{shared/layout.heddle}}` import + `` override) renders through one pre‑built extension node per definition invocation — no per‑render lookup, activation, or buffer indirection — unlike Razor sections, whose layout/section binding adds indirection. See @@ -225,9 +231,9 @@ compilation (member accessors), and Roslyn (embedded C#), so it is not cheap — "compile once, render many." In the same 2026‑07‑11 run, cold‑compiling the layout + home templates took **264.99 μs / 1,339.67 KB** for Heddle versus single‑digit microseconds for the Liquid engines (Fluid 3.65 μs, Scriban 4.68 μs, DotLiquid 7.21 μs) — a cost amortized across every -cached render. Compile cost is benchmarked via -[TemplateParseBenchmarks](../src/Heddle.Performance/TemplateParseBenchmarks.cs) and the runners in -[src/Heddle.Performance/Runners](../src/Heddle.Performance/Runners/README.md); full table in the +cached render. Compile cost is benchmarked by the harness's cold sidebar +(`dotnet run -c Release --project benchmarks/dotnet -- bench-cold`), which measures parse and +compile as separate rows because they are separate steps; full table in the [README](../README.md#performance). --- @@ -247,7 +253,7 @@ cached render. Compile cost is benchmarked via | `Heddle/LanguageTemplates` | `.tcs` resources used to emit C# for Roslyn. | | [src/Heddle.Language](../src/Heddle.Language) | ANTLR grammar + generated lexer/parser + editor assets. | | [src/Heddle.Tests](../src/Heddle.Tests) | xUnit tests + `.heddle` fixtures. | -| [src/Heddle.Performance](../src/Heddle.Performance) | BenchmarkDotNet benchmarks. | +| [benchmarks/dotnet](../benchmarks/dotnet) | BenchmarkDotNet benchmarks — the cross-stack .NET leg. Not in `Heddle.sln`. | --- diff --git a/docs/benchmarks/2026-07-11/Heddle.Performance.TemplateParseBenchmarks-report-github.md b/docs/benchmarks/2026-07-11/Heddle.Performance.TemplateParseBenchmarks-report-github.md deleted file mode 100644 index 70ed7a65..00000000 --- a/docs/benchmarks/2026-07-11/Heddle.Performance.TemplateParseBenchmarks-report-github.md +++ /dev/null @@ -1,17 +0,0 @@ -``` - -BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8655/25H2/2025Update/HudsonValley2) -AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores -.NET SDK 10.0.301 - [Host] : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4 - DefaultJob : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4 - - -``` -| Method | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio | -|---------------- |-------------:|------------:|------------:|-------------:|------:|--------:|--------:|--------:|-----------:|------------:| -| ParseHeddle | 264.985 μs | 1.1301 μs | 0.9437 μs | 264.826 μs | 1.00 | 0.00 | 81.5430 | 27.3438 | 1339.67 KB | 1.000 | -| ParseFluid | 3.653 μs | 0.0725 μs | 0.1680 μs | 3.571 μs | 0.01 | 0.00 | 0.3204 | - | 5.31 KB | 0.004 | -| ParseScriban | 4.684 μs | 0.0926 μs | 0.0866 μs | 4.626 μs | 0.02 | 0.00 | 1.4038 | 0.0763 | 22.95 KB | 0.017 | -| ParseDotLiquid | 7.208 μs | 0.1000 μs | 0.0886 μs | 7.165 μs | 0.03 | 0.00 | 2.1973 | 0.0305 | 36.01 KB | 0.027 | -| ParseHandlebars | 8,287.089 μs | 151.0238 μs | 126.1118 μs | 8,213.741 μs | 31.27 | 0.47 | 15.6250 | - | 260.65 KB | 0.195 | diff --git a/docs/benchmarks/2026-07-11/Heddle.Performance.TemplateParseBenchmarks-report.csv b/docs/benchmarks/2026-07-11/Heddle.Performance.TemplateParseBenchmarks-report.csv deleted file mode 100644 index f9c4dae7..00000000 --- a/docs/benchmarks/2026-07-11/Heddle.Performance.TemplateParseBenchmarks-report.csv +++ /dev/null @@ -1,6 +0,0 @@ -Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Median,Ratio,RatioSD,Gen0,Gen1,Allocated,Alloc Ratio -ParseHeddle,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,264.985 μs,1.1301 μs,0.9437 μs,264.826 μs,1.00,0.00,81.5430,27.3438,1339.67 KB,1.000 -ParseFluid,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,3.653 μs,0.0725 μs,0.1680 μs,3.571 μs,0.01,0.00,0.3204,0.0000,5.31 KB,0.004 -ParseScriban,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,4.684 μs,0.0926 μs,0.0866 μs,4.626 μs,0.02,0.00,1.4038,0.0763,22.95 KB,0.017 -ParseDotLiquid,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,7.208 μs,0.1000 μs,0.0886 μs,7.165 μs,0.03,0.00,2.1973,0.0305,36.01 KB,0.027 -ParseHandlebars,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,"8,287.089 μs",151.0238 μs,126.1118 μs,"8,213.741 μs",31.27,0.47,15.6250,0.0000,260.65 KB,0.195 diff --git a/docs/benchmarks/2026-07-11/Heddle.Performance.TemplateParseBenchmarks-report.html b/docs/benchmarks/2026-07-11/Heddle.Performance.TemplateParseBenchmarks-report.html deleted file mode 100644 index 238e77af..00000000 --- a/docs/benchmarks/2026-07-11/Heddle.Performance.TemplateParseBenchmarks-report.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - -Heddle.Performance.TemplateParseBenchmarks-20260711-200945 - - - - -
      
      -BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8655/25H2/2025Update/HudsonValley2)
      -AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      -.NET SDK 10.0.301
      -  [Host]     : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4
      -  DefaultJob : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4
      -
      -
      - - - - - - - - - -
      Method Mean ErrorStdDevMedianRatioRatioSDGen0Gen1AllocatedAlloc Ratio
      ParseHeddle264.985 μs1.1301 μs0.9437 μs264.826 μs1.000.0081.543027.34381339.67 KB1.000
      ParseFluid3.653 μs0.0725 μs0.1680 μs3.571 μs0.010.000.3204-5.31 KB0.004
      ParseScriban4.684 μs0.0926 μs0.0866 μs4.626 μs0.020.001.40380.076322.95 KB0.017
      ParseDotLiquid7.208 μs0.1000 μs0.0886 μs7.165 μs0.030.002.19730.030536.01 KB0.027
      ParseHandlebars8,287.089 μs151.0238 μs126.1118 μs8,213.741 μs31.270.4715.6250-260.65 KB0.195
      - - diff --git a/docs/benchmarks/2026-07-11/Heddle.Performance.TextRenderBenchmarks-report-github.md b/docs/benchmarks/2026-07-11/Heddle.Performance.TextRenderBenchmarks-report-github.md deleted file mode 100644 index 8e08138b..00000000 --- a/docs/benchmarks/2026-07-11/Heddle.Performance.TextRenderBenchmarks-report-github.md +++ /dev/null @@ -1,18 +0,0 @@ -``` - -BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8655/25H2/2025Update/HudsonValley2) -AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores -.NET SDK 10.0.301 - [Host] : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4 - DefaultJob : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4 - - -``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | -|--------------------- |----------:|---------:|----------:|------:|--------:|--------:|--------:|--------:|-----------:|------------:| -| RenderTemplateEngine | 32.50 μs | 1.199 μs | 3.535 μs | 1.01 | 0.15 | 2.6245 | 2.6245 | 2.6245 | 227.86 KB | 1.00 | -| RenderRazor | 65.55 μs | 3.613 μs | 10.653 μs | 2.04 | 0.40 | 9.0332 | 2.4414 | 0.2441 | 263.51 KB | 1.16 | -| RenderFluid | 64.88 μs | 1.281 μs | 2.838 μs | 2.02 | 0.23 | 11.2305 | 5.6152 | 3.7842 | 231.98 KB | 1.02 | -| RenderScriban | 376.71 μs | 7.944 μs | 23.422 μs | 11.73 | 1.44 | 59.5703 | 24.4141 | 16.6016 | 1154.34 KB | 5.07 | -| RenderDotLiquid | 178.21 μs | 3.549 μs | 7.087 μs | 5.55 | 0.63 | 19.0430 | 10.4980 | 7.5684 | 404.69 KB | 1.78 | -| RenderHandlebars | 69.76 μs | 1.359 μs | 3.898 μs | 2.17 | 0.26 | 11.1084 | 5.6152 | 3.9063 | 227.59 KB | 1.00 | diff --git a/docs/benchmarks/2026-07-11/Heddle.Performance.TextRenderBenchmarks-report.csv b/docs/benchmarks/2026-07-11/Heddle.Performance.TextRenderBenchmarks-report.csv deleted file mode 100644 index 2bcd19f0..00000000 --- a/docs/benchmarks/2026-07-11/Heddle.Performance.TextRenderBenchmarks-report.csv +++ /dev/null @@ -1,7 +0,0 @@ -Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Gen2,Allocated,Alloc Ratio -RenderTemplateEngine,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,32.50 μs,1.199 μs,3.535 μs,1.01,0.15,2.6245,2.6245,2.6245,227.86 KB,1.00 -RenderRazor,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,65.55 μs,3.613 μs,10.653 μs,2.04,0.40,9.0332,2.4414,0.2441,263.51 KB,1.16 -RenderFluid,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,64.88 μs,1.281 μs,2.838 μs,2.02,0.23,11.2305,5.6152,3.7842,231.98 KB,1.02 -RenderScriban,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,376.71 μs,7.944 μs,23.422 μs,11.73,1.44,59.5703,24.4141,16.6016,1154.34 KB,5.07 -RenderDotLiquid,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,178.21 μs,3.549 μs,7.087 μs,5.55,0.63,19.0430,10.4980,7.5684,404.69 KB,1.78 -RenderHandlebars,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,69.76 μs,1.359 μs,3.898 μs,2.17,0.26,11.1084,5.6152,3.9063,227.59 KB,1.00 diff --git a/docs/benchmarks/2026-07-11/Heddle.Performance.TextRenderBenchmarks-report.html b/docs/benchmarks/2026-07-11/Heddle.Performance.TextRenderBenchmarks-report.html deleted file mode 100644 index f3e6c11c..00000000 --- a/docs/benchmarks/2026-07-11/Heddle.Performance.TextRenderBenchmarks-report.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - -Heddle.Performance.TextRenderBenchmarks-20260711-200352 - - - - -
      
      -BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8655/25H2/2025Update/HudsonValley2)
      -AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      -.NET SDK 10.0.301
      -  [Host]     : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4
      -  DefaultJob : .NET 10.0.9 (10.0.9, 10.0.926.27113), X64 RyuJIT x86-64-v4
      -
      -
      - - - - - - - - - - -
      Method MeanErrorStdDevRatioRatioSDGen0Gen1Gen2AllocatedAlloc Ratio
      RenderTemplateEngine32.50 μs1.199 μs3.535 μs1.010.152.62452.62452.6245227.86 KB1.00
      RenderRazor65.55 μs3.613 μs10.653 μs2.040.409.03322.44140.2441263.51 KB1.16
      RenderFluid64.88 μs1.281 μs2.838 μs2.020.2311.23055.61523.7842231.98 KB1.02
      RenderScriban376.71 μs7.944 μs23.422 μs11.731.4459.570324.414116.60161154.34 KB5.07
      RenderDotLiquid178.21 μs3.549 μs7.087 μs5.550.6319.043010.49807.5684404.69 KB1.78
      RenderHandlebars69.76 μs1.359 μs3.898 μs2.170.2611.10845.61523.9063227.59 KB1.00
      - - diff --git a/docs/benchmarks/2026-07-11/index.md b/docs/benchmarks/2026-07-11/index.md deleted file mode 100644 index 2c55b1bb..00000000 --- a/docs/benchmarks/2026-07-11/index.md +++ /dev/null @@ -1,28 +0,0 @@ -# Benchmark run — 2026-07-11 - -Raw [BenchmarkDotNet](https://benchmarkdotnet.org/) artifacts for the Heddle competitor -head-to-head (D1/D2). Reproduce with `dotnet run -c Release --project src/Heddle.Performance`. - -## Environment - -``` -BenchmarkDotNet v0.15.8 · Windows 11 (10.0.26200.8655/25H2) -AMD Ryzen 9 9950X 4.30GHz, 16 physical / 32 logical cores -.NET SDK 10.0.301 · .NET 10.0.9 runtime, X64 RyuJIT x86-64-v4 -Commit 8341bb67 -``` - -The formatted results tables (render + compile) with ratios live in the -[README Performance section](../../../README.md#performance). The parity contract that makes the -comparison apples-to-apples is documented in -[src/Heddle.Performance/Runners](../../../src/Heddle.Performance/Runners/README.md). - -## Files - -Each suite has a rendered Markdown report (linked) plus `-report.csv` and `-report.html` -siblings in this directory. - -- Render — [`Heddle.Performance.TextRenderBenchmarks-report-github.md`](./Heddle.Performance.TextRenderBenchmarks-report-github.md) - (+ `Heddle.Performance.TextRenderBenchmarks-report.csv`, `Heddle.Performance.TextRenderBenchmarks-report.html`) -- Compile — [`Heddle.Performance.TemplateParseBenchmarks-report-github.md`](./Heddle.Performance.TemplateParseBenchmarks-report-github.md) - (+ `Heddle.Performance.TemplateParseBenchmarks-report.csv`, `Heddle.Performance.TemplateParseBenchmarks-report.html`) diff --git a/docs/benchmarks/2026-07-18/Heddle.Performance.LoopRenderBenchmarks-report-github.md b/docs/benchmarks/2026-07-18/Heddle.Performance.LoopRenderBenchmarks-report-github.md deleted file mode 100644 index c303e2b6..00000000 --- a/docs/benchmarks/2026-07-18/Heddle.Performance.LoopRenderBenchmarks-report-github.md +++ /dev/null @@ -1,17 +0,0 @@ -``` - -BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8875/25H2/2025Update/HudsonValley2) -AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores -.NET SDK 10.0.302 - [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 - DefaultJob : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 - - -``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | -|----------------- |-----------:|---------:|---------:|------:|--------:|----------:|---------:|--------:|----------:|------------:| -| RenderHeddle | 612.9 μs | 3.96 μs | 3.51 μs | 1.00 | 0.01 | 62.5000 | 40.0391 | 40.0391 | 1.14 MB | 1.00 | -| RenderFluid | 976.2 μs | 3.64 μs | 3.40 μs | 1.59 | 0.01 | 98.6328 | 55.6641 | 20.5078 | 1.63 MB | 1.42 | -| RenderScriban | 1,300.1 μs | 9.77 μs | 7.63 μs | 2.12 | 0.02 | 156.2500 | 78.1250 | 39.0625 | 2.72 MB | 2.38 | -| RenderDotLiquid | 4,097.8 μs | 49.66 μs | 46.45 μs | 6.69 | 0.08 | 1050.7813 | 457.0313 | 19.5313 | 16.85 MB | 14.72 | -| RenderHandlebars | 660.4 μs | 11.96 μs | 10.60 μs | 1.08 | 0.02 | 60.5469 | 35.1563 | 20.5078 | 1.01 MB | 0.88 | diff --git a/docs/benchmarks/2026-07-18/Heddle.Performance.LoopRenderBenchmarks-report.csv b/docs/benchmarks/2026-07-18/Heddle.Performance.LoopRenderBenchmarks-report.csv deleted file mode 100644 index b8df0110..00000000 --- a/docs/benchmarks/2026-07-18/Heddle.Performance.LoopRenderBenchmarks-report.csv +++ /dev/null @@ -1,6 +0,0 @@ -Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Gen2,Allocated,Alloc Ratio -RenderHeddle,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,612.9 μs,3.96 μs,3.51 μs,1.00,0.01,62.5000,40.0391,40.0391,1.14 MB,1.00 -RenderFluid,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,976.2 μs,3.64 μs,3.40 μs,1.59,0.01,98.6328,55.6641,20.5078,1.63 MB,1.42 -RenderScriban,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,"1,300.1 μs",9.77 μs,7.63 μs,2.12,0.02,156.2500,78.1250,39.0625,2.72 MB,2.38 -RenderDotLiquid,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,"4,097.8 μs",49.66 μs,46.45 μs,6.69,0.08,1050.7813,457.0313,19.5313,16.85 MB,14.72 -RenderHandlebars,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,660.4 μs,11.96 μs,10.60 μs,1.08,0.02,60.5469,35.1563,20.5078,1.01 MB,0.88 diff --git a/docs/benchmarks/2026-07-18/Heddle.Performance.LoopRenderBenchmarks-report.html b/docs/benchmarks/2026-07-18/Heddle.Performance.LoopRenderBenchmarks-report.html deleted file mode 100644 index 00d14d37..00000000 --- a/docs/benchmarks/2026-07-18/Heddle.Performance.LoopRenderBenchmarks-report.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - -Heddle.Performance.LoopRenderBenchmarks-20260718-193223 - - - - -
      
      -BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8875/25H2/2025Update/HudsonValley2)
      -AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      -.NET SDK 10.0.302
      -  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      -  DefaultJob : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      -
      -
      - - - - - - - - - -
      Method MeanErrorStdDevRatioRatioSDGen0Gen1Gen2AllocatedAlloc Ratio
      RenderHeddle612.9 μs3.96 μs3.51 μs1.000.0162.500040.039140.03911.14 MB1.00
      RenderFluid976.2 μs3.64 μs3.40 μs1.590.0198.632855.664120.50781.63 MB1.42
      RenderScriban1,300.1 μs9.77 μs7.63 μs2.120.02156.250078.125039.06252.72 MB2.38
      RenderDotLiquid4,097.8 μs49.66 μs46.45 μs6.690.081050.7813457.031319.531316.85 MB14.72
      RenderHandlebars660.4 μs11.96 μs10.60 μs1.080.0260.546935.156320.50781.01 MB0.88
      - - diff --git a/docs/benchmarks/2026-07-18/Heddle.Performance.SubstitutionRenderBenchmarks-report-github.md b/docs/benchmarks/2026-07-18/Heddle.Performance.SubstitutionRenderBenchmarks-report-github.md deleted file mode 100644 index c5796266..00000000 --- a/docs/benchmarks/2026-07-18/Heddle.Performance.SubstitutionRenderBenchmarks-report-github.md +++ /dev/null @@ -1,17 +0,0 @@ -``` - -BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8875/25H2/2025Update/HudsonValley2) -AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores -.NET SDK 10.0.302 - [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 - DefaultJob : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 - - -``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio | -|----------------- |-----------:|---------:|----------:|------:|--------:|-------:|-------:|----------:|------------:| -| RenderHeddle | 118.7 ns | 2.26 ns | 2.60 ns | 1.00 | 0.03 | 0.0961 | - | 1608 B | 1.00 | -| RenderFluid | 538.0 ns | 10.12 ns | 9.94 ns | 4.53 | 0.13 | 0.1392 | - | 2344 B | 1.46 | -| RenderScriban | 4,414.0 ns | 88.04 ns | 158.75 ns | 37.20 | 1.54 | 2.0752 | 0.1831 | 35200 B | 21.89 | -| RenderDotLiquid | 2,037.9 ns | 33.40 ns | 37.13 ns | 17.18 | 0.47 | 0.6199 | 0.0038 | 10384 B | 6.46 | -| RenderHandlebars | 398.3 ns | 4.94 ns | 4.38 ns | 3.36 | 0.08 | 0.0439 | - | 736 B | 0.46 | diff --git a/docs/benchmarks/2026-07-18/Heddle.Performance.SubstitutionRenderBenchmarks-report.csv b/docs/benchmarks/2026-07-18/Heddle.Performance.SubstitutionRenderBenchmarks-report.csv deleted file mode 100644 index 3e032b07..00000000 --- a/docs/benchmarks/2026-07-18/Heddle.Performance.SubstitutionRenderBenchmarks-report.csv +++ /dev/null @@ -1,6 +0,0 @@ -Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Allocated,Alloc Ratio -RenderHeddle,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,118.7 ns,2.26 ns,2.60 ns,1.00,0.03,0.0961,0.0000,1608 B,1.00 -RenderFluid,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,538.0 ns,10.12 ns,9.94 ns,4.53,0.13,0.1392,0.0000,2344 B,1.46 -RenderScriban,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,"4,414.0 ns",88.04 ns,158.75 ns,37.20,1.54,2.0752,0.1831,35200 B,21.89 -RenderDotLiquid,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,"2,037.9 ns",33.40 ns,37.13 ns,17.18,0.47,0.6199,0.0038,10384 B,6.46 -RenderHandlebars,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,398.3 ns,4.94 ns,4.38 ns,3.36,0.08,0.0439,0.0000,736 B,0.46 diff --git a/docs/benchmarks/2026-07-18/Heddle.Performance.SubstitutionRenderBenchmarks-report.html b/docs/benchmarks/2026-07-18/Heddle.Performance.SubstitutionRenderBenchmarks-report.html deleted file mode 100644 index 1d112e8d..00000000 --- a/docs/benchmarks/2026-07-18/Heddle.Performance.SubstitutionRenderBenchmarks-report.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - -Heddle.Performance.SubstitutionRenderBenchmarks-20260718-193004 - - - - -
      
      -BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8875/25H2/2025Update/HudsonValley2)
      -AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      -.NET SDK 10.0.302
      -  [Host]     : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      -  DefaultJob : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      -
      -
      - - - - - - - - - -
      Method MeanErrorStdDevRatioRatioSDGen0Gen1AllocatedAlloc Ratio
      RenderHeddle118.7 ns2.26 ns2.60 ns1.000.030.0961-1608 B1.00
      RenderFluid538.0 ns10.12 ns9.94 ns4.530.130.1392-2344 B1.46
      RenderScriban4,414.0 ns88.04 ns158.75 ns37.201.542.07520.183135200 B21.89
      RenderDotLiquid2,037.9 ns33.40 ns37.13 ns17.180.470.61990.003810384 B6.46
      RenderHandlebars398.3 ns4.94 ns4.38 ns3.360.080.0439-736 B0.46
      - - diff --git a/docs/benchmarks/2026-07-18/index.md b/docs/benchmarks/2026-07-18/index.md deleted file mode 100644 index 3220e678..00000000 --- a/docs/benchmarks/2026-07-18/index.md +++ /dev/null @@ -1,69 +0,0 @@ -# Benchmark run — 2026-07-18 - -Raw [BenchmarkDotNet](https://benchmarkdotnet.org/) artifacts for the two phase-5 workload-breadth -suites (trivial-substitution and large-loop), which bracket the composed home page measured in the -[2026-07-11 run](../2026-07-11/index.md). Reproduce with -`dotnet run -c Release --project src/Heddle.Performance -- --filter *SubstitutionRenderBenchmarks*` -(and `*LoopRenderBenchmarks*`). - -## Environment - -``` -BenchmarkDotNet v0.15.8 · Windows 11 (10.0.26200.8875/25H2) -AMD Ryzen 9 9950X 4.30GHz, 16 physical / 32 logical cores -.NET SDK 10.0.302 · .NET 10.0.10 runtime, X64 RyuJIT x86-64-v4 -Commit b83c7150 (working tree) -``` - -## The workloads - -Both workloads render **raw** (`OutputProfile.Text` on Heddle; the non-encoding path on every -twin) under Heddle's default `Native` expression tier, so the comparison measures templating, not -encoding. Each of the four competitor twins (Fluid, Scriban, DotLiquid, Handlebars.Net) is held -**byte-identical after normalization** to the Heddle oracle by a parity assertion that runs -before any timing. The templates are authored whitespace-free, so the normalizer's -whitespace-collapse has nothing to do here; the one difference it reconciles (via its documented -trailing-newline trim) is the single trailing LF the Heddle oracle renders from the `.heddle` -fixture's final newline, which no twin emits. Heddle is the ratio baseline; `[MemoryDiagnoser]` is enabled. - -- **Trivial substitution** (`trivial-substitution.heddle`): one flat card whose output (~338 - chars) is dominated by ten scalar member substitutions with minimal literal glue and **no** - composition — no layout, components, or loop. -- **Large loop** (`large-loop.heddle`): a single `@list` over **5,000** rows, each emitting two - scalar members (~193 KB output) — output dominated by one large iteration. Models for all five - engines are materialized once, so no op re-allocates its model. - -## Results — what this run actually shows - -The language assessment (retired — git history) predicted trivial substitution as the -shape where Heddle's composition advantage narrows or inverts. On this hardware and date the -picture is workload-dependent, and **not uniformly in Heddle's favor**: - -- **Trivial substitution.** Heddle rendered fastest (118.7 ns), but the prediction holds on - **memory**: Handlebars.Net allocated **less than half** of Heddle's bytes per op (736 B vs - 1,608 B — alloc ratio 0.46), so on allocation this workload **inverts** against Heddle. Fluid - was 4.5x on time, DotLiquid 17.2x, Scriban 37.2x. -- **Large loop.** The **time** race is at its tightest here: Handlebars.Net rendered within ~8% - of Heddle (660.4 μs vs 612.9 μs) while again allocating **less** (1.01 MB vs 1.14 MB — alloc - ratio 0.88). Fluid was 1.6x, Scriban 2.1x, DotLiquid 6.7x. - -Compare the [2026-07-11 composition page](../2026-07-11/index.md), where Heddle led the four -parity-checked engines by 2.0x on time with the least-or-tied-least allocation. No claim of -universal superiority follows from these runs: which engine is preferable depends on the workload -shape (and on whether render time or allocation matters more) — on scalar-substitution output -Handlebars.Net allocates materially less, and on a pure large loop it is within measurement -distance on time. Numbers are hardware- and date-specific; reproduce them yourself with the -command above. - -## Files - -Each suite has a rendered Markdown report (linked) plus `-report.csv` and `-report.html` siblings -in this directory. - -- Trivial substitution — [`Heddle.Performance.SubstitutionRenderBenchmarks-report-github.md`](./Heddle.Performance.SubstitutionRenderBenchmarks-report-github.md) - (+ `Heddle.Performance.SubstitutionRenderBenchmarks-report.csv`, `Heddle.Performance.SubstitutionRenderBenchmarks-report.html`) -- Large loop — [`Heddle.Performance.LoopRenderBenchmarks-report-github.md`](./Heddle.Performance.LoopRenderBenchmarks-report-github.md) - (+ `Heddle.Performance.LoopRenderBenchmarks-report.csv`, `Heddle.Performance.LoopRenderBenchmarks-report.html`) - -The parity contract that makes the comparison apples-to-apples is documented in -[src/Heddle.Performance/Runners](../../../src/Heddle.Performance/Runners/README.md). diff --git a/docs/benchmarks/2026-08-08/consolidated-tables.md b/docs/benchmarks/2026-08-08/consolidated-tables.md new file mode 100644 index 00000000..8c63838c --- /dev/null +++ b/docs/benchmarks/2026-08-08/consolidated-tables.md @@ -0,0 +1,1387 @@ + + +# Consolidated tables — 2026-08-08 + +## Toolchain pins and drift + +| Toolchain | Pin | Actually ran | Drift | +| --- | --- | --- | --- | +| .NET SDK | (protocol records the observed line) | 10.0.302 | no | +| Rust | 1.97.1 | rustc 1.97.1 (8bab26f4f 2026-07-14) | no | +| JDK | Temurin 25 | java version "25.0.4" 2026-07-21 LTS | no | +| Node.js | v24.x | v24.19.0 | no | +| CPython | 3.14.x | Python 3.14.7 | no | +| Go | go1.26.x | go version go1.26.5 windows/amd64 | no | +| templ | v0.3.1020 | v0.3.1020 | no | + +Every toolchain ran at its pin in this run. + +## Sizing regimes + +The CLR allocates any object of **85,000 bytes or more on the Large +Object Heap**, and .NET strings are UTF-16 — so a rendered page crosses that line at +**42,500 characters**, and every render past it +allocates on the LOH and drives a full, blocking Gen2 collection. None of the other five +ecosystems has this cliff: their outputs are UTF-8 or Latin-1 and stay on the normal heap. + +Workloads on either side of that boundary are therefore not measuring the same thing. +Every table below is ordered **tier 1 first, then tier 2, ascending by rendered size** +within each — not in normative protocol order, which `manifest.json` and the phase specs +retain. The tier is derived from the rendered size, never declared per workload. + +| Workload | Suite | golden B | rendered chars | as UTF-16 B | tier | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | raw | 338 | 338 | 676 | **1** | +| fortunes-encoded | encoded | 1,156 | 1,157 | 2,314 | **1** | +| fragment-heavy | raw | 4,730 | 4,730 | 9,460 | **1** | +| mixed-page | raw | 9,712 | 9,740 | 19,480 | **1** | +| conditional-heavy | raw | 15,549 | 15,549 | 31,098 | **1** | +| composed-page | raw | 34,847 | 54,401 | 108,802 | **2** | +| large-loop | raw | 192,780 | 192,780 | 385,560 | **2** | +| encoded-loop | encoded | 831,685 | 851,685 | 1,703,370 | **2** | + +## Cross-stack ranked — wall time per render + +One ranking per workload. There is no aggregate score, overall winner or +cross-workload average anywhere — Phase 7 D6(c) still forbids them, so no +single-number verdict can be quoted from these tables. + +### Controlled track + +#### Tier 1 — realistic sizing + +Outputs that fit the size of a real page, partial or fragment, and stay clear of the 85,000-byte Large Object Heap threshold once materialised as UTF-16. **These are the primary results.** + +**trivial-substitution — cross-stack (controlled) — 338 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 86.01 ns | [85.9 ns, 86.13 ns] 95% CI | 86 | 0.58 | 3.9 | +| 2 | eta 4.6.0 | JS | reach/context | 135.4 ns | 130.7 ns … 147.3 ns | 135 | 0.91 | 2.5 | +| 3 | Heddle | .NET | anchor (baseline) | 149.0 ns | ±7.75 ns (SD 4.61 ns) | 149 | 1.00 | 2.3 | +| 4 | JTE 3.2.4 | JVM | fair fight | 350.6 ns | ±3.052 ns 99.9% CI | 351 | 2.35 | 1.0 | +| 5 | Tera 2.0.0 | Rust | fair fight | 366 ns | [365.2 ns, 366.8 ns] 95% CI | 366 | 2.46 | 0.9 | +| 6 | Handlebars.Net 2.1.6 | .NET | fair fight | 385.8 ns | ±7.23 ns (SD 4.30 ns) | 386 | 2.59 | 0.9 | +| 7 | Fluid.Core 2.31.0 | .NET | fair fight | 482.9 ns | ±20.47 ns (SD 12.18 ns) | 483 | 3.24 | 0.7 | +| 8 | templ v0.3.1020 | Go | fair fight | 618.3 ns | ±0% | 618 | 4.15 | 0.5 | +| 9 | handlebars 4.7.9 | JS | reach/context | 742.5 ns | 719.3 ns … 767.6 ns | 743 | 4.98 | 0.5 | +| 10 | text/template (go1.26) | Go | fair fight | 1.042 μs | ±0% | 1,042 | 6.99 | 0.3 | +| 11 | DotLiquid 2.3.197 | .NET | fair fight | 1,888.2 ns | ±20.20 ns (SD 12.02 ns) | 1,888 | 12.67 | 0.2 | +| 12 | Jinja2 3.1.6 | Python | reach/context | 4.668 μs | SD 52.72 ns | 4,668 | 31.33 | 0.1 | +| 13 | Razor (ASP.NET Core MVC) | .NET | fair fight | 5,523.2 ns | ±63.10 ns (SD 37.55 ns) | 5,523 | 37.07 | 0.1 | +| 14 | Mako 1.3.12 | Python | reach/context | 5.635 μs | SD 42.39 ns | 5,635 | 37.82 | 0.1 | +| 15 | Thymeleaf 3.1.5 | JVM | fair fight | 7.205 μs | ±116 ns 99.9% CI | 7,205 | 48.35 | 0.0 | +| 16 | Scriban 7.2.5 | .NET | fair fight | 38,805.4 ns | ±639.12 ns (SD 380.33 ns) | 38,805 | 260.44 | 0.0 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**fortunes-encoded — cross-stack (controlled) — 1,157 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 423.3 ns | [422.9 ns, 423.8 ns] 95% CI | 423 | 0.57 | 2.7 | +| 2 | Heddle | .NET | anchor (baseline) | 739.1 ns | ±5.16 ns (SD 3.07 ns) | 739 | 1.00 | 1.6 | +| 3 | Handlebars.Net 2.1.6 | .NET | fair fight | 1,660.4 ns | ±194.35 ns (SD 115.66 ns) | 1,660 | 2.25 | 0.7 | +| 4 | JTE 3.2.4 | JVM | fair fight | 1.673 μs | ±26.4 ns 99.9% CI | 1,673 | 2.26 | 0.7 | +| 5 | templ v0.3.1020 | Go | fair fight | 1.727 μs | ±0% | 1,727 | 2.34 | 0.7 | +| 6 | eta 4.6.0 | JS | reach/context | 1.826 μs | 1.757 μs … 1.88 μs | 1,826 | 2.47 | 0.6 | +| 7 | Fluid.Core 2.31.0 | .NET | fair fight | 2,182.3 ns | ±120.30 ns (SD 71.59 ns) | 2,182 | 2.95 | 0.5 | +| 8 | handlebars 4.7.9 | JS | reach/context | 2.645 μs | 2.594 μs … 2.735 μs | 2,645 | 3.58 | 0.4 | +| 9 | Tera 2.0.0 | Rust | fair fight | 3.458 μs | [3.457 μs, 3.46 μs] 95% CI | 3,458 | 4.68 | 0.3 | +| 10 | Razor (ASP.NET Core MVC) | .NET | fair fight | 8,279.2 ns | ±154.23 ns (SD 91.78 ns) | 8,279 | 11.20 | 0.1 | +| 11 | Thymeleaf 3.1.5 | JVM | fair fight | 10.14 μs | ±233.4 ns 99.9% CI | 10,136 | 13.71 | 0.1 | +| 12 | Mako 1.3.12 | Python | reach/context | 11.37 μs | SD 78.72 ns | 11,367 | 15.38 | 0.1 | +| 13 | html/template (go1.26) | Go | fair fight | 11.61 μs | ±0% | 11,610 | 15.71 | 0.1 | +| 14 | Scriban 7.2.5 | .NET | fair fight | 15,308.6 ns | ±3,805.09 ns (SD 2,264.35 ns) | 15,309 | 20.71 | 0.1 | +| 15 | Jinja2 3.1.6 | Python | reach/context | 19.59 μs | SD 157.7 ns | 19,594 | 26.51 | 0.1 | +| 16 | DotLiquid 2.3.197 | .NET | fair fight | 25,655.3 ns | ±386.31 ns (SD 229.89 ns) | 25,655 | 34.71 | 0.0 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**fragment-heavy — cross-stack (controlled) — 4,730 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 900.4 ns | [899.4 ns, 901.3 ns] 95% CI | 900 | 0.29 | 5.3 | +| 2 | JTE 3.2.4 | JVM | fair fight | 1.699 μs | ±9.481 ns 99.9% CI | 1,699 | 0.55 | 2.8 | +| 3 | Heddle | .NET | anchor (baseline) | 3.081 μs | ±0.1664 μs (SD 0.0990 μs) | 3,081 | 1.00 | 1.5 | +| 4 | eta 4.6.0 | JS | reach/context | 4.809 μs | 4.755 μs … 5.062 μs | 4,809 | 1.56 | 1.0 | +| 5 | handlebars 4.7.9 | JS | reach/context | 6.651 μs | 6.571 μs … 7.295 μs | 6,651 | 2.16 | 0.7 | +| 6 | templ v0.3.1020 | Go | fair fight | 9.748 μs | ±0% | 9,748 | 3.16 | 0.5 | +| 7 | Fluid.Core 2.31.0 | .NET | fair fight | 11.220 μs | ±0.4969 μs (SD 0.2957 μs) | 11,220 | 3.64 | 0.4 | +| 8 | Tera 2.0.0 | Rust | fair fight | 12.12 μs | [12.12 μs, 12.13 μs] 95% CI | 12,124 | 3.94 | 0.4 | +| 9 | Handlebars.Net 2.1.6 | .NET | fair fight | 20.692 μs | ±0.3136 μs (SD 0.1866 μs) | 20,692 | 6.72 | 0.2 | +| 10 | text/template (go1.26) | Go | fair fight | 20.87 μs | ±0% | 20,870 | 6.77 | 0.2 | +| 11 | Razor (ASP.NET Core MVC) | .NET | fair fight | 44.056 μs | ±1.4609 μs (SD 0.8694 μs) | 44,056 | 14.30 | 0.1 | +| 12 | Scriban 7.2.5 | .NET | fair fight | 46.476 μs | ±1.3660 μs (SD 0.8129 μs) | 46,476 | 15.08 | 0.1 | +| 13 | Thymeleaf 3.1.5 | JVM | fair fight | 145 μs | ±2.316 μs 99.9% CI | 144,991 | 47.06 | 0.0 | +| 14 | DotLiquid 2.3.197 | .NET | fair fight | 170.223 μs | ±1.3890 μs (SD 0.8266 μs) | 170,223 | 55.25 | 0.0 | +| 15 | Mako 1.3.12 | Python | reach/context | 480.4 μs | SD 5.294 μs | 480,450 | 155.94 | 0.0 | +| 16 | Jinja2 3.1.6 | Python | reach/context | 498.4 μs | SD 1.52 μs | 498,444 | 161.78 | 0.0 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**mixed-page — cross-stack (controlled) — 9,740 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 1.108 μs | [1.108 μs, 1.109 μs] 95% CI | 1,108 | 0.42 | 8.8 | +| 2 | Heddle | .NET | anchor (baseline) | 2.636 μs | ±0.0337 μs (SD 0.0200 μs) | 2,636 | 1.00 | 3.7 | +| 3 | JTE 3.2.4 | JVM | fair fight | 2.835 μs | ±44.26 ns 99.9% CI | 2,835 | 1.08 | 3.4 | +| 4 | eta 4.6.0 | JS | reach/context | 3.004 μs | 2.938 μs … 3.034 μs | 3,004 | 1.14 | 3.2 | +| 5 | Tera 2.0.0 | Rust | fair fight | 5.701 μs | [5.697 μs, 5.705 μs] 95% CI | 5,701 | 2.16 | 1.7 | +| 6 | Handlebars.Net 2.1.6 | .NET | fair fight | 7.247 μs | ±0.1362 μs (SD 0.0811 μs) | 7,247 | 2.75 | 1.3 | +| 7 | handlebars 4.7.9 | JS | reach/context | 7.667 μs | 7.296 μs … 9.421 μs | 7,667 | 2.91 | 1.3 | +| 8 | Fluid.Core 2.31.0 | .NET | fair fight | 8.918 μs | ±0.2473 μs (SD 0.1472 μs) | 8,918 | 3.38 | 1.1 | +| 9 | templ v0.3.1020 | Go | fair fight | 9.707 μs | ±1% | 9,707 | 3.68 | 1.0 | +| 10 | Mako 1.3.12 | Python | reach/context | 14.38 μs | SD 185.9 ns | 14,376 | 5.45 | 0.7 | +| 11 | Razor (ASP.NET Core MVC) | .NET | fair fight | 20.131 μs | ±0.4106 μs (SD 0.2444 μs) | 20,131 | 7.64 | 0.5 | +| 12 | text/template (go1.26) | Go | fair fight | 22.15 μs | ±0% | 22,150 | 8.40 | 0.4 | +| 13 | DotLiquid 2.3.197 | .NET | fair fight | 56.338 μs | ±2.6957 μs (SD 1.6042 μs) | 56,338 | 21.37 | 0.2 | +| 14 | Jinja2 3.1.6 | Python | reach/context | 62.73 μs | SD 564.2 ns | 62,734 | 23.80 | 0.2 | +| 15 | Scriban 7.2.5 | .NET | fair fight | 71.202 μs | ±24.5102 μs (SD 14.5856 μs) | 71,202 | 27.01 | 0.1 | +| 16 | Thymeleaf 3.1.5 | JVM | fair fight | 118.6 μs | ±848.7 ns 99.9% CI | 118,601 | 44.99 | 0.1 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**conditional-heavy — cross-stack (controlled) — 15,549 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 3.752 μs | [3.749 μs, 3.755 μs] 95% CI | 3,752 | 0.25 | 4.1 | +| 2 | JTE 3.2.4 | JVM | fair fight | 7.423 μs | ±86.46 ns 99.9% CI | 7,423 | 0.49 | 2.1 | +| 3 | eta 4.6.0 | JS | reach/context | 10.54 μs | 10.42 μs … 10.68 μs | 10,538 | 0.70 | 1.5 | +| 4 | Heddle | .NET | anchor (baseline) | 15.02 μs | ±0.852 μs (SD 0.507 μs) | 15,020 | 1.00 | 1.0 | +| 5 | templ v0.3.1020 | Go | fair fight | 21.57 μs | ±0% | 21,570 | 1.44 | 0.7 | +| 6 | Handlebars.Net 2.1.6 | .NET | fair fight | 34.51 μs | ±0.641 μs (SD 0.382 μs) | 34,510 | 2.30 | 0.5 | +| 7 | Razor (ASP.NET Core MVC) | .NET | fair fight | 37.65 μs | ±0.257 μs (SD 0.153 μs) | 37,650 | 2.51 | 0.4 | +| 8 | Fluid.Core 2.31.0 | .NET | fair fight | 39.32 μs | ±0.387 μs (SD 0.230 μs) | 39,320 | 2.62 | 0.4 | +| 9 | Mako 1.3.12 | Python | reach/context | 39.85 μs | SD 1.104 μs | 39,852 | 2.65 | 0.4 | +| 10 | Tera 2.0.0 | Rust | fair fight | 41.05 μs | [41.03 μs, 41.08 μs] 95% CI | 41,053 | 2.73 | 0.4 | +| 11 | text/template (go1.26) | Go | fair fight | 94.49 μs | ±0% | 94,490 | 6.29 | 0.2 | +| 12 | handlebars 4.7.9 | JS | reach/context | 101.6 μs | 93.57 μs … 110.1 μs | 101,571 | 6.76 | 0.2 | +| 13 | Scriban 7.2.5 | .NET | fair fight | 105.60 μs | ±2.632 μs (SD 1.566 μs) | 105,600 | 7.03 | 0.1 | +| 14 | Jinja2 3.1.6 | Python | reach/context | 337.7 μs | SD 3.03 μs | 337,702 | 22.48 | 0.0 | +| 15 | DotLiquid 2.3.197 | .NET | fair fight | 343.11 μs | ±5.678 μs (SD 3.379 μs) | 343,110 | 22.84 | 0.0 | +| 16 | Thymeleaf 3.1.5 | JVM | fair fight | 461.9 μs | ±3.351 μs 99.9% CI | 461,900 | 30.75 | 0.0 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +#### Tier 2 — edge-case sizing + +Outputs that exceed the 85,000-byte Large Object Heap threshold as UTF-16, so every .NET render allocates on the LOH and drives a full Gen2 collection — a cost structural to the runtime and absent in the other five ecosystems. These are stress tests, not page renders; read them with that caveat attached. + +**composed-page — cross-stack (controlled) — 54,401 B rendered output (34,847 B golden, after whitespace normalization)** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 1.455 μs | [1.454 μs, 1.455 μs] 95% CI | 1,455 | 0.04 | 37.4 | +| 2 | Tera 2.0.0 | Rust | fair fight | 3.578 μs | [3.576 μs, 3.58 μs] 95% CI | 3,578 | 0.11 | 15.2 | +| 3 | templ v0.3.1020 | Go | fair fight | 3.953 μs | ±3% | 3,953 | 0.12 | 13.8 | +| 4 | eta 4.6.0 | JS | reach/context | 4.235 μs | 4.181 μs … 4.31 μs | 4,235 | 0.12 | 12.8 | +| 5 | handlebars 4.7.9 | JS | reach/context | 5.414 μs | 5.27 μs … 5.506 μs | 5,414 | 0.16 | 10.0 | +| 6 | text/template (go1.26) | Go | fair fight | 13.78 μs | ±1% | 13,780 | 0.40 | 3.9 | +| 7 | JTE 3.2.4 | JVM | fair fight | 14.44 μs | ±33.93 ns 99.9% CI | 14,437 | 0.42 | 3.8 | +| 8 | Mako 1.3.12 | Python | reach/context | 17.05 μs | SD 509.3 ns | 17,050 | 0.50 | 3.2 | +| 9 | Jinja2 3.1.6 | Python | reach/context | 19.36 μs | SD 391.1 ns | 19,363 | 0.57 | 2.8 | +| 10 | Thymeleaf 3.1.5 | JVM | fair fight | 21.52 μs | ±101.4 ns 99.9% CI | 21,517 | 0.63 | 2.5 | +| 11 | Heddle | .NET | anchor (baseline) | 34.066 μs | ±5.3035 μs (SD 3.1560 μs) | 34,066 | 1.00 | 1.6 | +| 12 | Fluid.Core 2.31.0 | .NET | fair fight | 60.234 μs | ±3.6891 μs (SD 2.1953 μs) | 60,234 | 1.77 | 0.9 | +| 13 | Handlebars.Net 2.1.6 | .NET | fair fight | 62.869 μs | ±3.8804 μs (SD 2.3092 μs) | 62,869 | 1.85 | 0.9 | +| 14 | Razor (ASP.NET Core MVC) | .NET | fair fight | 64.815 μs | ±10.3742 μs (SD 6.1735 μs) | 64,815 | 1.90 | 0.8 | +| 15 | DotLiquid 2.3.197 | .NET | fair fight | 153.755 μs | ±13.3191 μs (SD 7.9260 μs) | 153,755 | 4.51 | 0.4 | +| 16 | Scriban 7.2.5 | .NET | fair fight | 419.333 μs | ±30.5925 μs (SD 18.2051 μs) | 419,333 | 12.31 | 0.1 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**large-loop — cross-stack (controlled) — 192,780 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 60.57 μs | [59.96 μs, 61.18 μs] 95% CI | 60,568 | 0.12 | 3.2 | +| 2 | JTE 3.2.4 | JVM | fair fight | 112.2 μs | ±761.5 ns 99.9% CI | 112,228 | 0.23 | 1.7 | +| 3 | eta 4.6.0 | JS | reach/context | 250.1 μs | 247.6 μs … 256.7 μs | 250,076 | 0.51 | 0.8 | +| 4 | Tera 2.0.0 | Rust | fair fight | 328.5 μs | [328.4 μs, 328.6 μs] 95% CI | 328,491 | 0.67 | 0.6 | +| 5 | handlebars 4.7.9 | JS | reach/context | 407.3 μs | 401 μs … 420.3 μs | 407,297 | 0.83 | 0.5 | +| 6 | Heddle | .NET | anchor (baseline) | 492.1 μs | ±3.46 μs (SD 2.06 μs) | 492,100 | 1.00 | 0.4 | +| 7 | templ v0.3.1020 | Go | fair fight | 509.5 μs | ±0% | 509,500 | 1.04 | 0.4 | +| 8 | Mako 1.3.12 | Python | reach/context | 562.2 μs | SD 7.099 μs | 562,167 | 1.14 | 0.3 | +| 9 | Handlebars.Net 2.1.6 | .NET | fair fight | 742.2 μs | ±26.84 μs (SD 15.97 μs) | 742,200 | 1.51 | 0.3 | +| 10 | Razor (ASP.NET Core MVC) | .NET | fair fight | 744.1 μs | ±5.92 μs (SD 3.52 μs) | 744,100 | 1.51 | 0.3 | +| 11 | Fluid.Core 2.31.0 | .NET | fair fight | 790.1 μs | ±22.49 μs (SD 13.38 μs) | 790,100 | 1.61 | 0.2 | +| 12 | text/template (go1.26) | Go | fair fight | 1.202 ms | ±0% | 1,202,000 | 2.44 | 0.2 | +| 13 | Scriban 7.2.5 | .NET | fair fight | 1,562.8 μs | ±30.07 μs (SD 17.89 μs) | 1,562,800 | 3.18 | 0.1 | +| 14 | Jinja2 3.1.6 | Python | reach/context | 3.387 ms | SD 38.4 μs | 3,387,044 | 6.88 | 0.1 | +| 15 | DotLiquid 2.3.197 | .NET | fair fight | 3,735.0 μs | ±231.22 μs (SD 137.59 μs) | 3,735,000 | 7.59 | 0.1 | +| 16 | Thymeleaf 3.1.5 | JVM | fair fight | 6.649 ms | ±59.32 μs 99.9% CI | 6,648,937 | 13.51 | 0.0 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**encoded-loop — cross-stack (controlled) — 851,685 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 619.4 μs | [615.3 μs, 623.6 μs] 95% CI | 619,437 | 0.35 | 1.4 | +| 2 | templ v0.3.1020 | Go | fair fight | 1.286 ms | ±1% | 1,286,000 | 0.73 | 0.7 | +| 3 | JTE 3.2.4 | JVM | fair fight | 1.402 ms | ±339.1 μs 99.9% CI | 1,402,244 | 0.79 | 0.6 | +| 4 | Tera 2.0.0 | Rust | fair fight | 1.691 ms | [1.69 ms, 1.693 ms] 95% CI | 1,691,277 | 0.96 | 0.5 | +| 5 | Handlebars.Net 2.1.6 | .NET | fair fight | 1,719.5 μs | ±10.84 μs (SD 6.45 μs) | 1,719,500 | 0.97 | 0.5 | +| 6 | Razor (ASP.NET Core MVC) | .NET | fair fight | 1,761.1 μs | ±24.63 μs (SD 14.66 μs) | 1,761,100 | 1.00 | 0.5 | +| 7 | Heddle | .NET | anchor (baseline) | 1,766.0 μs | ±29.51 μs (SD 17.56 μs) | 1,766,000 | 1.00 | 0.5 | +| 8 | Fluid.Core 2.31.0 | .NET | fair fight | 2,574.9 μs | ±10.52 μs (SD 6.26 μs) | 2,574,900 | 1.46 | 0.3 | +| 9 | eta 4.6.0 | JS | reach/context | 4.436 ms | 4.302 ms … 4.579 ms | 4,436,399 | 2.51 | 0.2 | +| 10 | handlebars 4.7.9 | JS | reach/context | 4.713 ms | 4.57 ms … 4.867 ms | 4,712,629 | 2.67 | 0.2 | +| 11 | Mako 1.3.12 | Python | reach/context | 5.005 ms | SD 60.27 μs | 5,005,346 | 2.83 | 0.2 | +| 12 | Scriban 7.2.5 | .NET | fair fight | 6,725.7 μs | ±239.80 μs (SD 142.70 μs) | 6,725,700 | 3.81 | 0.1 | +| 13 | html/template (go1.26) | Go | fair fight | 7.469 ms | ±0% | 7,469,000 | 4.23 | 0.1 | +| 14 | DotLiquid 2.3.197 | .NET | fair fight | 7,823.7 μs | ±374.27 μs (SD 222.72 μs) | 7,823,700 | 4.43 | 0.1 | +| 15 | Thymeleaf 3.1.5 | JVM | fair fight | 8.31 ms | ±37.79 μs 99.9% CI | 8,309,714 | 4.71 | 0.1 | +| 16 | Jinja2 3.1.6 | Python | reach/context | 10.39 ms | SD 111.8 μs | 10,387,159 | 5.88 | 0.1 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +### Idiomatic track + +#### Tier 1 — realistic sizing + +Outputs that fit the size of a real page, partial or fragment, and stay clear of the 85,000-byte Large Object Heap threshold once materialised as UTF-16. **These are the primary results.** + +**trivial-substitution — cross-stack (idiomatic) — 338 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 130.4 ns | [130.2 ns, 130.7 ns] 95% CI | 130 | 0.88 | 2.6 | +| 2 | Heddle | .NET | anchor (baseline) | 148.1 ns | ±5.21 ns (SD 3.10 ns) | 148 | 0.99 | 2.3 | +| 3 | eta 4.6.0 | JS | reach/context | 253.6 ns | 244.7 ns … 276.1 ns | 254 | 1.70 | 1.3 | +| 4 | JTE 3.2.4 | JVM | fair fight | 368.4 ns | ±0.8194 ns 99.9% CI | 368 | 2.47 | 0.9 | +| 5 | Handlebars.Net 2.1.6 | .NET | fair fight | 461.2 ns | ±4.16 ns (SD 2.48 ns) | 461 | 3.10 | 0.7 | +| 6 | Fluid.Core 2.31.0 | .NET | fair fight | 491.4 ns | ±21.52 ns (SD 12.81 ns) | 491 | 3.30 | 0.7 | +| 7 | templ v0.3.1020 | Go | fair fight | 626.9 ns | ±1% | 627 | 4.21 | 0.5 | +| 8 | handlebars 4.7.9 | JS | reach/context | 629.5 ns | 609.9 ns … 650.8 ns | 630 | 4.22 | 0.5 | +| 9 | Tera 2.0.0 | Rust | fair fight | 804.1 ns | [802.7 ns, 805.6 ns] 95% CI | 804 | 5.40 | 0.4 | +| 10 | text/template (go1.26) | Go | fair fight | 1.055 μs | ±1% | 1,055 | 7.08 | 0.3 | +| 11 | DotLiquid 2.3.197 | .NET | fair fight | 1,925.7 ns | ±37.68 ns (SD 22.42 ns) | 1,926 | 12.92 | 0.2 | +| 12 | Jinja2 3.1.6 | Python | reach/context | 4.761 μs | SD 46.83 ns | 4,761 | 31.95 | 0.1 | +| 13 | Razor (ASP.NET Core MVC) | .NET | fair fight | 4,833.0 ns | ±49.84 ns (SD 29.66 ns) | 4,833 | 32.44 | 0.1 | +| 14 | Mako 1.3.12 | Python | reach/context | 5.641 μs | SD 48.36 ns | 5,641 | 37.86 | 0.1 | +| 15 | Thymeleaf 3.1.5 | JVM | fair fight | 6.61 μs | ±80.16 ns 99.9% CI | 6,610 | 44.36 | 0.1 | +| 16 | Scriban 7.2.5 | .NET | fair fight | 38,709.8 ns | ±3,542.32 ns (SD 2,107.98 ns) | 38,710 | 259.80 | 0.0 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**fortunes-encoded — cross-stack (idiomatic) — 1,157 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 435.1 ns | [433.5 ns, 436.7 ns] 95% CI | 435 | 0.59 | 2.7 | +| 2 | Heddle | .NET | anchor (baseline) | 763.2 ns | ±7.03 ns (SD 4.19 ns) | 763 | 1.03 | 1.5 | +| 3 | JTE 3.2.4 | JVM | fair fight | 1.46 μs | ±40.72 ns 99.9% CI | 1,460 | 1.98 | 0.8 | +| 4 | Handlebars.Net 2.1.6 | .NET | fair fight | 1,563.6 ns | ±23.87 ns (SD 14.21 ns) | 1,564 | 2.12 | 0.7 | +| 5 | eta 4.6.0 | JS | reach/context | 1.859 μs | 1.812 μs … 1.999 μs | 1,859 | 2.52 | 0.6 | +| 6 | Fluid.Core 2.31.0 | .NET | fair fight | 2,189.8 ns | ±69.50 ns (SD 41.36 ns) | 2,190 | 2.96 | 0.5 | +| 7 | handlebars 4.7.9 | JS | reach/context | 2.473 μs | 2.443 μs … 2.721 μs | 2,473 | 3.35 | 0.5 | +| 8 | templ v0.3.1020 | Go | fair fight | 2.66 μs | ±2% | 2,660 | 3.60 | 0.4 | +| 9 | Tera 2.0.0 | Rust | fair fight | 3.454 μs | [3.453 μs, 3.455 μs] 95% CI | 3,454 | 4.67 | 0.3 | +| 10 | Razor (ASP.NET Core MVC) | .NET | fair fight | 8,434.6 ns | ±183.55 ns (SD 109.22 ns) | 8,435 | 11.41 | 0.1 | +| 11 | Thymeleaf 3.1.5 | JVM | fair fight | 9.122 μs | ±81.84 ns 99.9% CI | 9,122 | 12.34 | 0.1 | +| 12 | Mako 1.3.12 | Python | reach/context | 11.28 μs | SD 94.33 ns | 11,281 | 15.26 | 0.1 | +| 13 | html/template (go1.26) | Go | fair fight | 11.68 μs | ±0% | 11,680 | 15.80 | 0.1 | +| 14 | Scriban 7.2.5 | .NET | fair fight | 16,562.8 ns | ±485.71 ns (SD 289.04 ns) | 16,563 | 22.41 | 0.1 | +| 15 | Jinja2 3.1.6 | Python | reach/context | 19.65 μs | SD 148.3 ns | 19,649 | 26.59 | 0.1 | +| 16 | DotLiquid 2.3.197 | .NET | fair fight | 25,677.9 ns | ±571.67 ns (SD 340.19 ns) | 25,678 | 34.74 | 0.0 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**fragment-heavy — cross-stack (idiomatic) — 4,730 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 1.184 μs | [1.181 μs, 1.186 μs] 95% CI | 1,184 | 0.38 | 4.0 | +| 2 | JTE 3.2.4 | JVM | fair fight | 2.035 μs | ±10.9 ns 99.9% CI | 2,035 | 0.66 | 2.3 | +| 3 | Heddle | .NET | anchor (baseline) | 3.285 μs | ±0.4394 μs (SD 0.2615 μs) | 3,285 | 1.07 | 1.4 | +| 4 | handlebars 4.7.9 | JS | reach/context | 5.763 μs | 5.68 μs … 6.392 μs | 5,763 | 1.87 | 0.8 | +| 5 | eta 4.6.0 | JS | reach/context | 6.508 μs | 6.428 μs … 6.8 μs | 6,508 | 2.11 | 0.7 | +| 6 | templ v0.3.1020 | Go | fair fight | 10.34 μs | ±1% | 10,340 | 3.36 | 0.5 | +| 7 | Fluid.Core 2.31.0 | .NET | fair fight | 11.798 μs | ±0.2033 μs (SD 0.1210 μs) | 11,798 | 3.83 | 0.4 | +| 8 | Tera 2.0.0 | Rust | fair fight | 14.52 μs | [14.51 μs, 14.54 μs] 95% CI | 14,525 | 4.71 | 0.3 | +| 9 | Handlebars.Net 2.1.6 | .NET | fair fight | 21.373 μs | ±0.8808 μs (SD 0.5241 μs) | 21,373 | 6.94 | 0.2 | +| 10 | text/template (go1.26) | Go | fair fight | 21.9 μs | ±0% | 21,900 | 7.11 | 0.2 | +| 11 | Mako 1.3.12 | Python | reach/context | 29.92 μs | SD 402.2 ns | 29,922 | 9.71 | 0.2 | +| 12 | Razor (ASP.NET Core MVC) | .NET | fair fight | 36.889 μs | ±0.4233 μs (SD 0.2519 μs) | 36,889 | 11.97 | 0.1 | +| 13 | Scriban 7.2.5 | .NET | fair fight | 52.684 μs | ±1.5357 μs (SD 0.9139 μs) | 52,684 | 17.10 | 0.1 | +| 14 | Jinja2 3.1.6 | Python | reach/context | 104.9 μs | SD 541.8 ns | 104,873 | 34.04 | 0.0 | +| 15 | Thymeleaf 3.1.5 | JVM | fair fight | 138.3 μs | ±1.031 μs 99.9% CI | 138,347 | 44.90 | 0.0 | +| 16 | DotLiquid 2.3.197 | .NET | fair fight | 278.300 μs | ±5.1166 μs (SD 3.0448 μs) | 278,300 | 90.33 | 0.0 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**mixed-page — cross-stack (idiomatic) — 9,740 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 2.3 μs | [2.296 μs, 2.304 μs] 95% CI | 2,300 | 0.87 | 4.2 | +| 2 | Heddle | .NET | anchor (baseline) | 2.906 μs | ±0.0269 μs (SD 0.0160 μs) | 2,906 | 1.10 | 3.4 | +| 3 | JTE 3.2.4 | JVM | fair fight | 3.023 μs | ±7.675 ns 99.9% CI | 3,023 | 1.15 | 3.2 | +| 4 | eta 4.6.0 | JS | reach/context | 4.956 μs | 4.922 μs … 5.047 μs | 4,956 | 1.88 | 2.0 | +| 5 | handlebars 4.7.9 | JS | reach/context | 6.471 μs | 6.268 μs … 7.75 μs | 6,471 | 2.45 | 1.5 | +| 6 | Fluid.Core 2.31.0 | .NET | fair fight | 9.115 μs | ±0.4819 μs (SD 0.2868 μs) | 9,115 | 3.46 | 1.1 | +| 7 | Handlebars.Net 2.1.6 | .NET | fair fight | 10.260 μs | ±0.2998 μs (SD 0.1784 μs) | 10,260 | 3.89 | 0.9 | +| 8 | templ v0.3.1020 | Go | fair fight | 12.79 μs | ±2% | 12,790 | 4.85 | 0.8 | +| 9 | Razor (ASP.NET Core MVC) | .NET | fair fight | 15.505 μs | ±0.2166 μs (SD 0.1289 μs) | 15,505 | 5.88 | 0.6 | +| 10 | text/template (go1.26) | Go | fair fight | 22.41 μs | ±0% | 22,410 | 8.50 | 0.4 | +| 11 | Tera 2.0.0 | Rust | fair fight | 22.65 μs | [22.63 μs, 22.66 μs] 95% CI | 22,646 | 8.59 | 0.4 | +| 12 | Mako 1.3.12 | Python | reach/context | 27.11 μs | SD 331.2 ns | 27,107 | 10.28 | 0.4 | +| 13 | DotLiquid 2.3.197 | .NET | fair fight | 59.112 μs | ±1.9223 μs (SD 1.1439 μs) | 59,112 | 22.42 | 0.2 | +| 14 | Scriban 7.2.5 | .NET | fair fight | 68.265 μs | ±13.4083 μs (SD 7.9790 μs) | 68,265 | 25.90 | 0.1 | +| 15 | Jinja2 3.1.6 | Python | reach/context | 79.35 μs | SD 709.2 ns | 79,348 | 30.10 | 0.1 | +| 16 | Thymeleaf 3.1.5 | JVM | fair fight | 114.3 μs | ±1.179 μs 99.9% CI | 114,270 | 43.35 | 0.1 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**conditional-heavy — cross-stack (idiomatic) — 15,549 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 5.392 μs | [5.379 μs, 5.406 μs] 95% CI | 5,392 | 0.36 | 2.9 | +| 2 | JTE 3.2.4 | JVM | fair fight | 12.44 μs | ±28.72 ns 99.9% CI | 12,444 | 0.83 | 1.2 | +| 3 | eta 4.6.0 | JS | reach/context | 15.33 μs | 15.21 μs … 15.77 μs | 15,326 | 1.02 | 1.0 | +| 4 | Heddle | .NET | anchor (baseline) | 15.70 μs | ±0.395 μs (SD 0.235 μs) | 15,700 | 1.05 | 1.0 | +| 5 | Razor (ASP.NET Core MVC) | .NET | fair fight | 25.25 μs | ±0.395 μs (SD 0.235 μs) | 25,250 | 1.68 | 0.6 | +| 6 | templ v0.3.1020 | Go | fair fight | 36.03 μs | ±1% | 36,030 | 2.40 | 0.4 | +| 7 | Handlebars.Net 2.1.6 | .NET | fair fight | 37.04 μs | ±0.174 μs (SD 0.103 μs) | 37,040 | 2.47 | 0.4 | +| 8 | Mako 1.3.12 | Python | reach/context | 39.54 μs | SD 828.5 ns | 39,536 | 2.63 | 0.4 | +| 9 | Fluid.Core 2.31.0 | .NET | fair fight | 40.62 μs | ±0.369 μs (SD 0.219 μs) | 40,620 | 2.70 | 0.4 | +| 10 | Tera 2.0.0 | Rust | fair fight | 51.41 μs | [51.37 μs, 51.45 μs] 95% CI | 51,412 | 3.42 | 0.3 | +| 11 | text/template (go1.26) | Go | fair fight | 95.92 μs | ±0% | 95,920 | 6.39 | 0.2 | +| 12 | handlebars 4.7.9 | JS | reach/context | 98.23 μs | 90.99 μs … 110.7 μs | 98,231 | 6.54 | 0.2 | +| 13 | Scriban 7.2.5 | .NET | fair fight | 112.02 μs | ±4.699 μs (SD 2.796 μs) | 112,020 | 7.46 | 0.1 | +| 14 | Jinja2 3.1.6 | Python | reach/context | 344.7 μs | SD 3.438 μs | 344,651 | 22.95 | 0.0 | +| 15 | DotLiquid 2.3.197 | .NET | fair fight | 354.09 μs | ±7.533 μs (SD 4.483 μs) | 354,090 | 23.57 | 0.0 | +| 16 | Thymeleaf 3.1.5 | JVM | fair fight | 457.6 μs | ±2.891 μs 99.9% CI | 457,644 | 30.47 | 0.0 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +#### Tier 2 — edge-case sizing + +Outputs that exceed the 85,000-byte Large Object Heap threshold as UTF-16, so every .NET render allocates on the LOH and drives a full Gen2 collection — a cost structural to the runtime and absent in the other five ecosystems. These are stress tests, not page renders; read them with that caveat attached. + +**composed-page — cross-stack (idiomatic) — 54,401 B rendered output (34,847 B golden, after whitespace normalization)** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 1.529 μs | [1.528 μs, 1.53 μs] 95% CI | 1,529 | 0.04 | 35.6 | +| 2 | eta 4.6.0 | JS | reach/context | 4.231 μs | 4.195 μs … 4.318 μs | 4,231 | 0.12 | 12.9 | +| 3 | templ v0.3.1020 | Go | fair fight | 4.234 μs | ±3% | 4,234 | 0.12 | 12.8 | +| 4 | handlebars 4.7.9 | JS | reach/context | 5.322 μs | 5.271 μs … 5.38 μs | 5,322 | 0.16 | 10.2 | +| 5 | Tera 2.0.0 | Rust | fair fight | 5.597 μs | [5.593 μs, 5.601 μs] 95% CI | 5,597 | 0.16 | 9.7 | +| 6 | JTE 3.2.4 | JVM | fair fight | 14.51 μs | ±27.35 ns 99.9% CI | 14,511 | 0.43 | 3.7 | +| 7 | text/template (go1.26) | Go | fair fight | 14.78 μs | ±1% | 14,780 | 0.43 | 3.7 | +| 8 | Mako 1.3.12 | Python | reach/context | 17.46 μs | SD 600.2 ns | 17,463 | 0.51 | 3.1 | +| 9 | Jinja2 3.1.6 | Python | reach/context | 19.29 μs | SD 302.5 ns | 19,287 | 0.57 | 2.8 | +| 10 | Thymeleaf 3.1.5 | JVM | fair fight | 21.44 μs | ±68.17 ns 99.9% CI | 21,441 | 0.63 | 2.5 | +| 11 | Heddle | .NET | anchor (baseline) | 32.761 μs | ±4.1901 μs (SD 2.4935 μs) | 32,761 | 0.96 | 1.7 | +| 12 | Razor (ASP.NET Core MVC) | .NET | fair fight | 59.550 μs | ±13.8188 μs (SD 8.2233 μs) | 59,550 | 1.75 | 0.9 | +| 13 | Fluid.Core 2.31.0 | .NET | fair fight | 60.527 μs | ±3.2964 μs (SD 1.9616 μs) | 60,527 | 1.78 | 0.9 | +| 14 | Handlebars.Net 2.1.6 | .NET | fair fight | 64.713 μs | ±6.4197 μs (SD 3.8203 μs) | 64,713 | 1.90 | 0.8 | +| 15 | DotLiquid 2.3.197 | .NET | fair fight | 194.211 μs | ±9.8814 μs (SD 5.8802 μs) | 194,211 | 5.70 | 0.3 | +| 16 | Scriban 7.2.5 | .NET | fair fight | 431.057 μs | ±40.3621 μs (SD 24.0189 μs) | 431,057 | 12.65 | 0.1 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**large-loop — cross-stack (idiomatic) — 192,780 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 78.19 μs | [77.76 μs, 78.6 μs] 95% CI | 78,189 | 0.16 | 2.5 | +| 2 | JTE 3.2.4 | JVM | fair fight | 132.3 μs | ±1.188 μs 99.9% CI | 132,278 | 0.27 | 1.5 | +| 3 | handlebars 4.7.9 | JS | reach/context | 355.8 μs | 352.4 μs … 442 μs | 355,768 | 0.72 | 0.5 | +| 4 | eta 4.6.0 | JS | reach/context | 355.8 μs | 352.4 μs … 361.6 μs | 355,803 | 0.72 | 0.5 | +| 5 | Tera 2.0.0 | Rust | fair fight | 493.3 μs | [492.8 μs, 493.8 μs] 95% CI | 493,282 | 1.00 | 0.4 | +| 6 | Heddle | .NET | anchor (baseline) | 566.1 μs | ±7.08 μs (SD 4.21 μs) | 566,100 | 1.15 | 0.3 | +| 7 | Razor (ASP.NET Core MVC) | .NET | fair fight | 569.7 μs | ±8.76 μs (SD 5.21 μs) | 569,700 | 1.16 | 0.3 | +| 8 | Mako 1.3.12 | Python | reach/context | 570.8 μs | SD 6.691 μs | 570,801 | 1.16 | 0.3 | +| 9 | templ v0.3.1020 | Go | fair fight | 759 μs | ±0% | 759,000 | 1.54 | 0.3 | +| 10 | Handlebars.Net 2.1.6 | .NET | fair fight | 780.0 μs | ±33.19 μs (SD 19.75 μs) | 780,000 | 1.59 | 0.2 | +| 11 | Fluid.Core 2.31.0 | .NET | fair fight | 859.7 μs | ±10.35 μs (SD 6.16 μs) | 859,700 | 1.75 | 0.2 | +| 12 | text/template (go1.26) | Go | fair fight | 1.203 ms | ±0% | 1,203,000 | 2.44 | 0.2 | +| 13 | Scriban 7.2.5 | .NET | fair fight | 1,615.7 μs | ±75.75 μs (SD 45.08 μs) | 1,615,700 | 3.28 | 0.1 | +| 14 | Jinja2 3.1.6 | Python | reach/context | 3.38 ms | SD 44.43 μs | 3,379,516 | 6.87 | 0.1 | +| 15 | DotLiquid 2.3.197 | .NET | fair fight | 3,795.1 μs | ±28.20 μs (SD 16.78 μs) | 3,795,100 | 7.71 | 0.1 | +| 16 | Thymeleaf 3.1.5 | JVM | fair fight | 6.277 ms | ±225.8 μs 99.9% CI | 6,276,528 | 12.75 | 0.0 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +**encoded-loop — cross-stack (idiomatic) — 851,685 B rendered output** + +| # | Engine | Ecosystem | Evidence | harness statistic | harness dispersion | ns/render | vs Heddle | implied B/ns | +| ---: | --- | --- | --- | ---: | ---: | ---: | ---: | ---: | +| 1 | Askama 0.16.0 | Rust | fair fight | 591.8 μs | [589.5 μs, 594.2 μs] 95% CI | 591,806 | 0.34 | 1.4 | +| 2 | JTE 3.2.4 | JVM | fair fight | 1.072 ms | ±6.388 μs 99.9% CI | 1,072,307 | 0.61 | 0.8 | +| 3 | Tera 2.0.0 | Rust | fair fight | 1.723 ms | [1.721 ms, 1.725 ms] 95% CI | 1,723,011 | 0.98 | 0.5 | +| 4 | templ v0.3.1020 | Go | fair fight | 1.782 ms | ±1% | 1,782,000 | 1.01 | 0.5 | +| 5 | Razor (ASP.NET Core MVC) | .NET | fair fight | 1,812.5 μs | ±9.47 μs (SD 5.63 μs) | 1,812,500 | 1.03 | 0.5 | +| 6 | Heddle | .NET | anchor (baseline) | 1,977.7 μs | ±47.15 μs (SD 28.06 μs) | 1,977,700 | 1.12 | 0.4 | +| 7 | Handlebars.Net 2.1.6 | .NET | fair fight | 2,027.5 μs | ±15.27 μs (SD 9.08 μs) | 2,027,500 | 1.15 | 0.4 | +| 8 | Fluid.Core 2.31.0 | .NET | fair fight | 2,941.9 μs | ±191.42 μs (SD 113.91 μs) | 2,941,900 | 1.67 | 0.3 | +| 9 | eta 4.6.0 | JS | reach/context | 4.449 ms | 4.298 ms … 4.747 ms | 4,448,685 | 2.52 | 0.2 | +| 10 | handlebars 4.7.9 | JS | reach/context | 4.553 ms | 4.394 ms … 4.899 ms | 4,553,071 | 2.58 | 0.2 | +| 11 | Mako 1.3.12 | Python | reach/context | 5.23 ms | SD 72.61 μs | 5,230,128 | 2.96 | 0.2 | +| 12 | Scriban 7.2.5 | .NET | fair fight | 6,501.1 μs | ±433.82 μs (SD 258.16 μs) | 6,501,100 | 3.68 | 0.1 | +| 13 | html/template (go1.26) | Go | fair fight | 7.47 ms | ±0% | 7,470,000 | 4.23 | 0.1 | +| 14 | DotLiquid 2.3.197 | .NET | fair fight | 7,900.6 μs | ±157.76 μs (SD 93.88 μs) | 7,900,600 | 4.47 | 0.1 | +| 15 | Thymeleaf 3.1.5 | JVM | fair fight | 8.85 ms | ±55.21 μs 99.9% CI | 8,849,900 | 5.01 | 0.1 | +| 16 | Jinja2 3.1.6 | Python | reach/context | 10.37 ms | SD 105.9 μs | 10,366,914 | 5.87 | 0.1 | + +*Source: docs/benchmarks/2026-08-08 — each figure is its harness's default central-tendency point estimate, unmodified except for conversion to ns/render.* + +## Controlled track — per ecosystem + +### .NET + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (textwriter sink) ‡ | 142.7 ns | ±13.55 ns (SD 8.06 ns) | 143 | 0.96 | +| trivial-substitution | Heddle | 149.0 ns | ±7.75 ns (SD 4.61 ns) | 149 | 1.00 | +| trivial-substitution | Heddle (utf8 sink) ‡ | 161.9 ns | ±2.65 ns (SD 1.58 ns) | 162 | 1.09 | +| trivial-substitution | Handlebars.Net 2.1.6 | 385.8 ns | ±7.23 ns (SD 4.30 ns) | 386 | 2.59 | +| trivial-substitution | Fluid.Core 2.31.0 | 482.9 ns | ±20.47 ns (SD 12.18 ns) | 483 | 3.24 | +| trivial-substitution | DotLiquid 2.3.197 | 1,888.2 ns | ±20.20 ns (SD 12.02 ns) | 1,888 | 12.67 | +| trivial-substitution | Razor (ASP.NET Core MVC) | 5,523.2 ns | ±63.10 ns (SD 37.55 ns) | 5,523 | 37.07 | +| trivial-substitution | Scriban 7.2.5 | 38,805.4 ns | ±639.12 ns (SD 380.33 ns) | 38,805 | 260.44 | +| fortunes-encoded | Heddle (textwriter sink) ‡ | 640.6 ns | ±8.16 ns (SD 4.86 ns) | 641 | 0.87 | +| fortunes-encoded | Heddle (utf8 sink) ‡ | 726.3 ns | ±4.99 ns (SD 2.97 ns) | 726 | 0.98 | +| fortunes-encoded | Heddle | 739.1 ns | ±5.16 ns (SD 3.07 ns) | 739 | 1.00 | +| fortunes-encoded | Handlebars.Net 2.1.6 | 1,660.4 ns | ±194.35 ns (SD 115.66 ns) | 1,660 | 2.25 | +| fortunes-encoded | Fluid.Core 2.31.0 | 2,182.3 ns | ±120.30 ns (SD 71.59 ns) | 2,182 | 2.95 | +| fortunes-encoded | Razor (ASP.NET Core MVC) | 8,279.2 ns | ±154.23 ns (SD 91.78 ns) | 8,279 | 11.20 | +| fortunes-encoded | Scriban 7.2.5 | 15,308.6 ns | ±3,805.09 ns (SD 2,264.35 ns) | 15,309 | 20.71 | +| fortunes-encoded | DotLiquid 2.3.197 | 25,655.3 ns | ±386.31 ns (SD 229.89 ns) | 25,655 | 34.71 | +| fragment-heavy | Heddle (textwriter sink) ‡ | 2.817 μs | ±0.1876 μs (SD 0.1117 μs) | 2,817 | 0.91 | +| fragment-heavy | Heddle | 3.081 μs | ±0.1664 μs (SD 0.0990 μs) | 3,081 | 1.00 | +| fragment-heavy | Heddle (utf8 sink) ‡ | 3.460 μs | ±0.2422 μs (SD 0.1441 μs) | 3,460 | 1.12 | +| fragment-heavy | Fluid.Core 2.31.0 | 11.220 μs | ±0.4969 μs (SD 0.2957 μs) | 11,220 | 3.64 | +| fragment-heavy | Handlebars.Net 2.1.6 | 20.692 μs | ±0.3136 μs (SD 0.1866 μs) | 20,692 | 6.72 | +| fragment-heavy | Razor (ASP.NET Core MVC) | 44.056 μs | ±1.4609 μs (SD 0.8694 μs) | 44,056 | 14.30 | +| fragment-heavy | Scriban 7.2.5 | 46.476 μs | ±1.3660 μs (SD 0.8129 μs) | 46,476 | 15.08 | +| fragment-heavy | DotLiquid 2.3.197 | 170.223 μs | ±1.3890 μs (SD 0.8266 μs) | 170,223 | 55.25 | +| mixed-page | Heddle (textwriter sink) ‡ | 2.265 μs | ±0.0121 μs (SD 0.0072 μs) | 2,265 | 0.86 | +| mixed-page | Heddle | 2.636 μs | ±0.0337 μs (SD 0.0200 μs) | 2,636 | 1.00 | +| mixed-page | Heddle (utf8 sink) ‡ | 2.788 μs | ±0.1047 μs (SD 0.0623 μs) | 2,788 | 1.06 | +| mixed-page | Handlebars.Net 2.1.6 | 7.247 μs | ±0.1362 μs (SD 0.0811 μs) | 7,247 | 2.75 | +| mixed-page | Fluid.Core 2.31.0 | 8.918 μs | ±0.2473 μs (SD 0.1472 μs) | 8,918 | 3.38 | +| mixed-page | Razor (ASP.NET Core MVC) | 20.131 μs | ±0.4106 μs (SD 0.2444 μs) | 20,131 | 7.64 | +| mixed-page | DotLiquid 2.3.197 | 56.338 μs | ±2.6957 μs (SD 1.6042 μs) | 56,338 | 21.37 | +| mixed-page | Scriban 7.2.5 | 71.202 μs | ±24.5102 μs (SD 14.5856 μs) | 71,202 | 27.01 | +| conditional-heavy | Heddle (textwriter sink) ‡ | 14.53 μs | ±0.332 μs (SD 0.197 μs) | 14,530 | 0.97 | +| conditional-heavy | Heddle | 15.02 μs | ±0.852 μs (SD 0.507 μs) | 15,020 | 1.00 | +| conditional-heavy | Heddle (utf8 sink) ‡ | 18.18 μs | ±0.277 μs (SD 0.165 μs) | 18,180 | 1.21 | +| conditional-heavy | Handlebars.Net 2.1.6 | 34.51 μs | ±0.641 μs (SD 0.382 μs) | 34,510 | 2.30 | +| conditional-heavy | Razor (ASP.NET Core MVC) | 37.65 μs | ±0.257 μs (SD 0.153 μs) | 37,650 | 2.51 | +| conditional-heavy | Fluid.Core 2.31.0 | 39.32 μs | ±0.387 μs (SD 0.230 μs) | 39,320 | 2.62 | +| conditional-heavy | Scriban 7.2.5 | 105.60 μs | ±2.632 μs (SD 1.566 μs) | 105,600 | 7.03 | +| conditional-heavy | DotLiquid 2.3.197 | 343.11 μs | ±5.678 μs (SD 3.379 μs) | 343,110 | 22.84 | +| composed-page | Heddle (textwriter sink) ‡ | 1.238 μs | ±0.0085 μs (SD 0.0051 μs) | 1,238 | 0.04 | +| composed-page | Heddle (utf8 sink) ‡ | 1.798 μs | ±0.2713 μs (SD 0.1614 μs) | 1,798 | 0.05 | +| composed-page | Heddle | 34.066 μs | ±5.3035 μs (SD 3.1560 μs) | 34,066 | 1.00 | +| composed-page | Fluid.Core 2.31.0 | 60.234 μs | ±3.6891 μs (SD 2.1953 μs) | 60,234 | 1.77 | +| composed-page | Handlebars.Net 2.1.6 | 62.869 μs | ±3.8804 μs (SD 2.3092 μs) | 62,869 | 1.85 | +| composed-page | Razor (ASP.NET Core MVC) | 64.815 μs | ±10.3742 μs (SD 6.1735 μs) | 64,815 | 1.90 | +| composed-page | DotLiquid 2.3.197 | 153.755 μs | ±13.3191 μs (SD 7.9260 μs) | 153,755 | 4.51 | +| composed-page | Scriban 7.2.5 | 419.333 μs | ±30.5925 μs (SD 18.2051 μs) | 419,333 | 12.31 | +| large-loop | Heddle (textwriter sink) ‡ | 131.1 μs | ±0.60 μs (SD 0.36 μs) | 131,100 | 0.27 | +| large-loop | Heddle (utf8 sink) ‡ | 157.3 μs | ±1.83 μs (SD 1.09 μs) | 157,300 | 0.32 | +| large-loop | Heddle | 492.1 μs | ±3.46 μs (SD 2.06 μs) | 492,100 | 1.00 | +| large-loop | Handlebars.Net 2.1.6 | 742.2 μs | ±26.84 μs (SD 15.97 μs) | 742,200 | 1.51 | +| large-loop | Razor (ASP.NET Core MVC) | 744.1 μs | ±5.92 μs (SD 3.52 μs) | 744,100 | 1.51 | +| large-loop | Fluid.Core 2.31.0 | 790.1 μs | ±22.49 μs (SD 13.38 μs) | 790,100 | 1.61 | +| large-loop | Scriban 7.2.5 | 1,562.8 μs | ±30.07 μs (SD 17.89 μs) | 1,562,800 | 3.18 | +| large-loop | DotLiquid 2.3.197 | 3,735.0 μs | ±231.22 μs (SD 137.59 μs) | 3,735,000 | 7.59 | +| encoded-loop | Heddle (textwriter sink) ‡ | 610.1 μs | ±17.41 μs (SD 10.36 μs) | 610,100 | 0.35 | +| encoded-loop | Heddle (utf8 sink) ‡ | 725.3 μs | ±6.52 μs (SD 3.88 μs) | 725,300 | 0.41 | +| encoded-loop | Handlebars.Net 2.1.6 | 1,719.5 μs | ±10.84 μs (SD 6.45 μs) | 1,719,500 | 0.97 | +| encoded-loop | Razor (ASP.NET Core MVC) | 1,761.1 μs | ±24.63 μs (SD 14.66 μs) | 1,761,100 | 1.00 | +| encoded-loop | Heddle | 1,766.0 μs | ±29.51 μs (SD 17.56 μs) | 1,766,000 | 1.00 | +| encoded-loop | Fluid.Core 2.31.0 | 2,574.9 μs | ±10.52 μs (SD 6.26 μs) | 2,574,900 | 1.46 | +| encoded-loop | Scriban 7.2.5 | 6,725.7 μs | ±239.80 μs (SD 142.70 μs) | 6,725,700 | 3.81 | +| encoded-loop | DotLiquid 2.3.197 | 7,823.7 μs | ±374.27 μs (SD 222.72 μs) | 7,823,700 | 4.43 | + +‡ **Streaming-sink rows** — the same engine streaming into a caller-owned buffer that is pre-sized in untimed setup and reused across iterations, so the row is engine cost with no output materialisation. Every other row, the Heddle anchor included, materialises a string. The `vs Heddle` ratio therefore compares different work; the rows are excluded from every ranking and exist to show what a caller that can stream avoids paying. + +*Source: docs/benchmarks/2026-08-08 — fair fight evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +### Rust + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (reference) | 149 ns | — | 149 | 1.00 | +| trivial-substitution | Askama 0.16.0 | 86.01 ns | [85.9 ns, 86.13 ns] 95% CI | 86 | 0.58 | +| trivial-substitution | Tera 2.0.0 | 366 ns | [365.2 ns, 366.8 ns] 95% CI | 366 | 2.46 | +| fortunes-encoded | Heddle (reference) | 739.1 ns | — | 739 | 1.00 | +| fortunes-encoded | Askama 0.16.0 | 423.3 ns | [422.9 ns, 423.8 ns] 95% CI | 423 | 0.57 | +| fortunes-encoded | Tera 2.0.0 | 3.458 μs | [3.457 μs, 3.46 μs] 95% CI | 3,458 | 4.68 | +| fragment-heavy | Heddle (reference) | 3.081 μs | — | 3,081 | 1.00 | +| fragment-heavy | Askama 0.16.0 | 900.4 ns | [899.4 ns, 901.3 ns] 95% CI | 900 | 0.29 | +| fragment-heavy | Tera 2.0.0 | 12.12 μs | [12.12 μs, 12.13 μs] 95% CI | 12,124 | 3.94 | +| mixed-page | Heddle (reference) | 2.636 μs | — | 2,636 | 1.00 | +| mixed-page | Askama 0.16.0 | 1.108 μs | [1.108 μs, 1.109 μs] 95% CI | 1,108 | 0.42 | +| mixed-page | Tera 2.0.0 | 5.701 μs | [5.697 μs, 5.705 μs] 95% CI | 5,701 | 2.16 | +| conditional-heavy | Heddle (reference) | 15.02 μs | — | 15,020 | 1.00 | +| conditional-heavy | Askama 0.16.0 | 3.752 μs | [3.749 μs, 3.755 μs] 95% CI | 3,752 | 0.25 | +| conditional-heavy | Tera 2.0.0 | 41.05 μs | [41.03 μs, 41.08 μs] 95% CI | 41,053 | 2.73 | +| composed-page | Heddle (reference) | 34.07 μs | — | 34,066 | 1.00 | +| composed-page | Askama 0.16.0 | 1.455 μs | [1.454 μs, 1.455 μs] 95% CI | 1,455 | 0.04 | +| composed-page | Tera 2.0.0 | 3.578 μs | [3.576 μs, 3.58 μs] 95% CI | 3,578 | 0.11 | +| large-loop | Heddle (reference) | 492.1 μs | — | 492,100 | 1.00 | +| large-loop | Askama 0.16.0 | 60.57 μs | [59.96 μs, 61.18 μs] 95% CI | 60,568 | 0.12 | +| large-loop | Tera 2.0.0 | 328.5 μs | [328.4 μs, 328.6 μs] 95% CI | 328,491 | 0.67 | +| encoded-loop | Heddle (reference) | 1.766 ms | — | 1,766,000 | 1.00 | +| encoded-loop | Askama 0.16.0 | 619.4 μs | [615.3 μs, 623.6 μs] 95% CI | 619,437 | 0.35 | +| encoded-loop | Tera 2.0.0 | 1.691 ms | [1.69 ms, 1.693 ms] 95% CI | 1,691,277 | 0.96 | + +*Source: docs/benchmarks/2026-08-08 — fair fight evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +### JVM + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (reference) | 149 ns | — | 149 | 1.00 | +| trivial-substitution | JTE 3.2.4 | 350.6 ns | ±3.052 ns 99.9% CI | 351 | 2.35 | +| trivial-substitution | Thymeleaf 3.1.5 | 7.205 μs | ±116 ns 99.9% CI | 7,205 | 48.35 | +| fortunes-encoded | Heddle (reference) | 739.1 ns | — | 739 | 1.00 | +| fortunes-encoded | JTE 3.2.4 | 1.673 μs | ±26.4 ns 99.9% CI | 1,673 | 2.26 | +| fortunes-encoded | Thymeleaf 3.1.5 | 10.14 μs | ±233.4 ns 99.9% CI | 10,136 | 13.71 | +| fragment-heavy | Heddle (reference) | 3.081 μs | — | 3,081 | 1.00 | +| fragment-heavy | JTE 3.2.4 | 1.699 μs | ±9.481 ns 99.9% CI | 1,699 | 0.55 | +| fragment-heavy | Thymeleaf 3.1.5 | 145 μs | ±2.316 μs 99.9% CI | 144,991 | 47.06 | +| mixed-page | Heddle (reference) | 2.636 μs | — | 2,636 | 1.00 | +| mixed-page | JTE 3.2.4 | 2.835 μs | ±44.26 ns 99.9% CI | 2,835 | 1.08 | +| mixed-page | Thymeleaf 3.1.5 | 118.6 μs | ±848.7 ns 99.9% CI | 118,601 | 44.99 | +| conditional-heavy | Heddle (reference) | 15.02 μs | — | 15,020 | 1.00 | +| conditional-heavy | JTE 3.2.4 | 7.423 μs | ±86.46 ns 99.9% CI | 7,423 | 0.49 | +| conditional-heavy | Thymeleaf 3.1.5 | 461.9 μs | ±3.351 μs 99.9% CI | 461,900 | 30.75 | +| composed-page | Heddle (reference) | 34.07 μs | — | 34,066 | 1.00 | +| composed-page | JTE 3.2.4 | 14.44 μs | ±33.93 ns 99.9% CI | 14,437 | 0.42 | +| composed-page | Thymeleaf 3.1.5 | 21.52 μs | ±101.4 ns 99.9% CI | 21,517 | 0.63 | +| large-loop | Heddle (reference) | 492.1 μs | — | 492,100 | 1.00 | +| large-loop | JTE 3.2.4 | 112.2 μs | ±761.5 ns 99.9% CI | 112,228 | 0.23 | +| large-loop | Thymeleaf 3.1.5 | 6.649 ms | ±59.32 μs 99.9% CI | 6,648,937 | 13.51 | +| encoded-loop | Heddle (reference) | 1.766 ms | — | 1,766,000 | 1.00 | +| encoded-loop | JTE 3.2.4 | 1.402 ms | ±339.1 μs 99.9% CI | 1,402,244 | 0.79 | +| encoded-loop | Thymeleaf 3.1.5 | 8.31 ms | ±37.79 μs 99.9% CI | 8,309,714 | 4.71 | + +*Source: docs/benchmarks/2026-08-08 — fair fight evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +### JS + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (reference) | 149 ns | — | 149 | 1.00 | +| trivial-substitution | eta 4.6.0 | 135.4 ns | 130.7 ns … 147.3 ns | 135 | 0.91 | +| trivial-substitution | handlebars 4.7.9 | 742.5 ns | 719.3 ns … 767.6 ns | 743 | 4.98 | +| fortunes-encoded | Heddle (reference) | 739.1 ns | — | 739 | 1.00 | +| fortunes-encoded | eta 4.6.0 | 1.826 μs | 1.757 μs … 1.88 μs | 1,826 | 2.47 | +| fortunes-encoded | handlebars 4.7.9 | 2.645 μs | 2.594 μs … 2.735 μs | 2,645 | 3.58 | +| fragment-heavy | Heddle (reference) | 3.081 μs | — | 3,081 | 1.00 | +| fragment-heavy | eta 4.6.0 | 4.809 μs | 4.755 μs … 5.062 μs | 4,809 | 1.56 | +| fragment-heavy | handlebars 4.7.9 | 6.651 μs | 6.571 μs … 7.295 μs | 6,651 | 2.16 | +| mixed-page | Heddle (reference) | 2.636 μs | — | 2,636 | 1.00 | +| mixed-page | eta 4.6.0 | 3.004 μs | 2.938 μs … 3.034 μs | 3,004 | 1.14 | +| mixed-page | handlebars 4.7.9 | 7.667 μs | 7.296 μs … 9.421 μs | 7,667 | 2.91 | +| conditional-heavy | Heddle (reference) | 15.02 μs | — | 15,020 | 1.00 | +| conditional-heavy | eta 4.6.0 | 10.54 μs | 10.42 μs … 10.68 μs | 10,538 | 0.70 | +| conditional-heavy | handlebars 4.7.9 | 101.6 μs | 93.57 μs … 110.1 μs | 101,571 | 6.76 | +| composed-page | Heddle (reference) | 34.07 μs | — | 34,066 | 1.00 | +| composed-page | eta 4.6.0 | 4.235 μs | 4.181 μs … 4.31 μs | 4,235 | 0.12 | +| composed-page | handlebars 4.7.9 | 5.414 μs | 5.27 μs … 5.506 μs | 5,414 | 0.16 | +| large-loop | Heddle (reference) | 492.1 μs | — | 492,100 | 1.00 | +| large-loop | eta 4.6.0 | 250.1 μs | 247.6 μs … 256.7 μs | 250,076 | 0.51 | +| large-loop | handlebars 4.7.9 | 407.3 μs | 401 μs … 420.3 μs | 407,297 | 0.83 | +| encoded-loop | Heddle (reference) | 1.766 ms | — | 1,766,000 | 1.00 | +| encoded-loop | eta 4.6.0 | 4.436 ms | 4.302 ms … 4.579 ms | 4,436,399 | 2.51 | +| encoded-loop | handlebars 4.7.9 | 4.713 ms | 4.57 ms … 4.867 ms | 4,712,629 | 2.67 | + +*Source: docs/benchmarks/2026-08-08 — reach/context evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +### Python + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (reference) | 149 ns | — | 149 | 1.00 | +| trivial-substitution | Jinja2 3.1.6 | 4.668 μs | SD 52.72 ns | 4,668 | 31.33 | +| trivial-substitution | Mako 1.3.12 | 5.635 μs | SD 42.39 ns | 5,635 | 37.82 | +| fortunes-encoded | Heddle (reference) | 739.1 ns | — | 739 | 1.00 | +| fortunes-encoded | Mako 1.3.12 | 11.37 μs | SD 78.72 ns | 11,367 | 15.38 | +| fortunes-encoded | Jinja2 3.1.6 | 19.59 μs | SD 157.7 ns | 19,594 | 26.51 | +| fragment-heavy | Heddle (reference) | 3.081 μs | — | 3,081 | 1.00 | +| fragment-heavy | Mako 1.3.12 | 480.4 μs | SD 5.294 μs | 480,450 | 155.94 | +| fragment-heavy | Jinja2 3.1.6 | 498.4 μs | SD 1.52 μs | 498,444 | 161.78 | +| mixed-page | Heddle (reference) | 2.636 μs | — | 2,636 | 1.00 | +| mixed-page | Mako 1.3.12 | 14.38 μs | SD 185.9 ns | 14,376 | 5.45 | +| mixed-page | Jinja2 3.1.6 | 62.73 μs | SD 564.2 ns | 62,734 | 23.80 | +| conditional-heavy | Heddle (reference) | 15.02 μs | — | 15,020 | 1.00 | +| conditional-heavy | Mako 1.3.12 | 39.85 μs | SD 1.104 μs | 39,852 | 2.65 | +| conditional-heavy | Jinja2 3.1.6 | 337.7 μs | SD 3.03 μs | 337,702 | 22.48 | +| composed-page | Heddle (reference) | 34.07 μs | — | 34,066 | 1.00 | +| composed-page | Mako 1.3.12 | 17.05 μs | SD 509.3 ns | 17,050 | 0.50 | +| composed-page | Jinja2 3.1.6 | 19.36 μs | SD 391.1 ns | 19,363 | 0.57 | +| large-loop | Heddle (reference) | 492.1 μs | — | 492,100 | 1.00 | +| large-loop | Mako 1.3.12 | 562.2 μs | SD 7.099 μs | 562,167 | 1.14 | +| large-loop | Jinja2 3.1.6 | 3.387 ms | SD 38.4 μs | 3,387,044 | 6.88 | +| encoded-loop | Heddle (reference) | 1.766 ms | — | 1,766,000 | 1.00 | +| encoded-loop | Mako 1.3.12 | 5.005 ms | SD 60.27 μs | 5,005,346 | 2.83 | +| encoded-loop | Jinja2 3.1.6 | 10.39 ms | SD 111.8 μs | 10,387,159 | 5.88 | + +*Source: docs/benchmarks/2026-08-08 — reach/context evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +### Go + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (reference) | 149 ns | — | 149 | 1.00 | +| trivial-substitution | templ v0.3.1020 | 618.3 ns | ±0% | 618 | 4.15 | +| trivial-substitution | text/template (go1.26) | 1.042 μs | ±0% | 1,042 | 6.99 | +| fortunes-encoded | Heddle (reference) | 739.1 ns | — | 739 | 1.00 | +| fortunes-encoded | templ v0.3.1020 | 1.727 μs | ±0% | 1,727 | 2.34 | +| fortunes-encoded | html/template (go1.26) | 11.61 μs | ±0% | 11,610 | 15.71 | +| fragment-heavy | Heddle (reference) | 3.081 μs | — | 3,081 | 1.00 | +| fragment-heavy | templ v0.3.1020 | 9.748 μs | ±0% | 9,748 | 3.16 | +| fragment-heavy | text/template (go1.26) | 20.87 μs | ±0% | 20,870 | 6.77 | +| mixed-page | Heddle (reference) | 2.636 μs | — | 2,636 | 1.00 | +| mixed-page | templ v0.3.1020 | 9.707 μs | ±1% | 9,707 | 3.68 | +| mixed-page | text/template (go1.26) | 22.15 μs | ±0% | 22,150 | 8.40 | +| conditional-heavy | Heddle (reference) | 15.02 μs | — | 15,020 | 1.00 | +| conditional-heavy | templ v0.3.1020 | 21.57 μs | ±0% | 21,570 | 1.44 | +| conditional-heavy | text/template (go1.26) | 94.49 μs | ±0% | 94,490 | 6.29 | +| composed-page | Heddle (reference) | 34.07 μs | — | 34,066 | 1.00 | +| composed-page | templ v0.3.1020 | 3.953 μs | ±3% | 3,953 | 0.12 | +| composed-page | text/template (go1.26) | 13.78 μs | ±1% | 13,780 | 0.40 | +| large-loop | Heddle (reference) | 492.1 μs | — | 492,100 | 1.00 | +| large-loop | templ v0.3.1020 | 509.5 μs | ±0% | 509,500 | 1.04 | +| large-loop | text/template (go1.26) | 1.202 ms | ±0% | 1,202,000 | 2.44 | +| encoded-loop | Heddle (reference) | 1.766 ms | — | 1,766,000 | 1.00 | +| encoded-loop | templ v0.3.1020 | 1.286 ms | ±1% | 1,286,000 | 0.73 | +| encoded-loop | html/template (go1.26) | 7.469 ms | ±0% | 7,469,000 | 4.23 | + +*Source: docs/benchmarks/2026-08-08 — fair fight evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +## Idiomatic track — per ecosystem + +### .NET + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (textwriter sink) ‡ | 141.6 ns | ±13.85 ns (SD 8.24 ns) | 142 | 0.95 | +| trivial-substitution | Heddle | 148.1 ns | ±5.21 ns (SD 3.10 ns) | 148 | 0.99 | +| trivial-substitution | Heddle (utf8 sink) ‡ | 160.4 ns | ±2.34 ns (SD 1.39 ns) | 160 | 1.08 | +| trivial-substitution | Handlebars.Net 2.1.6 | 461.2 ns | ±4.16 ns (SD 2.48 ns) | 461 | 3.10 | +| trivial-substitution | Fluid.Core 2.31.0 | 491.4 ns | ±21.52 ns (SD 12.81 ns) | 491 | 3.30 | +| trivial-substitution | DotLiquid 2.3.197 | 1,925.7 ns | ±37.68 ns (SD 22.42 ns) | 1,926 | 12.92 | +| trivial-substitution | Razor (ASP.NET Core MVC) | 4,833.0 ns | ±49.84 ns (SD 29.66 ns) | 4,833 | 32.44 | +| trivial-substitution | Scriban 7.2.5 | 38,709.8 ns | ±3,542.32 ns (SD 2,107.98 ns) | 38,710 | 259.80 | +| fortunes-encoded | Heddle (textwriter sink) ‡ | 648.3 ns | ±27.29 ns (SD 16.24 ns) | 648 | 0.88 | +| fortunes-encoded | Heddle (utf8 sink) ‡ | 734.9 ns | ±22.65 ns (SD 13.48 ns) | 735 | 0.99 | +| fortunes-encoded | Heddle | 763.2 ns | ±7.03 ns (SD 4.19 ns) | 763 | 1.03 | +| fortunes-encoded | Handlebars.Net 2.1.6 | 1,563.6 ns | ±23.87 ns (SD 14.21 ns) | 1,564 | 2.12 | +| fortunes-encoded | Fluid.Core 2.31.0 | 2,189.8 ns | ±69.50 ns (SD 41.36 ns) | 2,190 | 2.96 | +| fortunes-encoded | Razor (ASP.NET Core MVC) | 8,434.6 ns | ±183.55 ns (SD 109.22 ns) | 8,435 | 11.41 | +| fortunes-encoded | Scriban 7.2.5 | 16,562.8 ns | ±485.71 ns (SD 289.04 ns) | 16,563 | 22.41 | +| fortunes-encoded | DotLiquid 2.3.197 | 25,677.9 ns | ±571.67 ns (SD 340.19 ns) | 25,678 | 34.74 | +| fragment-heavy | Heddle (textwriter sink) ‡ | 2.899 μs | ±0.3339 μs (SD 0.1987 μs) | 2,899 | 0.94 | +| fragment-heavy | Heddle | 3.285 μs | ±0.4394 μs (SD 0.2615 μs) | 3,285 | 1.07 | +| fragment-heavy | Heddle (utf8 sink) ‡ | 3.515 μs | ±0.2909 μs (SD 0.1731 μs) | 3,515 | 1.14 | +| fragment-heavy | Fluid.Core 2.31.0 | 11.798 μs | ±0.2033 μs (SD 0.1210 μs) | 11,798 | 3.83 | +| fragment-heavy | Handlebars.Net 2.1.6 | 21.373 μs | ±0.8808 μs (SD 0.5241 μs) | 21,373 | 6.94 | +| fragment-heavy | Razor (ASP.NET Core MVC) | 36.889 μs | ±0.4233 μs (SD 0.2519 μs) | 36,889 | 11.97 | +| fragment-heavy | Scriban 7.2.5 | 52.684 μs | ±1.5357 μs (SD 0.9139 μs) | 52,684 | 17.10 | +| fragment-heavy | DotLiquid 2.3.197 | 278.300 μs | ±5.1166 μs (SD 3.0448 μs) | 278,300 | 90.33 | +| mixed-page | Heddle (textwriter sink) ‡ | 2.304 μs | ±0.0205 μs (SD 0.0122 μs) | 2,304 | 0.87 | +| mixed-page | Heddle (utf8 sink) ‡ | 2.754 μs | ±0.0365 μs (SD 0.0217 μs) | 2,754 | 1.04 | +| mixed-page | Heddle | 2.906 μs | ±0.0269 μs (SD 0.0160 μs) | 2,906 | 1.10 | +| mixed-page | Fluid.Core 2.31.0 | 9.115 μs | ±0.4819 μs (SD 0.2868 μs) | 9,115 | 3.46 | +| mixed-page | Handlebars.Net 2.1.6 | 10.260 μs | ±0.2998 μs (SD 0.1784 μs) | 10,260 | 3.89 | +| mixed-page | Razor (ASP.NET Core MVC) | 15.505 μs | ±0.2166 μs (SD 0.1289 μs) | 15,505 | 5.88 | +| mixed-page | DotLiquid 2.3.197 | 59.112 μs | ±1.9223 μs (SD 1.1439 μs) | 59,112 | 22.42 | +| mixed-page | Scriban 7.2.5 | 68.265 μs | ±13.4083 μs (SD 7.9790 μs) | 68,265 | 25.90 | +| conditional-heavy | Heddle (textwriter sink) ‡ | 14.86 μs | ±0.205 μs (SD 0.122 μs) | 14,860 | 0.99 | +| conditional-heavy | Heddle | 15.70 μs | ±0.395 μs (SD 0.235 μs) | 15,700 | 1.05 | +| conditional-heavy | Heddle (utf8 sink) ‡ | 18.87 μs | ±0.466 μs (SD 0.277 μs) | 18,870 | 1.26 | +| conditional-heavy | Razor (ASP.NET Core MVC) | 25.25 μs | ±0.395 μs (SD 0.235 μs) | 25,250 | 1.68 | +| conditional-heavy | Handlebars.Net 2.1.6 | 37.04 μs | ±0.174 μs (SD 0.103 μs) | 37,040 | 2.47 | +| conditional-heavy | Fluid.Core 2.31.0 | 40.62 μs | ±0.369 μs (SD 0.219 μs) | 40,620 | 2.70 | +| conditional-heavy | Scriban 7.2.5 | 112.02 μs | ±4.699 μs (SD 2.796 μs) | 112,020 | 7.46 | +| conditional-heavy | DotLiquid 2.3.197 | 354.09 μs | ±7.533 μs (SD 4.483 μs) | 354,090 | 23.57 | +| composed-page | Heddle (textwriter sink) ‡ | 1.260 μs | ±0.0123 μs (SD 0.0073 μs) | 1,260 | 0.04 | +| composed-page | Heddle (utf8 sink) ‡ | 1.883 μs | ±0.1831 μs (SD 0.1089 μs) | 1,883 | 0.06 | +| composed-page | Heddle | 32.761 μs | ±4.1901 μs (SD 2.4935 μs) | 32,761 | 0.96 | +| composed-page | Razor (ASP.NET Core MVC) | 59.550 μs | ±13.8188 μs (SD 8.2233 μs) | 59,550 | 1.75 | +| composed-page | Fluid.Core 2.31.0 | 60.527 μs | ±3.2964 μs (SD 1.9616 μs) | 60,527 | 1.78 | +| composed-page | Handlebars.Net 2.1.6 | 64.713 μs | ±6.4197 μs (SD 3.8203 μs) | 64,713 | 1.90 | +| composed-page | DotLiquid 2.3.197 | 194.211 μs | ±9.8814 μs (SD 5.8802 μs) | 194,211 | 5.70 | +| composed-page | Scriban 7.2.5 | 431.057 μs | ±40.3621 μs (SD 24.0189 μs) | 431,057 | 12.65 | +| large-loop | Heddle (textwriter sink) ‡ | 131.7 μs | ±2.63 μs (SD 1.56 μs) | 131,700 | 0.27 | +| large-loop | Heddle (utf8 sink) ‡ | 158.0 μs | ±5.31 μs (SD 3.16 μs) | 158,000 | 0.32 | +| large-loop | Heddle | 566.1 μs | ±7.08 μs (SD 4.21 μs) | 566,100 | 1.15 | +| large-loop | Razor (ASP.NET Core MVC) | 569.7 μs | ±8.76 μs (SD 5.21 μs) | 569,700 | 1.16 | +| large-loop | Handlebars.Net 2.1.6 | 780.0 μs | ±33.19 μs (SD 19.75 μs) | 780,000 | 1.59 | +| large-loop | Fluid.Core 2.31.0 | 859.7 μs | ±10.35 μs (SD 6.16 μs) | 859,700 | 1.75 | +| large-loop | Scriban 7.2.5 | 1,615.7 μs | ±75.75 μs (SD 45.08 μs) | 1,615,700 | 3.28 | +| large-loop | DotLiquid 2.3.197 | 3,795.1 μs | ±28.20 μs (SD 16.78 μs) | 3,795,100 | 7.71 | +| encoded-loop | Heddle (textwriter sink) ‡ | 605.5 μs | ±12.61 μs (SD 7.50 μs) | 605,500 | 0.34 | +| encoded-loop | Heddle (utf8 sink) ‡ | 712.3 μs | ±7.81 μs (SD 4.65 μs) | 712,300 | 0.40 | +| encoded-loop | Razor (ASP.NET Core MVC) | 1,812.5 μs | ±9.47 μs (SD 5.63 μs) | 1,812,500 | 1.03 | +| encoded-loop | Heddle | 1,977.7 μs | ±47.15 μs (SD 28.06 μs) | 1,977,700 | 1.12 | +| encoded-loop | Handlebars.Net 2.1.6 | 2,027.5 μs | ±15.27 μs (SD 9.08 μs) | 2,027,500 | 1.15 | +| encoded-loop | Fluid.Core 2.31.0 | 2,941.9 μs | ±191.42 μs (SD 113.91 μs) | 2,941,900 | 1.67 | +| encoded-loop | Scriban 7.2.5 | 6,501.1 μs | ±433.82 μs (SD 258.16 μs) | 6,501,100 | 3.68 | +| encoded-loop | DotLiquid 2.3.197 | 7,900.6 μs | ±157.76 μs (SD 93.88 μs) | 7,900,600 | 4.47 | + +‡ **Streaming-sink rows** — the same engine streaming into a caller-owned buffer that is pre-sized in untimed setup and reused across iterations, so the row is engine cost with no output materialisation. Every other row, the Heddle anchor included, materialises a string. The `vs Heddle` ratio therefore compares different work; the rows are excluded from every ranking and exist to show what a caller that can stream avoids paying. + +*Source: docs/benchmarks/2026-08-08 — fair fight evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +### Rust + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (reference) | 149 ns | — | 149 | 1.00 | +| trivial-substitution | Askama 0.16.0 | 130.4 ns | [130.2 ns, 130.7 ns] 95% CI | 130 | 0.88 | +| trivial-substitution | Tera 2.0.0 | 804.1 ns | [802.7 ns, 805.6 ns] 95% CI | 804 | 5.40 | +| fortunes-encoded | Heddle (reference) | 739.1 ns | — | 739 | 1.00 | +| fortunes-encoded | Askama 0.16.0 | 435.1 ns | [433.5 ns, 436.7 ns] 95% CI | 435 | 0.59 | +| fortunes-encoded | Tera 2.0.0 | 3.454 μs | [3.453 μs, 3.455 μs] 95% CI | 3,454 | 4.67 | +| fragment-heavy | Heddle (reference) | 3.081 μs | — | 3,081 | 1.00 | +| fragment-heavy | Askama 0.16.0 | 1.184 μs | [1.181 μs, 1.186 μs] 95% CI | 1,184 | 0.38 | +| fragment-heavy | Tera 2.0.0 | 14.52 μs | [14.51 μs, 14.54 μs] 95% CI | 14,525 | 4.71 | +| mixed-page | Heddle (reference) | 2.636 μs | — | 2,636 | 1.00 | +| mixed-page | Askama 0.16.0 | 2.3 μs | [2.296 μs, 2.304 μs] 95% CI | 2,300 | 0.87 | +| mixed-page | Tera 2.0.0 | 22.65 μs | [22.63 μs, 22.66 μs] 95% CI | 22,646 | 8.59 | +| conditional-heavy | Heddle (reference) | 15.02 μs | — | 15,020 | 1.00 | +| conditional-heavy | Askama 0.16.0 | 5.392 μs | [5.379 μs, 5.406 μs] 95% CI | 5,392 | 0.36 | +| conditional-heavy | Tera 2.0.0 | 51.41 μs | [51.37 μs, 51.45 μs] 95% CI | 51,412 | 3.42 | +| composed-page | Heddle (reference) | 34.07 μs | — | 34,066 | 1.00 | +| composed-page | Askama 0.16.0 | 1.529 μs | [1.528 μs, 1.53 μs] 95% CI | 1,529 | 0.04 | +| composed-page | Tera 2.0.0 | 5.597 μs | [5.593 μs, 5.601 μs] 95% CI | 5,597 | 0.16 | +| large-loop | Heddle (reference) | 492.1 μs | — | 492,100 | 1.00 | +| large-loop | Askama 0.16.0 | 78.19 μs | [77.76 μs, 78.6 μs] 95% CI | 78,189 | 0.16 | +| large-loop | Tera 2.0.0 | 493.3 μs | [492.8 μs, 493.8 μs] 95% CI | 493,282 | 1.00 | +| encoded-loop | Heddle (reference) | 1.766 ms | — | 1,766,000 | 1.00 | +| encoded-loop | Askama 0.16.0 | 591.8 μs | [589.5 μs, 594.2 μs] 95% CI | 591,806 | 0.34 | +| encoded-loop | Tera 2.0.0 | 1.723 ms | [1.721 ms, 1.725 ms] 95% CI | 1,723,011 | 0.98 | + +*Source: docs/benchmarks/2026-08-08 — fair fight evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +### JVM + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (reference) | 149 ns | — | 149 | 1.00 | +| trivial-substitution | JTE 3.2.4 | 368.4 ns | ±0.8194 ns 99.9% CI | 368 | 2.47 | +| trivial-substitution | Thymeleaf 3.1.5 | 6.61 μs | ±80.16 ns 99.9% CI | 6,610 | 44.36 | +| fortunes-encoded | Heddle (reference) | 739.1 ns | — | 739 | 1.00 | +| fortunes-encoded | JTE 3.2.4 | 1.46 μs | ±40.72 ns 99.9% CI | 1,460 | 1.98 | +| fortunes-encoded | Thymeleaf 3.1.5 | 9.122 μs | ±81.84 ns 99.9% CI | 9,122 | 12.34 | +| fragment-heavy | Heddle (reference) | 3.081 μs | — | 3,081 | 1.00 | +| fragment-heavy | JTE 3.2.4 | 2.035 μs | ±10.9 ns 99.9% CI | 2,035 | 0.66 | +| fragment-heavy | Thymeleaf 3.1.5 | 138.3 μs | ±1.031 μs 99.9% CI | 138,347 | 44.90 | +| mixed-page | Heddle (reference) | 2.636 μs | — | 2,636 | 1.00 | +| mixed-page | JTE 3.2.4 | 3.023 μs | ±7.675 ns 99.9% CI | 3,023 | 1.15 | +| mixed-page | Thymeleaf 3.1.5 | 114.3 μs | ±1.179 μs 99.9% CI | 114,270 | 43.35 | +| conditional-heavy | Heddle (reference) | 15.02 μs | — | 15,020 | 1.00 | +| conditional-heavy | JTE 3.2.4 | 12.44 μs | ±28.72 ns 99.9% CI | 12,444 | 0.83 | +| conditional-heavy | Thymeleaf 3.1.5 | 457.6 μs | ±2.891 μs 99.9% CI | 457,644 | 30.47 | +| composed-page | Heddle (reference) | 34.07 μs | — | 34,066 | 1.00 | +| composed-page | JTE 3.2.4 | 14.51 μs | ±27.35 ns 99.9% CI | 14,511 | 0.43 | +| composed-page | Thymeleaf 3.1.5 | 21.44 μs | ±68.17 ns 99.9% CI | 21,441 | 0.63 | +| large-loop | Heddle (reference) | 492.1 μs | — | 492,100 | 1.00 | +| large-loop | JTE 3.2.4 | 132.3 μs | ±1.188 μs 99.9% CI | 132,278 | 0.27 | +| large-loop | Thymeleaf 3.1.5 | 6.277 ms | ±225.8 μs 99.9% CI | 6,276,528 | 12.75 | +| encoded-loop | Heddle (reference) | 1.766 ms | — | 1,766,000 | 1.00 | +| encoded-loop | JTE 3.2.4 | 1.072 ms | ±6.388 μs 99.9% CI | 1,072,307 | 0.61 | +| encoded-loop | Thymeleaf 3.1.5 | 8.85 ms | ±55.21 μs 99.9% CI | 8,849,900 | 5.01 | + +*Source: docs/benchmarks/2026-08-08 — fair fight evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +### JS + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (reference) | 149 ns | — | 149 | 1.00 | +| trivial-substitution | eta 4.6.0 | 253.6 ns | 244.7 ns … 276.1 ns | 254 | 1.70 | +| trivial-substitution | handlebars 4.7.9 | 629.5 ns | 609.9 ns … 650.8 ns | 630 | 4.22 | +| fortunes-encoded | Heddle (reference) | 739.1 ns | — | 739 | 1.00 | +| fortunes-encoded | eta 4.6.0 | 1.859 μs | 1.812 μs … 1.999 μs | 1,859 | 2.52 | +| fortunes-encoded | handlebars 4.7.9 | 2.473 μs | 2.443 μs … 2.721 μs | 2,473 | 3.35 | +| fragment-heavy | Heddle (reference) | 3.081 μs | — | 3,081 | 1.00 | +| fragment-heavy | handlebars 4.7.9 | 5.763 μs | 5.68 μs … 6.392 μs | 5,763 | 1.87 | +| fragment-heavy | eta 4.6.0 | 6.508 μs | 6.428 μs … 6.8 μs | 6,508 | 2.11 | +| mixed-page | Heddle (reference) | 2.636 μs | — | 2,636 | 1.00 | +| mixed-page | eta 4.6.0 | 4.956 μs | 4.922 μs … 5.047 μs | 4,956 | 1.88 | +| mixed-page | handlebars 4.7.9 | 6.471 μs | 6.268 μs … 7.75 μs | 6,471 | 2.45 | +| conditional-heavy | Heddle (reference) | 15.02 μs | — | 15,020 | 1.00 | +| conditional-heavy | eta 4.6.0 | 15.33 μs | 15.21 μs … 15.77 μs | 15,326 | 1.02 | +| conditional-heavy | handlebars 4.7.9 | 98.23 μs | 90.99 μs … 110.7 μs | 98,231 | 6.54 | +| composed-page | Heddle (reference) | 34.07 μs | — | 34,066 | 1.00 | +| composed-page | eta 4.6.0 | 4.231 μs | 4.195 μs … 4.318 μs | 4,231 | 0.12 | +| composed-page | handlebars 4.7.9 | 5.322 μs | 5.271 μs … 5.38 μs | 5,322 | 0.16 | +| large-loop | Heddle (reference) | 492.1 μs | — | 492,100 | 1.00 | +| large-loop | handlebars 4.7.9 | 355.8 μs | 352.4 μs … 442 μs | 355,768 | 0.72 | +| large-loop | eta 4.6.0 | 355.8 μs | 352.4 μs … 361.6 μs | 355,803 | 0.72 | +| encoded-loop | Heddle (reference) | 1.766 ms | — | 1,766,000 | 1.00 | +| encoded-loop | eta 4.6.0 | 4.449 ms | 4.298 ms … 4.747 ms | 4,448,685 | 2.52 | +| encoded-loop | handlebars 4.7.9 | 4.553 ms | 4.394 ms … 4.899 ms | 4,553,071 | 2.58 | + +*Source: docs/benchmarks/2026-08-08 — reach/context evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +### Python + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (reference) | 149 ns | — | 149 | 1.00 | +| trivial-substitution | Jinja2 3.1.6 | 4.761 μs | SD 46.83 ns | 4,761 | 31.95 | +| trivial-substitution | Mako 1.3.12 | 5.641 μs | SD 48.36 ns | 5,641 | 37.86 | +| fortunes-encoded | Heddle (reference) | 739.1 ns | — | 739 | 1.00 | +| fortunes-encoded | Mako 1.3.12 | 11.28 μs | SD 94.33 ns | 11,281 | 15.26 | +| fortunes-encoded | Jinja2 3.1.6 | 19.65 μs | SD 148.3 ns | 19,649 | 26.59 | +| fragment-heavy | Heddle (reference) | 3.081 μs | — | 3,081 | 1.00 | +| fragment-heavy | Mako 1.3.12 | 29.92 μs | SD 402.2 ns | 29,922 | 9.71 | +| fragment-heavy | Jinja2 3.1.6 | 104.9 μs | SD 541.8 ns | 104,873 | 34.04 | +| mixed-page | Heddle (reference) | 2.636 μs | — | 2,636 | 1.00 | +| mixed-page | Mako 1.3.12 | 27.11 μs | SD 331.2 ns | 27,107 | 10.28 | +| mixed-page | Jinja2 3.1.6 | 79.35 μs | SD 709.2 ns | 79,348 | 30.10 | +| conditional-heavy | Heddle (reference) | 15.02 μs | — | 15,020 | 1.00 | +| conditional-heavy | Mako 1.3.12 | 39.54 μs | SD 828.5 ns | 39,536 | 2.63 | +| conditional-heavy | Jinja2 3.1.6 | 344.7 μs | SD 3.438 μs | 344,651 | 22.95 | +| composed-page | Heddle (reference) | 34.07 μs | — | 34,066 | 1.00 | +| composed-page | Mako 1.3.12 | 17.46 μs | SD 600.2 ns | 17,463 | 0.51 | +| composed-page | Jinja2 3.1.6 | 19.29 μs | SD 302.5 ns | 19,287 | 0.57 | +| large-loop | Heddle (reference) | 492.1 μs | — | 492,100 | 1.00 | +| large-loop | Mako 1.3.12 | 570.8 μs | SD 6.691 μs | 570,801 | 1.16 | +| large-loop | Jinja2 3.1.6 | 3.38 ms | SD 44.43 μs | 3,379,516 | 6.87 | +| encoded-loop | Heddle (reference) | 1.766 ms | — | 1,766,000 | 1.00 | +| encoded-loop | Mako 1.3.12 | 5.23 ms | SD 72.61 μs | 5,230,128 | 2.96 | +| encoded-loop | Jinja2 3.1.6 | 10.37 ms | SD 105.9 μs | 10,366,914 | 5.87 | + +*Source: docs/benchmarks/2026-08-08 — reach/context evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +### Go + +| Workload | Engine | harness statistic | harness dispersion | ns/render | vs Heddle | +| --- | --- | ---: | ---: | ---: | ---: | +| trivial-substitution | Heddle (reference) | 149 ns | — | 149 | 1.00 | +| trivial-substitution | templ v0.3.1020 | 626.9 ns | ±1% | 627 | 4.21 | +| trivial-substitution | text/template (go1.26) | 1.055 μs | ±1% | 1,055 | 7.08 | +| fortunes-encoded | Heddle (reference) | 739.1 ns | — | 739 | 1.00 | +| fortunes-encoded | templ v0.3.1020 | 2.66 μs | ±2% | 2,660 | 3.60 | +| fortunes-encoded | html/template (go1.26) | 11.68 μs | ±0% | 11,680 | 15.80 | +| fragment-heavy | Heddle (reference) | 3.081 μs | — | 3,081 | 1.00 | +| fragment-heavy | templ v0.3.1020 | 10.34 μs | ±1% | 10,340 | 3.36 | +| fragment-heavy | text/template (go1.26) | 21.9 μs | ±0% | 21,900 | 7.11 | +| mixed-page | Heddle (reference) | 2.636 μs | — | 2,636 | 1.00 | +| mixed-page | templ v0.3.1020 | 12.79 μs | ±2% | 12,790 | 4.85 | +| mixed-page | text/template (go1.26) | 22.41 μs | ±0% | 22,410 | 8.50 | +| conditional-heavy | Heddle (reference) | 15.02 μs | — | 15,020 | 1.00 | +| conditional-heavy | templ v0.3.1020 | 36.03 μs | ±1% | 36,030 | 2.40 | +| conditional-heavy | text/template (go1.26) | 95.92 μs | ±0% | 95,920 | 6.39 | +| composed-page | Heddle (reference) | 34.07 μs | — | 34,066 | 1.00 | +| composed-page | templ v0.3.1020 | 4.234 μs | ±3% | 4,234 | 0.12 | +| composed-page | text/template (go1.26) | 14.78 μs | ±1% | 14,780 | 0.43 | +| large-loop | Heddle (reference) | 492.1 μs | — | 492,100 | 1.00 | +| large-loop | templ v0.3.1020 | 759 μs | ±0% | 759,000 | 1.54 | +| large-loop | text/template (go1.26) | 1.203 ms | ±0% | 1,203,000 | 2.44 | +| encoded-loop | Heddle (reference) | 1.766 ms | — | 1,766,000 | 1.00 | +| encoded-loop | templ v0.3.1020 | 1.782 ms | ±1% | 1,782,000 | 1.01 | +| encoded-loop | html/template (go1.26) | 7.47 ms | ±0% | 7,470,000 | 4.23 | + +*Source: docs/benchmarks/2026-08-08 — fair fight evidence. The Heddle row is the .NET anchor measured in this same run on the same machine.* + +## Cold compile / parse — per ecosystem + +Per-ecosystem only, never cross-compared (Q1.3). Within the .NET table the rows are not +comparable with each other either: a `Parse*` row produces an interpretable tree and a +`Compile*` row produces executable code, which are different steps of a first use. + +### .NET + +| Workload | Engine | harness statistic | harness dispersion | +| --- | --- | ---: | ---: | +| composed-page | ParseScriban | 393.8 ns | ±18.77 ns (SD 11.17 ns) | +| composed-page | ParseDotLiquid | 824.0 ns | ±22.96 ns (SD 13.66 ns) | +| composed-page | ParseFluid | 83,061.3 ns | ±3,913.52 ns (SD 2,328.88 ns) | +| composed-page | ParseHeddle | 301,347.8 ns | ±31,046.30 ns (SD 18,475.16 ns) | +| composed-page | CompileHeddle | 527,285.2 ns | ±50,852.80 ns (SD 30,261.69 ns) | +| composed-page | CompileHandlebars | 726,066.2 ns | ±11,931.16 ns (SD 7,100.04 ns) | + +*Source: docs/benchmarks/2026-08-08.* + +### Rust + +| Workload | Engine | harness statistic | harness dispersion | +| --- | --- | ---: | ---: | +| all templates | Tera 2.0.0 (parse all templates) | 511.8 μs | [511.5 μs, 512.1 μs] 95% CI | + +*Source: docs/benchmarks/2026-08-08.* + +### JVM + +No cold-compile cells in this run. + +### JS + +| Workload | Engine | harness statistic | harness dispersion | +| --- | --- | ---: | ---: | +| composed-page | eta 4.6.0 | 11.44 μs | 11.36 μs … 11.7 μs | +| composed-page | handlebars 4.7.9 | 166.4 μs | 150.3 μs … 733.1 μs | +| conditional-heavy | eta 4.6.0 | 17.2 μs | 17.12 μs … 17.3 μs | +| conditional-heavy | handlebars 4.7.9 | 279.5 μs | 251.4 μs … 754.8 μs | +| encoded-loop | eta 4.6.0 | 4.423 ms | 4.221 ms … 5.468 ms | +| encoded-loop | handlebars 4.7.9 | 5.042 ms | 4.776 ms … 7.016 ms | +| fortunes-encoded | eta 4.6.0 | 5.982 μs | 5.957 μs … 6.056 μs | +| fortunes-encoded | handlebars 4.7.9 | 58.54 μs | 51.3 μs … 1.035 ms | +| fragment-heavy | eta 4.6.0 | 12 μs | 11.98 μs … 12.05 μs | +| fragment-heavy | handlebars 4.7.9 | 96 μs | 85.7 μs … 839.8 μs | +| large-loop | eta 4.6.0 | 257.5 μs | 225.6 μs … 2.057 ms | +| large-loop | handlebars 4.7.9 | 499.1 μs | 434.8 μs … 1.747 ms | +| mixed-page | eta 4.6.0 | 14.73 μs | 14.66 μs … 14.9 μs | +| mixed-page | handlebars 4.7.9 | 298.6 μs | 269.5 μs … 779.7 μs | +| trivial-substitution | eta 4.6.0 | 6.348 μs | 6.296 μs … 6.469 μs | +| trivial-substitution | handlebars 4.7.9 | 143.1 μs | 132.6 μs … 685.5 μs | + +*Source: docs/benchmarks/2026-08-08.* + +### Python + +| Workload | Engine | harness statistic | harness dispersion | +| --- | --- | ---: | ---: | +| composed-page | Jinja2 3.1.6 | 112.2 μs | SD 534.4 ns | +| composed-page | Mako 1.3.12 | 138 μs | SD 4.281 μs | +| conditional-heavy | Mako 1.3.12 | 551.3 μs | SD 18.03 μs | +| conditional-heavy | Jinja2 3.1.6 | 763 μs | SD 4.168 μs | +| encoded-loop | Mako 1.3.12 | 319.1 μs | SD 11.2 μs | +| encoded-loop | Jinja2 3.1.6 | 354 μs | SD 1.393 μs | +| fortunes-encoded | Mako 1.3.12 | 277.6 μs | SD 1.272 μs | +| fortunes-encoded | Jinja2 3.1.6 | 308.3 μs | SD 1.531 μs | +| fragment-heavy | Mako 1.3.12 | 211.9 μs | SD 704 ns | +| fragment-heavy | Jinja2 3.1.6 | 244 μs | SD 5.094 μs | +| large-loop | Mako 1.3.12 | 252 μs | SD 1.07 μs | +| large-loop | Jinja2 3.1.6 | 278.5 μs | SD 3.954 μs | +| mixed-page | Mako 1.3.12 | 927.8 μs | SD 3.414 μs | +| mixed-page | Jinja2 3.1.6 | 1.1 ms | SD 4.206 μs | +| trivial-substitution | Jinja2 3.1.6 | 440.8 μs | SD 1.593 μs | +| trivial-substitution | Mako 1.3.12 | 510.5 μs | SD 17.69 μs | + +*Source: docs/benchmarks/2026-08-08.* + +### Go + +| Workload | Engine | harness statistic | harness dispersion | +| --- | --- | ---: | ---: | +| all templates | html/template (go1.26) | 6.136 μs | ±1% | +| all templates | text/template (go1.26) | 38.69 μs | ±0% | + +*Source: docs/benchmarks/2026-08-08.* + +## Per-ecosystem sidebars — not cross-comparable + +Allocation, GC and memory figures are per-ecosystem measurements taken by different +tools with different definitions. No table or sentence juxtaposes them across +runtimes (Phase 7 D6(e), unchanged). + +### .NET — allocation (BenchmarkDotNet `[MemoryDiagnoser]`) + +| Workload | Engine | Track | Allocated | Alloc ratio | Gen0 / Gen1 / Gen2 | +| --- | --- | --- | ---: | ---: | ---: | +| composed-page | Heddle | controlled | 233392 B | 1.000 | 3.1128 / 3.1128 / 3.1128 | +| composed-page | Heddle (utf8 sink) ‡ | controlled | 184 B | 0.001 | 0.0095 / 0.0000 / 0.0000 | +| composed-page | Heddle (textwriter sink) ‡ | controlled | 128 B | 0.001 | 0.0076 / 0.0000 / 0.0000 | +| composed-page | Fluid.Core 2.31.0 | controlled | 237548 B | 1.018 | 11.1694 / 5.6152 / 3.6621 | +| composed-page | Scriban 7.2.5 | controlled | 1182107 B | 5.065 | 58.5938 / 26.3672 / 15.6250 | +| composed-page | DotLiquid 2.3.197 | controlled | 415490 B | 1.780 | 18.7988 / 9.5215 / 7.3242 | +| composed-page | Handlebars.Net 2.1.6 | controlled | 233056 B | 0.999 | 10.9863 / 5.3711 / 3.7842 | +| composed-page | Razor (ASP.NET Core MVC) | controlled | 245440 B | 1.052 | 8.6670 / 1.9531 / 0.7324 | +| composed-page | Heddle | idiomatic | 233414 B | 1.000 | 3.1738 / 3.1738 / 3.1738 | +| composed-page | Heddle (utf8 sink) ‡ | idiomatic | 184 B | 0.001 | 0.0095 / 0.0000 / 0.0000 | +| composed-page | Heddle (textwriter sink) ‡ | idiomatic | 128 B | 0.001 | 0.0076 / 0.0000 / 0.0000 | +| composed-page | Fluid.Core 2.31.0 | idiomatic | 237764 B | 1.019 | 11.1694 / 5.5542 / 3.6621 | +| composed-page | Scriban 7.2.5 | idiomatic | 1212660 B | 5.195 | 59.5703 / 21.4844 / 15.6250 | +| composed-page | DotLiquid 2.3.197 | idiomatic | 429755 B | 1.841 | 19.5313 / 9.7656 / 7.3242 | +| composed-page | Handlebars.Net 2.1.6 | idiomatic | 233305 B | 1.000 | 10.9863 / 5.2490 / 3.7842 | +| composed-page | Razor (ASP.NET Core MVC) | idiomatic | 245665 B | 1.052 | 8.6670 / 2.0752 / 0.7324 | +| trivial-substitution | Heddle | controlled | 1720 B | 1.00 | 0.1028 / 0.0000 / - | +| trivial-substitution | Heddle (utf8 sink) ‡ | controlled | 208 B | 0.12 | 0.0124 / 0.0000 / - | +| trivial-substitution | Heddle (textwriter sink) ‡ | controlled | 200 B | 0.12 | 0.0119 / 0.0000 / - | +| trivial-substitution | Fluid.Core 2.31.0 | controlled | 2344 B | 1.36 | 0.1392 / 0.0000 / - | +| trivial-substitution | Scriban 7.2.5 | controlled | 343936 B | 199.96 | 20.5078 / 1.7090 / - | +| trivial-substitution | DotLiquid 2.3.197 | controlled | 10384 B | 6.04 | 0.6199 / 0.0038 / - | +| trivial-substitution | Handlebars.Net 2.1.6 | controlled | 736 B | 0.43 | 0.0439 / 0.0000 / - | +| trivial-substitution | Razor (ASP.NET Core MVC) | controlled | 13360 B | 7.77 | 0.7935 / 0.2594 / - | +| trivial-substitution | Heddle | idiomatic | 1920 B | 1.00 | 0.1147 / 0.0000 / - | +| trivial-substitution | Heddle (utf8 sink) ‡ | idiomatic | 208 B | 0.11 | 0.0124 / 0.0000 / - | +| trivial-substitution | Heddle (textwriter sink) ‡ | idiomatic | 200 B | 0.10 | 0.0119 / 0.0000 / - | +| trivial-substitution | Fluid.Core 2.31.0 | idiomatic | 2424 B | 1.26 | 0.1440 / 0.0000 / - | +| trivial-substitution | Scriban 7.2.5 | idiomatic | 344024 B | 179.18 | 20.5078 / 1.8311 / - | +| trivial-substitution | DotLiquid 2.3.197 | idiomatic | 10464 B | 5.45 | 0.6218 / 0.0038 / - | +| trivial-substitution | Handlebars.Net 2.1.6 | idiomatic | 816 B | 0.42 | 0.0486 / 0.0000 / - | +| trivial-substitution | Razor (ASP.NET Core MVC) | idiomatic | 13200 B | 6.88 | 0.7858 / 0.2594 / - | +| large-loop | Heddle | controlled | 1172.35 KB | 1.00 | 53.7109 / 30.7617 / 30.7617 | +| large-loop | Heddle (utf8 sink) ‡ | controlled | 381.41 KB | 0.33 | 23.1934 / 0.0000 / 0.0000 | +| large-loop | Heddle (textwriter sink) ‡ | controlled | 381.41 KB | 0.33 | 23.1934 / 0.0000 / 0.0000 | +| large-loop | Fluid.Core 2.31.0 | controlled | 1668.61 KB | 1.42 | 93.7500 / 50.7813 / 15.6250 | +| large-loop | Scriban 7.2.5 | controlled | 2819.21 KB | 2.40 | 156.2500 / 80.0781 / 31.2500 | +| large-loop | DotLiquid 2.3.197 | controlled | 17257.6 KB | 14.72 | 1042.9688 / 449.2188 / 11.7188 | +| large-loop | Handlebars.Net 2.1.6 | controlled | 1033.68 KB | 0.88 | 55.6641 / 30.2734 / 15.6250 | +| large-loop | Razor (ASP.NET Core MVC) | controlled | 1363.37 KB | 1.16 | 58.5938 / 56.6406 / 0.0000 | +| large-loop | Heddle | idiomatic | 1295.42 KB | 1.00 | 57.6172 / 35.1563 / 35.1563 | +| large-loop | Heddle (utf8 sink) ‡ | idiomatic | 381.41 KB | 0.29 | 23.1934 / 0.0000 / 0.0000 | +| large-loop | Heddle (textwriter sink) ‡ | idiomatic | 381.41 KB | 0.29 | 23.1934 / 0.0000 / 0.0000 | +| large-loop | Fluid.Core 2.31.0 | idiomatic | 1790.02 KB | 1.38 | 99.6094 / 54.6875 / 17.5781 | +| large-loop | Scriban 7.2.5 | idiomatic | 2920.92 KB | 2.25 | 156.2500 / 78.1250 / 31.2500 | +| large-loop | DotLiquid 2.3.197 | idiomatic | 17363.3 KB | 13.40 | 1050.7813 / 453.1250 / 15.6250 | +| large-loop | Handlebars.Net 2.1.6 | idiomatic | 1104.14 KB | 0.85 | 58.5938 / 32.2266 / 16.6016 | +| large-loop | Razor (ASP.NET Core MVC) | idiomatic | 1351.8 KB | 1.04 | 54.6875 / 41.0156 / 0.0000 | +| mixed-page | Heddle | controlled | 43.96 KB | 1.00 | 2.6855 / 0.1755 / - | +| mixed-page | Heddle (utf8 sink) ‡ | controlled | 3.92 KB | 0.09 | 0.2365 / 0.0000 / - | +| mixed-page | Heddle (textwriter sink) ‡ | controlled | 3.91 KB | 0.09 | 0.2365 / 0.0000 / - | +| mixed-page | Fluid.Core 2.31.0 | controlled | 28.99 KB | 0.66 | 1.7700 / 0.0000 / - | +| mixed-page | Scriban 7.2.5 | controlled | 453.25 KB | 10.31 | 27.3438 / 2.4414 / - | +| mixed-page | DotLiquid 2.3.197 | controlled | 283.67 KB | 6.45 | 17.3340 / 1.3428 / - | +| mixed-page | Handlebars.Net 2.1.6 | controlled | 43.83 KB | 1.00 | 2.6779 / 0.2060 / - | +| mixed-page | Razor (ASP.NET Core MVC) | controlled | 62.54 KB | 1.42 | 3.7842 / 1.2207 / - | +| mixed-page | Heddle | idiomatic | 62.3 KB | 1.00 | 3.8033 / 0.3777 / - | +| mixed-page | Heddle (utf8 sink) ‡ | idiomatic | 3.92 KB | 0.06 | 0.2365 / 0.0000 / - | +| mixed-page | Heddle (textwriter sink) ‡ | idiomatic | 3.91 KB | 0.06 | 0.2365 / 0.0000 / - | +| mixed-page | Fluid.Core 2.31.0 | idiomatic | 35.49 KB | 0.57 | 2.1667 / 0.0000 / - | +| mixed-page | Scriban 7.2.5 | idiomatic | 481.21 KB | 7.72 | 29.2969 / 0.9766 / - | +| mixed-page | DotLiquid 2.3.197 | idiomatic | 306.88 KB | 4.93 | 18.7378 / 2.1973 / - | +| mixed-page | Handlebars.Net 2.1.6 | idiomatic | 66.41 KB | 1.07 | 4.0588 / 0.4425 / - | +| mixed-page | Razor (ASP.NET Core MVC) | idiomatic | 85.91 KB | 1.38 | 5.2490 / 1.3123 / - | +| conditional-heavy | Heddle | controlled | 98.43 KB | 1.00 | 6.0120 / 0.6561 / - | +| conditional-heavy | Heddle (utf8 sink) ‡ | controlled | 34.55 KB | 0.35 | 2.1057 / 0.0000 / - | +| conditional-heavy | Heddle (textwriter sink) ‡ | controlled | 34.55 KB | 0.35 | 2.1057 / 0.0000 / - | +| conditional-heavy | Fluid.Core 2.31.0 | controlled | 54.94 KB | 0.56 | 3.2959 / 0.1221 / - | +| conditional-heavy | Scriban 7.2.5 | controlled | 301.81 KB | 3.07 | 18.4326 / 3.0518 / - | +| conditional-heavy | DotLiquid 2.3.197 | controlled | 1485.26 KB | 15.09 | 90.8203 / 0.0000 / - | +| conditional-heavy | Handlebars.Net 2.1.6 | controlled | 67.08 KB | 0.68 | 4.0894 / 0.3662 / - | +| conditional-heavy | Razor (ASP.NET Core MVC) | controlled | 93.04 KB | 0.95 | 5.6152 / 2.8076 / - | +| conditional-heavy | Heddle | idiomatic | 136.98 KB | 1.00 | 8.3618 / 1.3733 / - | +| conditional-heavy | Heddle (utf8 sink) ‡ | idiomatic | 34.55 KB | 0.25 | 2.1057 / 0.0000 / - | +| conditional-heavy | Heddle (textwriter sink) ‡ | idiomatic | 34.55 KB | 0.25 | 2.1057 / 0.0000 / - | +| conditional-heavy | Fluid.Core 2.31.0 | idiomatic | 76.83 KB | 0.56 | 4.6387 / 0.0000 / - | +| conditional-heavy | Scriban 7.2.5 | idiomatic | 341.52 KB | 2.49 | 20.7520 / 4.1504 / - | +| conditional-heavy | DotLiquid 2.3.197 | idiomatic | 1538.55 KB | 11.23 | 93.7500 / 17.5781 / - | +| conditional-heavy | Handlebars.Net 2.1.6 | idiomatic | 118.02 KB | 0.86 | 7.2021 / 0.9766 / - | +| conditional-heavy | Razor (ASP.NET Core MVC) | idiomatic | 146.8 KB | 1.07 | 8.9417 / 2.2278 / - | +| fragment-heavy | Heddle | controlled | 22.54 KB | 1.00 | 1.3771 / 0.0496 / - | +| fragment-heavy | Heddle (utf8 sink) ‡ | controlled | 3.05 KB | 0.14 | 0.1831 / 0.0000 / - | +| fragment-heavy | Heddle (textwriter sink) ‡ | controlled | 3.04 KB | 0.13 | 0.1831 / 0.0000 / - | +| fragment-heavy | Fluid.Core 2.31.0 | controlled | 34.37 KB | 1.52 | 2.0905 / 0.0153 / - | +| fragment-heavy | Scriban 7.2.5 | controlled | 190.42 KB | 8.45 | 11.2305 / 1.4648 / - | +| fragment-heavy | DotLiquid 2.3.197 | controlled | 937.89 KB | 41.61 | 57.3730 / 4.1504 / - | +| fragment-heavy | Handlebars.Net 2.1.6 | controlled | 476.2 KB | 21.13 | 29.1443 / 2.4719 / - | +| fragment-heavy | Razor (ASP.NET Core MVC) | controlled | 135.57 KB | 6.02 | 8.0566 / 1.9531 / - | +| fragment-heavy | Heddle | idiomatic | 30.04 KB | 1.00 | 1.8349 / 0.0839 / - | +| fragment-heavy | Heddle (utf8 sink) ‡ | idiomatic | 3.05 KB | 0.10 | 0.1831 / 0.0000 / - | +| fragment-heavy | Heddle (textwriter sink) ‡ | idiomatic | 3.04 KB | 0.10 | 0.1831 / 0.0000 / - | +| fragment-heavy | Fluid.Core 2.31.0 | idiomatic | 36.82 KB | 1.23 | 2.2430 / 0.0153 / - | +| fragment-heavy | Scriban 7.2.5 | idiomatic | 201.28 KB | 6.70 | 12.2070 / 1.9531 / - | +| fragment-heavy | DotLiquid 2.3.197 | idiomatic | 1503.44 KB | 50.05 | 91.7969 / 7.3242 / - | +| fragment-heavy | Handlebars.Net 2.1.6 | idiomatic | 477.89 KB | 15.91 | 29.2358 / 2.5635 / - | +| fragment-heavy | Razor (ASP.NET Core MVC) | idiomatic | 135.15 KB | 4.50 | 8.2397 / 2.0752 / - | +| fortunes-encoded | Heddle | controlled | 6.95 KB | 1.00 | 0.4253 / 0.0038 / - | +| fortunes-encoded | Heddle (utf8 sink) ‡ | controlled | 2.25 KB | 0.32 | 0.1373 / 0.0000 / - | +| fortunes-encoded | Heddle (textwriter sink) ‡ | controlled | 2.24 KB | 0.32 | 0.1364 / 0.0000 / - | +| fortunes-encoded | Fluid.Core 2.31.0 | controlled | 5.61 KB | 0.81 | 0.3433 / 0.0000 / - | +| fortunes-encoded | Scriban 7.2.5 | controlled | 77.42 KB | 11.13 | 4.7302 / 0.5188 / - | +| fortunes-encoded | DotLiquid 2.3.197 | controlled | 73.22 KB | 10.53 | 4.4556 / 0.2747 / - | +| fortunes-encoded | Handlebars.Net 2.1.6 | controlled | 2.22 KB | 0.32 | 0.1354 / 0.0000 / - | +| fortunes-encoded | Razor (ASP.NET Core MVC) | controlled | 21.87 KB | 3.15 | 1.3275 / 0.6561 / - | +| fortunes-encoded | Heddle | idiomatic | 8.18 KB | 1.00 | 0.5007 / 0.0057 / - | +| fortunes-encoded | Heddle (utf8 sink) ‡ | idiomatic | 2.25 KB | 0.28 | 0.1373 / 0.0000 / - | +| fortunes-encoded | Heddle (textwriter sink) ‡ | idiomatic | 2.24 KB | 0.27 | 0.1364 / 0.0000 / - | +| fortunes-encoded | Fluid.Core 2.31.0 | idiomatic | 6 KB | 0.73 | 0.3662 / 0.0000 / - | +| fortunes-encoded | Scriban 7.2.5 | idiomatic | 78.61 KB | 9.61 | 4.7607 / 0.3662 / - | +| fortunes-encoded | DotLiquid 2.3.197 | idiomatic | 74.37 KB | 9.09 | 4.5471 / 0.2136 / - | +| fortunes-encoded | Handlebars.Net 2.1.6 | idiomatic | 2.46 KB | 0.30 | 0.1488 / 0.0000 / - | +| fortunes-encoded | Razor (ASP.NET Core MVC) | idiomatic | 22.26 KB | 2.72 | 1.3580 / 0.6714 / - | +| encoded-loop | Heddle | controlled | 5.79 MB | 1.00 | 275.3906 / 109.3750 / 109.3750 | +| encoded-loop | Heddle (utf8 sink) ‡ | controlled | 2.66 MB | 0.46 | 166.0156 / 0.0000 / 0.0000 | +| encoded-loop | Heddle (textwriter sink) ‡ | controlled | 2.66 MB | 0.46 | 166.0156 / 0.0000 / 0.0000 | +| encoded-loop | Fluid.Core 2.31.0 | controlled | 5.86 MB | 1.01 | 324.2188 / 214.8438 / 50.7813 | +| encoded-loop | Scriban 7.2.5 | controlled | 12.15 MB | 2.10 | 671.8750 / 445.3125 / 101.5625 | +| encoded-loop | DotLiquid 2.3.197 | controlled | 29.99 MB | 5.18 | 1828.1250 / 828.1250 / 46.8750 | +| encoded-loop | Handlebars.Net 2.1.6 | controlled | 3.11 MB | 0.54 | 152.3438 / 111.3281 / 52.7344 | +| encoded-loop | Razor (ASP.NET Core MVC) | controlled | 4.91 MB | 0.85 | 210.9375 / 207.0313 / 0.0000 | +| encoded-loop | Heddle | idiomatic | 6.38 MB | 1.00 | 289.0625 / 123.0469 / 123.0469 | +| encoded-loop | Heddle (utf8 sink) ‡ | idiomatic | 2.66 MB | 0.42 | 166.0156 / 0.0000 / 0.0000 | +| encoded-loop | Heddle (textwriter sink) ‡ | idiomatic | 2.66 MB | 0.42 | 166.0156 / 0.0000 / 0.0000 | +| encoded-loop | Fluid.Core 2.31.0 | idiomatic | 6.47 MB | 1.01 | 351.5625 / 242.1875 / 62.5000 | +| encoded-loop | Scriban 7.2.5 | idiomatic | 12.97 MB | 2.03 | 710.9375 / 398.4375 / 125.0000 | +| encoded-loop | DotLiquid 2.3.197 | idiomatic | 30.61 MB | 4.80 | 1843.7500 / 921.8750 / 46.8750 | +| encoded-loop | Handlebars.Net 2.1.6 | idiomatic | 3.64 MB | 0.57 | 179.6875 / 128.9063 / 62.5000 | +| encoded-loop | Razor (ASP.NET Core MVC) | idiomatic | 5.82 MB | 0.91 | 238.2813 / 234.3750 / 0.0000 | + +‡ **The two streaming-sink rows measure a different quantity from every other row, and their `Allocated` figures must not be compared with the materialising rows'.** A materialising row's `Allocated` includes the rendered output; the sink rows stream into a caller-owned buffer that is allocated once in untimed setup, pre-sized past the output's high-water mark, and reused across iterations. Their `Allocated` is therefore the engine's per-render bookkeeping — the steady-state GC pressure a pooled streaming consumer (a `PipeWriter`-shaped caller) sees — and NOT the cost of owning the output: the buffer's working set, on the order of the rendered output itself, is real memory the caller holds for the render's duration and simply is not a per-render allocation. Read an `Alloc ratio` of 0.001 as "streaming retires the per-render allocation", never as "the render fits in a few hundred bytes". + +#### .NET — Heddle-internal suites (not competitor tables) + +| Suite | Method | Mean | Allocated | +| --- | --- | ---: | ---: | +| TechniqueRuntimeBenchmarks | Utf8 (composed-page) | 1,872.6 ns | 184 B | +| TechniqueRuntimeBenchmarks | TextWriter (composed-page) | 1,336.0 ns | 128 B | +| TechniqueRuntimeBenchmarks | String (composed-page) | 23,666.9 ns | 233411 B | +| TechniqueRuntimeBenchmarks | Utf8 (conditional-heavy) | 18,405.1 ns | 35384 B | +| TechniqueRuntimeBenchmarks | TextWriter (conditional-heavy) | 14,301.4 ns | 35376 B | +| TechniqueRuntimeBenchmarks | String (conditional-heavy) | 14,777.3 ns | 100792 B | +| TechniqueRuntimeBenchmarks | Utf8 (encoded-loop) | 723,383.6 ns | 2792016 B | +| TechniqueRuntimeBenchmarks | TextWriter (encoded-loop) | 594,913.8 ns | 2792008 B | +| TechniqueRuntimeBenchmarks | String (encoded-loop) | 3,949,423.1 ns | 6075514 B | +| TechniqueRuntimeBenchmarks | Utf8 (fortunes-encoded) | 710.3 ns | 2304 B | +| TechniqueRuntimeBenchmarks | TextWriter (fortunes-encoded) | 629.6 ns | 2296 B | +| TechniqueRuntimeBenchmarks | String (fortunes-encoded) | 736.8 ns | 7120 B | +| TechniqueRuntimeBenchmarks | Utf8 (fragment-heavy) | 3,429.6 ns | 3120 B | +| TechniqueRuntimeBenchmarks | TextWriter (fragment-heavy) | 2,953.8 ns | 3112 B | +| TechniqueRuntimeBenchmarks | String (fragment-heavy) | 3,253.8 ns | 23080 B | +| TechniqueRuntimeBenchmarks | Utf8 (large-loop) | 156,968.2 ns | 390568 B | +| TechniqueRuntimeBenchmarks | TextWriter (large-loop) | 129,373.8 ns | 390560 B | +| TechniqueRuntimeBenchmarks | String (large-loop) | 1,144,406.6 ns | 1200421 B | +| TechniqueRuntimeBenchmarks | Utf8 (mixed-page) | 2,797.3 ns | 4016 B | +| TechniqueRuntimeBenchmarks | TextWriter (mixed-page) | 2,215.0 ns | 4008 B | +| TechniqueRuntimeBenchmarks | String (mixed-page) | 2,558.0 ns | 45016 B | +| TechniqueRuntimeBenchmarks | Utf8 (trivial-substitution) | 132.0 ns | 208 B | +| TechniqueRuntimeBenchmarks | TextWriter (trivial-substitution) | 108.5 ns | 200 B | +| TechniqueRuntimeBenchmarks | String (trivial-substitution) | 152.9 ns | 1720 B | +| TechniquePrecompiledBenchmarks | Utf8 (conditional-heavy) | 24,572.1 ns | 35352 B | +| TechniquePrecompiledBenchmarks | TextWriter (conditional-heavy) | 17,830.6 ns | 35344 B | +| TechniquePrecompiledBenchmarks | String (conditional-heavy) | 18,328.5 ns | 131768 B | +| TechniquePrecompiledBenchmarks | Utf8 (fragment-heavy) | 4,463.1 ns | 3088 B | +| TechniquePrecompiledBenchmarks | TextWriter (fragment-heavy) | 2,968.3 ns | 3080 B | +| TechniquePrecompiledBenchmarks | String (fragment-heavy) | 3,603.0 ns | 40768 B | +| TechniquePrecompiledBenchmarks | Utf8 (large-loop) | 220,761.0 ns | 390536 B | +| TechniquePrecompiledBenchmarks | TextWriter (large-loop) | 157,615.4 ns | 390528 B | +| TechniquePrecompiledBenchmarks | String (large-loop) | 2,574,464.1 ns | 1579378 B | +| TechniquePrecompiledBenchmarks | Utf8 (mixed-page) | 4,376.7 ns | 3984 B | +| TechniquePrecompiledBenchmarks | TextWriter (mixed-page) | 2,600.4 ns | 3976 B | +| TechniquePrecompiledBenchmarks | String (mixed-page) | 3,336.8 ns | 70816 B | +| TechniquePrecompiledBenchmarks | Utf8 (trivial-substitution) | 201.9 ns | 176 B | +| TechniquePrecompiledBenchmarks | TextWriter (trivial-substitution) | 130.4 ns | 168 B | +| TechniquePrecompiledBenchmarks | String (trivial-substitution) | 189.9 ns | 2880 B | +| PropsBenchmarks | DefinitionNoProps | 77.95 ns | 416 B | +| PropsBenchmarks | AllConstantProps | 91.44 ns | 520 B | +| PropsBenchmarks | DynamicProps | 118.12 ns | 552 B | +| PropsBenchmarks | ParameterizedSlot | 218.24 ns | 992 B | +| BranchBenchmarks | ListNoBranches | 462,605.83 ns | 925548 B | +| BranchBenchmarks | ListIfPair | 274,382.76 ns | 1083840 B | +| BranchBenchmarks | ListIfElse | 262,863.86 ns | 1163840 B | +| BranchBenchmarks | FlagshipNeverPublishes | 51.62 ns | 304 B | +| LanguageServiceBenchmarks | CompileFlagOff | 483.3 μs | 186.61 KB | +| LanguageServiceBenchmarks | CompileFlagOn | 762.4 μs | 478.38 KB | + +### JVM — allocation (JMH `-prof gc`) + +| Workload | Engine | Track | gc.alloc.rate.norm | gc.count | +| --- | --- | --- | ---: | ---: | +| composed-page | JTE 3.2.4 | controlled | 356.58 KB | 339 | +| composed-page | JTE 3.2.4 | idiomatic | 356.68 KB | 338 | +| composed-page | Thymeleaf 3.1.5 | controlled | 347.09 KB | 255 | +| composed-page | Thymeleaf 3.1.5 | idiomatic | 346.51 KB | 254 | +| conditional-heavy | JTE 3.2.4 | controlled | 39.35 KB | 136 | +| conditional-heavy | JTE 3.2.4 | idiomatic | 163.54 KB | 205 | +| conditional-heavy | Thymeleaf 3.1.5 | controlled | 899.39 KB | 55 | +| conditional-heavy | Thymeleaf 3.1.5 | idiomatic | 953.57 KB | 59 | +| encoded-loop | JTE 3.2.4 | controlled | 9.93 MB | 142 | +| encoded-loop | JTE 3.2.4 | idiomatic | 5.68 MB | 127 | +| encoded-loop | Thymeleaf 3.1.5 | controlled | 22.13 MB | 75 | +| encoded-loop | Thymeleaf 3.1.5 | idiomatic | 22.84 MB | 74 | +| fortunes-encoded | JTE 3.2.4 | controlled | 27.05 KB | 246 | +| fortunes-encoded | JTE 3.2.4 | idiomatic | 27.55 KB | 275 | +| fortunes-encoded | Thymeleaf 3.1.5 | controlled | 27.73 KB | 75 | +| fortunes-encoded | Thymeleaf 3.1.5 | idiomatic | 31.93 KB | 98 | +| fragment-heavy | JTE 3.2.4 | controlled | 12.84 KB | 154 | +| fragment-heavy | JTE 3.2.4 | idiomatic | 14.30 KB | 160 | +| fragment-heavy | Thymeleaf 3.1.5 | controlled | 285.09 KB | 54 | +| fragment-heavy | Thymeleaf 3.1.5 | idiomatic | 283.64 KB | 57 | +| large-loop | JTE 3.2.4 | controlled | 692.61 KB | 141 | +| large-loop | JTE 3.2.4 | idiomatic | 1.31 MB | 194 | +| large-loop | Thymeleaf 3.1.5 | controlled | 13.79 MB | 60 | +| large-loop | Thymeleaf 3.1.5 | idiomatic | 13.01 MB | 59 | +| mixed-page | JTE 3.2.4 | controlled | 33.70 KB | 184 | +| mixed-page | JTE 3.2.4 | idiomatic | 38.45 KB | 198 | +| mixed-page | Thymeleaf 3.1.5 | controlled | 231.11 KB | 54 | +| mixed-page | Thymeleaf 3.1.5 | idiomatic | 260.27 KB | 62 | +| trivial-substitution | JTE 3.2.4 | controlled | 8.45 KB | 316 | +| trivial-substitution | JTE 3.2.4 | idiomatic | 8.50 KB | 311 | +| trivial-substitution | Thymeleaf 3.1.5 | controlled | 14.91 KB | 57 | +| trivial-substitution | Thymeleaf 3.1.5 | idiomatic | 14.33 KB | 61 | + +### Python — memory (`tracemalloc`) + +| Workload | Engine | Track | allocated (mean) | retained (mean) | reps | +| --- | --- | --- | ---: | ---: | ---: | +| composed-page | Jinja2 3.1.6 | controlled | 112.25 KB | 110.39 KB | 100 | +| conditional-heavy | Jinja2 3.1.6 | controlled | 32.58 KB | 16.91 KB | 100 | +| encoded-loop | Jinja2 3.1.6 | controlled | 3.71 MB | 1.45 MB | 100 | +| fortunes-encoded | Jinja2 3.1.6 | controlled | 8.83 KB | 3.94 KB | 100 | +| fragment-heavy | Jinja2 3.1.6 | controlled | 17.76 KB | 11.01 KB | 100 | +| large-loop | Jinja2 3.1.6 | controlled | 624.21 KB | 189.99 KB | 100 | +| mixed-page | Jinja2 3.1.6 | controlled | 17.91 KB | 11.20 KB | 100 | +| trivial-substitution | Jinja2 3.1.6 | controlled | 4.18 KB | 2.01 KB | 100 | +| composed-page | Jinja2 3.1.6 | idiomatic | 112.55 KB | 110.43 KB | 100 | +| conditional-heavy | Jinja2 3.1.6 | idiomatic | 39.99 KB | 22.54 KB | 100 | +| encoded-loop | Jinja2 3.1.6 | idiomatic | 3.73 MB | 1.47 MB | 100 | +| fortunes-encoded | Jinja2 3.1.6 | idiomatic | 8.90 KB | 4.01 KB | 100 | +| fragment-heavy | Jinja2 3.1.6 | idiomatic | 20.19 KB | 10.23 KB | 100 | +| large-loop | Jinja2 3.1.6 | idiomatic | 633.97 KB | 199.76 KB | 100 | +| mixed-page | Jinja2 3.1.6 | idiomatic | 18.73 KB | 12.00 KB | 100 | +| trivial-substitution | Jinja2 3.1.6 | idiomatic | 4.21 KB | 2.04 KB | 100 | +| composed-page | Mako 1.3.12 | controlled | 114.07 KB | 112.64 KB | 100 | +| conditional-heavy | Mako 1.3.12 | controlled | 45.63 KB | 18.35 KB | 100 | +| encoded-loop | Mako 1.3.12 | controlled | 3.96 MB | 1.46 MB | 100 | +| fortunes-encoded | Mako 1.3.12 | controlled | 9.99 KB | 5.38 KB | 100 | +| fragment-heavy | Mako 1.3.12 | controlled | 54.88 KB | 46.48 KB | 100 | +| large-loop | Mako 1.3.12 | controlled | 807.88 KB | 191.42 KB | 100 | +| mixed-page | Mako 1.3.12 | controlled | 22.46 KB | 12.91 KB | 100 | +| trivial-substitution | Mako 1.3.12 | controlled | 5.41 KB | 3.49 KB | 100 | +| composed-page | Mako 1.3.12 | idiomatic | 114.61 KB | 112.67 KB | 100 | +| conditional-heavy | Mako 1.3.12 | idiomatic | 46.67 KB | 19.39 KB | 100 | +| encoded-loop | Mako 1.3.12 | idiomatic | 3.97 MB | 1.47 MB | 100 | +| fortunes-encoded | Mako 1.3.12 | idiomatic | 10.04 KB | 5.42 KB | 100 | +| fragment-heavy | Mako 1.3.12 | idiomatic | 19.62 KB | 9.67 KB | 100 | +| large-loop | Mako 1.3.12 | idiomatic | 812.78 KB | 196.31 KB | 100 | +| mixed-page | Mako 1.3.12 | idiomatic | 24.51 KB | 14.93 KB | 100 | +| trivial-substitution | Mako 1.3.12 | idiomatic | 5.44 KB | 3.51 KB | 100 | + +### Go — allocation (`go test -benchmem` via benchstat) + +| Workload | Engine | Track | B/op | allocs/op | +| --- | --- | --- | ---: | ---: | +| composed-page | text/template (go1.26) | controlled | 61.62Ki | 187.0 | +| composed-page | templ v0.3.1020 | controlled | 57.31Ki | 23.00 | +| conditional-heavy | text/template (go1.26) | controlled | 20.88Ki | 305.0 | +| conditional-heavy | templ v0.3.1020 | controlled | 23.24Ki | 606.0 | +| encoded-loop | html/template (go1.26) | controlled | 3.913Mi | 124.9k | +| encoded-loop | templ v0.3.1020 | controlled | 2.537Mi | 50.01k | +| fortunes-encoded | html/template (go1.26) | controlled | 4.674Ki | 155.0 | +| fortunes-encoded | templ v0.3.1020 | controlled | 2.805Ki | 38.00 | +| fragment-heavy | text/template (go1.26) | controlled | 12.81Ki | 245.0 | +| fragment-heavy | templ v0.3.1020 | controlled | 12.64Ki | 413.0 | +| large-loop | text/template (go1.26) | controlled | 346.6Ki | 14.75k | +| large-loop | templ v0.3.1020 | controlled | 385.0Ki | 19.74k | +| mixed-page | text/template (go1.26) | controlled | 12.29Ki | 149.0 | +| mixed-page | templ v0.3.1020 | controlled | 17.05Ki | 314.0 | +| trivial-substitution | text/template (go1.26) | controlled | 640.0 | 4.000 | +| trivial-substitution | templ v0.3.1020 | controlled | 944.0 | 24.00 | +| composed-page | text/template (go1.26) | idiomatic | 61.63Ki | 187.0 | +| composed-page | templ v0.3.1020 | idiomatic | 57.31Ki | 23.00 | +| conditional-heavy | text/template (go1.26) | idiomatic | 26.13Ki | 305.0 | +| conditional-heavy | templ v0.3.1020 | idiomatic | 45.13Ki | 1.206k | +| encoded-loop | html/template (go1.26) | idiomatic | 3.983Mi | 124.9k | +| encoded-loop | templ v0.3.1020 | idiomatic | 3.148Mi | 65.01k | +| fortunes-encoded | html/template (go1.26) | idiomatic | 5.174Ki | 155.0 | +| fortunes-encoded | templ v0.3.1020 | idiomatic | 3.931Ki | 74.00 | +| fragment-heavy | text/template (go1.26) | idiomatic | 13.44Ki | 247.0 | +| fragment-heavy | templ v0.3.1020 | idiomatic | 12.64Ki | 413.0 | +| large-loop | text/template (go1.26) | idiomatic | 386.6Ki | 14.75k | +| large-loop | templ v0.3.1020 | idiomatic | 854.2Ki | 34.74k | +| mixed-page | text/template (go1.26) | idiomatic | 15.54Ki | 149.0 | +| mixed-page | templ v0.3.1020 | idiomatic | 19.94Ki | 373.0 | +| trivial-substitution | text/template (go1.26) | idiomatic | 672.0 | 4.000 | +| trivial-substitution | templ v0.3.1020 | idiomatic | 944.0 | 24.00 | + +### JS — no memory sidebar + +The JS phase shipped **time-only** (Phase 4 D3): no memory sidebar exists, so none is +published here even though mitata emits a heap estimate. + +### Rust — allocation report + +The counting-allocator report ships as the raw artifact +[rust/alloc-report.txt](rust/alloc-report.txt); this script does not parse it into +a table, so no Rust allocation figures appear here. + +## Plausibility register + +`implied B/ns` is the **rendered** output size divided by the wall time — the diagnostic +the D6 amendment requires on every cross-stack table. It is **not** a performance metric. +Its purpose is to expose cells where the harness cannot be producing the full output, +so a reader does not mistake a measurement artifact for engine speed. + +The numerator is the rendered size, not the golden `byteLength`. The golden oracle is +stored in its **normalized** form — `TwinContent.Normalize` collapses every inter-tag +whitespace run before export — so on `composed-page` it is 1.56x smaller than what the +engines actually emit (34,847 B stored against 54,401 chars rendered). Dividing by the +golden there understated every engine's throughput by that factor and would have let a +cell sit above the ceiling unflagged. The other seven workloads agree within 2.4%. + +### Cells above the 50 B/ns ceiling + +A cell above this ceiling claims more sustained store bandwidth than one core of this +machine has while also executing template logic. The threshold was set from the observed +distribution of an earlier run rather than from a model. That run — since withdrawn, and +its render figures invalid — had two cells at 105.4 and 91.7 B/ns and then nothing until +30.9 B/ns, which was a compiled Rust template whose output is mostly a memcpy of large +literal chunks: fast, but physically possible. The ceiling sits in that gap. The two high +cells were the V8 rope artifact, since fixed harness-side (amendment E4), and the threshold +is retained as a standing cross-check rather than as a finding about that run. + +In *this* run the highest implied throughput is **43.9 B/ns**, and the top five are 43.9, 43.2, 37.4, 35.6, 30.3 B/ns against the 50 B/ns ceiling. + +No cell exceeds the ceiling in this run. + +### JS — heap per render against output size (corroborating signal) + +mitata reports an estimated heap figure per render, published here as context only. + +**This column cannot decide materialisation, and is no longer read as if it could.** +The figure is a *net* heap delta measured across a batch of thousands of iterations, +so anything the collector reclaims inside that batch is invisible to it: a render +that allocates its full output and immediately drops it can report a near-zero +delta. That is why the same metric yields a ratio above 5 on `large-loop` (where +allocation outruns the collector within a batch) and near 0.01 on `composed-page` +(where it does not) in one and the same run. Earlier revisions of this register +treated a ratio below 0.1 as proof of a non-materialised output; on the artifacts of +the run that first exposed the defect that happened to agree with it, but it is not a +sound inference and it false-positives on cells that are now provably correct. + +**The authoritative control is harness-side, not report-side.** Every bench body +materialises through `%FlattenString` and each run asserts `MATERIALISATION-CHECK` +before writing artifacts, failing the step outright rather than annotating a table +(amendment E4). The +throughput ceiling above is the report-side cross-check on that gate. A low heap +ratio here is a prompt to look at those two, not a verdict of its own. + +| Workload | Engine | Track | rendered B | heap/render B | ratio | reading | +| --- | --- | --- | ---: | ---: | ---: | --- | +| composed-page | eta 4.6.0 | controlled | 54,401 | 257 | 0.00 | net delta ≈ 0 (garbage reclaimed within the batch) | +| composed-page | eta 4.6.0 | idiomatic | 54,401 | 257 | 0.00 | net delta ≈ 0 (garbage reclaimed within the batch) | +| composed-page | handlebars 4.7.9 | idiomatic | 54,401 | 261 | 0.00 | net delta ≈ 0 (garbage reclaimed within the batch) | +| composed-page | handlebars 4.7.9 | controlled | 54,401 | 263 | 0.00 | net delta ≈ 0 (garbage reclaimed within the batch) | +| mixed-page | eta 4.6.0 | idiomatic | 9,740 | 494 | 0.05 | net delta ≈ 0 (garbage reclaimed within the batch) | +| conditional-heavy | eta 4.6.0 | idiomatic | 15,549 | 2,608 | 0.17 | net delta below output size | +| conditional-heavy | eta 4.6.0 | controlled | 15,549 | 4,434 | 0.29 | net delta below output size | +| mixed-page | handlebars 4.7.9 | idiomatic | 9,740 | 5,635 | 0.58 | net delta below output size | +| mixed-page | handlebars 4.7.9 | controlled | 9,740 | 5,669 | 0.58 | net delta below output size | +| mixed-page | eta 4.6.0 | controlled | 9,740 | 6,655 | 0.68 | net delta below output size | +| fragment-heavy | eta 4.6.0 | idiomatic | 4,730 | 6,699 | 1.42 | net delta at or above output size | +| fragment-heavy | eta 4.6.0 | controlled | 4,730 | 7,556 | 1.60 | net delta at or above output size | +| fragment-heavy | handlebars 4.7.9 | controlled | 4,730 | 10,048 | 2.12 | net delta at or above output size | +| fragment-heavy | handlebars 4.7.9 | idiomatic | 4,730 | 10,057 | 2.13 | net delta at or above output size | +| trivial-substitution | eta 4.6.0 | controlled | 338 | 1,091 | 3.23 | net delta at or above output size | +| large-loop | eta 4.6.0 | controlled | 192,780 | 993,834 | 5.16 | net delta at or above output size | +| trivial-substitution | eta 4.6.0 | idiomatic | 338 | 1,789 | 5.29 | net delta at or above output size | +| fortunes-encoded | eta 4.6.0 | controlled | 1,157 | 6,655 | 5.75 | net delta at or above output size | +| fortunes-encoded | eta 4.6.0 | idiomatic | 1,157 | 6,740 | 5.83 | net delta at or above output size | +| large-loop | eta 4.6.0 | idiomatic | 192,780 | 1,568,890 | 8.14 | net delta at or above output size | +| encoded-loop | handlebars 4.7.9 | idiomatic | 851,685 | 7,217,455 | 8.47 | net delta at or above output size | +| encoded-loop | handlebars 4.7.9 | controlled | 851,685 | 7,217,674 | 8.47 | net delta at or above output size | +| encoded-loop | eta 4.6.0 | controlled | 851,685 | 7,645,592 | 8.98 | net delta at or above output size | +| encoded-loop | eta 4.6.0 | idiomatic | 851,685 | 7,675,595 | 9.01 | net delta at or above output size | +| fortunes-encoded | handlebars 4.7.9 | idiomatic | 1,157 | 11,437 | 9.89 | net delta at or above output size | +| fortunes-encoded | handlebars 4.7.9 | controlled | 1,157 | 11,469 | 9.91 | net delta at or above output size | +| large-loop | handlebars 4.7.9 | idiomatic | 192,780 | 2,118,795 | 10.99 | net delta at or above output size | +| large-loop | handlebars 4.7.9 | controlled | 192,780 | 2,118,946 | 10.99 | net delta at or above output size | +| trivial-substitution | handlebars 4.7.9 | idiomatic | 338 | 4,208 | 12.45 | net delta at or above output size | +| trivial-substitution | handlebars 4.7.9 | controlled | 338 | 4,241 | 12.55 | net delta at or above output size | +| conditional-heavy | handlebars 4.7.9 | idiomatic | 15,549 | 683,783 | 43.98 | net delta at or above output size | +| conditional-heavy | handlebars 4.7.9 | controlled | 15,549 | 683,854 | 43.98 | net delta at or above output size | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.BranchBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.BranchBenchmarks-report-github.md new file mode 100644 index 00000000..66fc0b95 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.BranchBenchmarks-report-github.md @@ -0,0 +1,18 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | +|----------------------- |--------------:|--------------:|--------------:|------:|--------:|--------:|--------:|--------:|----------:|------------:| +| ListNoBranches | 462,605.83 ns | 1,180.952 ns | 702.766 ns | 1.000 | 0.00 | 71.2891 | 28.3203 | 28.3203 | 925548 B | 1.000 | +| ListIfPair | 274,382.76 ns | 26,593.574 ns | 15,825.409 ns | 0.593 | 0.03 | 64.4531 | 9.7656 | - | 1083840 B | 1.171 | +| ListIfElse | 262,863.86 ns | 1,979.206 ns | 1,177.794 ns | 0.568 | 0.00 | 69.3359 | 11.2305 | - | 1163840 B | 1.257 | +| FlagshipNeverPublishes | 51.62 ns | 5.037 ns | 2.997 ns | 0.000 | 0.00 | 0.0181 | - | - | 304 B | 0.000 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.BranchBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.BranchBenchmarks-report.csv new file mode 100644 index 00000000..4651fe13 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.BranchBenchmarks-report.csv @@ -0,0 +1,5 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Gen2,Allocated,Alloc Ratio +ListNoBranches,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,"462,605.83 ns","1,180.952 ns",702.766 ns,1.000,0.00,71.2891,28.3203,28.3203,925548 B,1.000 +ListIfPair,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,"274,382.76 ns","26,593.574 ns","15,825.409 ns",0.593,0.03,64.4531,9.7656,0.0000,1083840 B,1.171 +ListIfElse,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,"262,863.86 ns","1,979.206 ns","1,177.794 ns",0.568,0.00,69.3359,11.2305,0.0000,1163840 B,1.257 +FlagshipNeverPublishes,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,51.62 ns,5.037 ns,2.997 ns,0.000,0.00,0.0181,0.0000,0.0000,304 B,0.000 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.BranchBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.BranchBenchmarks-report.html new file mode 100644 index 00000000..5a69344c --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.BranchBenchmarks-report.html @@ -0,0 +1,35 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.BranchBenchmarks-20260808-030917 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + +
      Method Mean Error StdDev RatioRatioSDGen0Gen1Gen2AllocatedAlloc Ratio
      ListNoBranches462,605.83 ns1,180.952 ns702.766 ns1.0000.0071.289128.320328.3203925548 B1.000
      ListIfPair274,382.76 ns26,593.574 ns15,825.409 ns0.5930.0364.45319.7656-1083840 B1.171
      ListIfElse262,863.86 ns1,979.206 ns1,177.794 ns0.5680.0069.335911.2305-1163840 B1.257
      FlagshipNeverPublishes51.62 ns5.037 ns2.997 ns0.0000.000.0181--304 B0.000
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ColdCompileBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ColdCompileBenchmarks-report-github.md new file mode 100644 index 00000000..5c5a70cc --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ColdCompileBenchmarks-report-github.md @@ -0,0 +1,20 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio | +|------------------ |-------------:|-------------:|-------------:|------:|--------:|--------:|--------:|-----------:|------------:| +| ParseHeddle | 301,347.8 ns | 31,046.30 ns | 18,475.16 ns | 1.003 | 0.08 | 86.9141 | 43.4570 | 1420.83 KB | 1.000 | +| CompileHeddle | 527,285.2 ns | 50,852.80 ns | 30,261.69 ns | 1.755 | 0.14 | 50.7813 | 48.8281 | 834.97 KB | 0.588 | +| ParseFluid | 83,061.3 ns | 3,913.52 ns | 2,328.88 ns | 0.277 | 0.02 | 23.5596 | 5.8594 | 386.79 KB | 0.272 | +| ParseScriban | 393.8 ns | 18.77 ns | 11.17 ns | 0.001 | 0.00 | 0.1607 | 0.0010 | 2.63 KB | 0.002 | +| ParseDotLiquid | 824.0 ns | 22.96 ns | 13.66 ns | 0.003 | 0.00 | 0.2041 | - | 3.34 KB | 0.002 | +| CompileHandlebars | 726,066.2 ns | 11,931.16 ns | 7,100.04 ns | 2.417 | 0.13 | 2.9297 | 1.9531 | 48.92 KB | 0.034 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ColdCompileBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ColdCompileBenchmarks-report.csv new file mode 100644 index 00000000..b9ca63de --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ColdCompileBenchmarks-report.csv @@ -0,0 +1,7 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Allocated,Alloc Ratio +ParseHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,"301,347.8 ns","31,046.30 ns","18,475.16 ns",1.003,0.08,86.9141,43.4570,1420.83 KB,1.000 +CompileHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,"527,285.2 ns","50,852.80 ns","30,261.69 ns",1.755,0.14,50.7813,48.8281,834.97 KB,0.588 +ParseFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,"83,061.3 ns","3,913.52 ns","2,328.88 ns",0.277,0.02,23.5596,5.8594,386.79 KB,0.272 +ParseScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,393.8 ns,18.77 ns,11.17 ns,0.001,0.00,0.1607,0.0010,2.63 KB,0.002 +ParseDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,824.0 ns,22.96 ns,13.66 ns,0.003,0.00,0.2041,0.0000,3.34 KB,0.002 +CompileHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,"726,066.2 ns","11,931.16 ns","7,100.04 ns",2.417,0.13,2.9297,1.9531,48.92 KB,0.034 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ColdCompileBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ColdCompileBenchmarks-report.html new file mode 100644 index 00000000..5618b341 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ColdCompileBenchmarks-report.html @@ -0,0 +1,37 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.ColdCompileBenchmarks-20260808-030521 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + +
      Method Mean Error StdDevRatioRatioSDGen0Gen1AllocatedAlloc Ratio
      ParseHeddle301,347.8 ns31,046.30 ns18,475.16 ns1.0030.0886.914143.45701420.83 KB1.000
      CompileHeddle527,285.2 ns50,852.80 ns30,261.69 ns1.7550.1450.781348.8281834.97 KB0.588
      ParseFluid83,061.3 ns3,913.52 ns2,328.88 ns0.2770.0223.55965.8594386.79 KB0.272
      ParseScriban393.8 ns18.77 ns11.17 ns0.0010.000.16070.00102.63 KB0.002
      ParseDotLiquid824.0 ns22.96 ns13.66 ns0.0030.000.2041-3.34 KB0.002
      CompileHandlebars726,066.2 ns11,931.16 ns7,100.04 ns2.4170.132.92971.953148.92 KB0.034
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ComposedPageBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ComposedPageBenchmarks-report-github.md new file mode 100644 index 00000000..df2a764c --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ComposedPageBenchmarks-report-github.md @@ -0,0 +1,31 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Track | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | +|----------------------- |----------- |-----------:|-----------:|-----------:|------:|--------:|--------:|--------:|--------:|----------:|------------:| +| **RenderHeddle** | **controlled** | **34.066 μs** | **5.3035 μs** | **3.1560 μs** | **1.01** | **0.13** | **3.1128** | **3.1128** | **3.1128** | **233392 B** | **1.000** | +| RenderHeddleUtf8 | controlled | 1.798 μs | 0.2713 μs | 0.1614 μs | 0.05 | 0.01 | 0.0095 | - | - | 184 B | 0.001 | +| RenderHeddleTextWriter | controlled | 1.238 μs | 0.0085 μs | 0.0051 μs | 0.04 | 0.00 | 0.0076 | - | - | 128 B | 0.001 | +| RenderFluid | controlled | 60.234 μs | 3.6891 μs | 2.1953 μs | 1.78 | 0.18 | 11.1694 | 5.6152 | 3.6621 | 237548 B | 1.018 | +| RenderScriban | controlled | 419.333 μs | 30.5925 μs | 18.2051 μs | 12.41 | 1.29 | 58.5938 | 26.3672 | 15.6250 | 1182107 B | 5.065 | +| RenderDotLiquid | controlled | 153.755 μs | 13.3191 μs | 7.9260 μs | 4.55 | 0.49 | 18.7988 | 9.5215 | 7.3242 | 415490 B | 1.780 | +| RenderHandlebars | controlled | 62.869 μs | 3.8804 μs | 2.3092 μs | 1.86 | 0.19 | 10.9863 | 5.3711 | 3.7842 | 233056 B | 0.999 | +| RenderRazor | controlled | 64.815 μs | 10.3742 μs | 6.1735 μs | 1.92 | 0.25 | 8.6670 | 1.9531 | 0.7324 | 245440 B | 1.052 | +| | | | | | | | | | | | | +| **RenderHeddle** | **idiomatic** | **32.761 μs** | **4.1901 μs** | **2.4935 μs** | **1.01** | **0.10** | **3.1738** | **3.1738** | **3.1738** | **233414 B** | **1.000** | +| RenderHeddleUtf8 | idiomatic | 1.883 μs | 0.1831 μs | 0.1089 μs | 0.06 | 0.01 | 0.0095 | - | - | 184 B | 0.001 | +| RenderHeddleTextWriter | idiomatic | 1.260 μs | 0.0123 μs | 0.0073 μs | 0.04 | 0.00 | 0.0076 | - | - | 128 B | 0.001 | +| RenderFluid | idiomatic | 60.527 μs | 3.2964 μs | 1.9616 μs | 1.86 | 0.15 | 11.1694 | 5.5542 | 3.6621 | 237764 B | 1.019 | +| RenderScriban | idiomatic | 431.057 μs | 40.3621 μs | 24.0189 μs | 13.23 | 1.21 | 59.5703 | 21.4844 | 15.6250 | 1212660 B | 5.195 | +| RenderDotLiquid | idiomatic | 194.211 μs | 9.8814 μs | 5.8802 μs | 5.96 | 0.48 | 19.5313 | 9.7656 | 7.3242 | 429755 B | 1.841 | +| RenderHandlebars | idiomatic | 64.713 μs | 6.4197 μs | 3.8203 μs | 1.99 | 0.19 | 10.9863 | 5.2490 | 3.7842 | 233305 B | 1.000 | +| RenderRazor | idiomatic | 59.550 μs | 13.8188 μs | 8.2233 μs | 1.83 | 0.28 | 8.6670 | 2.0752 | 0.7324 | 245665 B | 1.052 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ComposedPageBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ComposedPageBenchmarks-report.csv new file mode 100644 index 00000000..838bd295 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ComposedPageBenchmarks-report.csv @@ -0,0 +1,17 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Track,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Gen2,Allocated,Alloc Ratio +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,34.066 μs,5.3035 μs,3.1560 μs,1.01,0.13,3.1128,3.1128,3.1128,233392 B,1.000 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,1.798 μs,0.2713 μs,0.1614 μs,0.05,0.01,0.0095,0.0000,0.0000,184 B,0.001 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,1.238 μs,0.0085 μs,0.0051 μs,0.04,0.00,0.0076,0.0000,0.0000,128 B,0.001 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,60.234 μs,3.6891 μs,2.1953 μs,1.78,0.18,11.1694,5.6152,3.6621,237548 B,1.018 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,419.333 μs,30.5925 μs,18.2051 μs,12.41,1.29,58.5938,26.3672,15.6250,1182107 B,5.065 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,153.755 μs,13.3191 μs,7.9260 μs,4.55,0.49,18.7988,9.5215,7.3242,415490 B,1.780 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,62.869 μs,3.8804 μs,2.3092 μs,1.86,0.19,10.9863,5.3711,3.7842,233056 B,0.999 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,64.815 μs,10.3742 μs,6.1735 μs,1.92,0.25,8.6670,1.9531,0.7324,245440 B,1.052 +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,32.761 μs,4.1901 μs,2.4935 μs,1.01,0.10,3.1738,3.1738,3.1738,233414 B,1.000 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,1.883 μs,0.1831 μs,0.1089 μs,0.06,0.01,0.0095,0.0000,0.0000,184 B,0.001 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,1.260 μs,0.0123 μs,0.0073 μs,0.04,0.00,0.0076,0.0000,0.0000,128 B,0.001 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,60.527 μs,3.2964 μs,1.9616 μs,1.86,0.15,11.1694,5.5542,3.6621,237764 B,1.019 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,431.057 μs,40.3621 μs,24.0189 μs,13.23,1.21,59.5703,21.4844,15.6250,1212660 B,5.195 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,194.211 μs,9.8814 μs,5.8802 μs,5.96,0.48,19.5313,9.7656,7.3242,429755 B,1.841 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,64.713 μs,6.4197 μs,3.8203 μs,1.99,0.19,10.9863,5.2490,3.7842,233305 B,1.000 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,59.550 μs,13.8188 μs,8.2233 μs,1.83,0.28,8.6670,2.0752,0.7324,245665 B,1.052 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ComposedPageBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ComposedPageBenchmarks-report.html new file mode 100644 index 00000000..26701667 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ComposedPageBenchmarks-report.html @@ -0,0 +1,47 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.ComposedPageBenchmarks-20260808-013512 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + + + + + + + + + + + +
      Method TrackMeanErrorStdDevRatioRatioSDGen0Gen1Gen2AllocatedAlloc Ratio
      RenderHeddlecontrolled34.066 μs5.3035 μs3.1560 μs1.010.133.11283.11283.1128233392 B1.000
      RenderHeddleUtf8controlled1.798 μs0.2713 μs0.1614 μs0.050.010.0095--184 B0.001
      RenderHeddleTextWritercontrolled1.238 μs0.0085 μs0.0051 μs0.040.000.0076--128 B0.001
      RenderFluidcontrolled60.234 μs3.6891 μs2.1953 μs1.780.1811.16945.61523.6621237548 B1.018
      RenderScribancontrolled419.333 μs30.5925 μs18.2051 μs12.411.2958.593826.367215.62501182107 B5.065
      RenderDotLiquidcontrolled153.755 μs13.3191 μs7.9260 μs4.550.4918.79889.52157.3242415490 B1.780
      RenderHandlebarscontrolled62.869 μs3.8804 μs2.3092 μs1.860.1910.98635.37113.7842233056 B0.999
      RenderRazorcontrolled64.815 μs10.3742 μs6.1735 μs1.920.258.66701.95310.7324245440 B1.052
      RenderHeddleidiomatic32.761 μs4.1901 μs2.4935 μs1.010.103.17383.17383.1738233414 B1.000
      RenderHeddleUtf8idiomatic1.883 μs0.1831 μs0.1089 μs0.060.010.0095--184 B0.001
      RenderHeddleTextWriteridiomatic1.260 μs0.0123 μs0.0073 μs0.040.000.0076--128 B0.001
      RenderFluididiomatic60.527 μs3.2964 μs1.9616 μs1.860.1511.16945.55423.6621237764 B1.019
      RenderScribanidiomatic431.057 μs40.3621 μs24.0189 μs13.231.2159.570321.484415.62501212660 B5.195
      RenderDotLiquididiomatic194.211 μs9.8814 μs5.8802 μs5.960.4819.53139.76567.3242429755 B1.841
      RenderHandlebarsidiomatic64.713 μs6.4197 μs3.8203 μs1.990.1910.98635.24903.7842233305 B1.000
      RenderRazoridiomatic59.550 μs13.8188 μs8.2233 μs1.830.288.66702.07520.7324245665 B1.052
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ConditionalHeavyBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ConditionalHeavyBenchmarks-report-github.md new file mode 100644 index 00000000..32e61990 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ConditionalHeavyBenchmarks-report-github.md @@ -0,0 +1,31 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Track | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio | +|----------------------- |----------- |----------:|---------:|---------:|------:|--------:|--------:|--------:|-----------:|------------:| +| **RenderHeddle** | **controlled** | **15.02 μs** | **0.852 μs** | **0.507 μs** | **1.00** | **0.05** | **6.0120** | **0.6561** | **98.43 KB** | **1.00** | +| RenderHeddleUtf8 | controlled | 18.18 μs | 0.277 μs | 0.165 μs | 1.21 | 0.04 | 2.1057 | - | 34.55 KB | 0.35 | +| RenderHeddleTextWriter | controlled | 14.53 μs | 0.332 μs | 0.197 μs | 0.97 | 0.03 | 2.1057 | - | 34.55 KB | 0.35 | +| RenderFluid | controlled | 39.32 μs | 0.387 μs | 0.230 μs | 2.62 | 0.08 | 3.2959 | 0.1221 | 54.94 KB | 0.56 | +| RenderScriban | controlled | 105.60 μs | 2.632 μs | 1.566 μs | 7.04 | 0.24 | 18.4326 | 3.0518 | 301.81 KB | 3.07 | +| RenderDotLiquid | controlled | 343.11 μs | 5.678 μs | 3.379 μs | 22.86 | 0.76 | 90.8203 | - | 1485.26 KB | 15.09 | +| RenderHandlebars | controlled | 34.51 μs | 0.641 μs | 0.382 μs | 2.30 | 0.08 | 4.0894 | 0.3662 | 67.08 KB | 0.68 | +| RenderRazor | controlled | 37.65 μs | 0.257 μs | 0.153 μs | 2.51 | 0.08 | 5.6152 | 2.8076 | 93.04 KB | 0.95 | +| | | | | | | | | | | | +| **RenderHeddle** | **idiomatic** | **15.70 μs** | **0.395 μs** | **0.235 μs** | **1.00** | **0.02** | **8.3618** | **1.3733** | **136.98 KB** | **1.00** | +| RenderHeddleUtf8 | idiomatic | 18.87 μs | 0.466 μs | 0.277 μs | 1.20 | 0.02 | 2.1057 | - | 34.55 KB | 0.25 | +| RenderHeddleTextWriter | idiomatic | 14.86 μs | 0.205 μs | 0.122 μs | 0.95 | 0.02 | 2.1057 | - | 34.55 KB | 0.25 | +| RenderFluid | idiomatic | 40.62 μs | 0.369 μs | 0.219 μs | 2.59 | 0.04 | 4.6387 | - | 76.83 KB | 0.56 | +| RenderScriban | idiomatic | 112.02 μs | 4.699 μs | 2.796 μs | 7.13 | 0.20 | 20.7520 | 4.1504 | 341.52 KB | 2.49 | +| RenderDotLiquid | idiomatic | 354.09 μs | 7.533 μs | 4.483 μs | 22.55 | 0.42 | 93.7500 | 17.5781 | 1538.55 KB | 11.23 | +| RenderHandlebars | idiomatic | 37.04 μs | 0.174 μs | 0.103 μs | 2.36 | 0.03 | 7.2021 | 0.9766 | 118.02 KB | 0.86 | +| RenderRazor | idiomatic | 25.25 μs | 0.395 μs | 0.235 μs | 1.61 | 0.03 | 8.9417 | 2.2278 | 146.8 KB | 1.07 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ConditionalHeavyBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ConditionalHeavyBenchmarks-report.csv new file mode 100644 index 00000000..03efa40a --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ConditionalHeavyBenchmarks-report.csv @@ -0,0 +1,17 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Track,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Allocated,Alloc Ratio +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,15.02 μs,0.852 μs,0.507 μs,1.00,0.05,6.0120,0.6561,98.43 KB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,18.18 μs,0.277 μs,0.165 μs,1.21,0.04,2.1057,0.0000,34.55 KB,0.35 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,14.53 μs,0.332 μs,0.197 μs,0.97,0.03,2.1057,0.0000,34.55 KB,0.35 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,39.32 μs,0.387 μs,0.230 μs,2.62,0.08,3.2959,0.1221,54.94 KB,0.56 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,105.60 μs,2.632 μs,1.566 μs,7.04,0.24,18.4326,3.0518,301.81 KB,3.07 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,343.11 μs,5.678 μs,3.379 μs,22.86,0.76,90.8203,0.0000,1485.26 KB,15.09 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,34.51 μs,0.641 μs,0.382 μs,2.30,0.08,4.0894,0.3662,67.08 KB,0.68 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,37.65 μs,0.257 μs,0.153 μs,2.51,0.08,5.6152,2.8076,93.04 KB,0.95 +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,15.70 μs,0.395 μs,0.235 μs,1.00,0.02,8.3618,1.3733,136.98 KB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,18.87 μs,0.466 μs,0.277 μs,1.20,0.02,2.1057,0.0000,34.55 KB,0.25 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,14.86 μs,0.205 μs,0.122 μs,0.95,0.02,2.1057,0.0000,34.55 KB,0.25 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,40.62 μs,0.369 μs,0.219 μs,2.59,0.04,4.6387,0.0000,76.83 KB,0.56 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,112.02 μs,4.699 μs,2.796 μs,7.13,0.20,20.7520,4.1504,341.52 KB,2.49 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,354.09 μs,7.533 μs,4.483 μs,22.55,0.42,93.7500,17.5781,1538.55 KB,11.23 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,37.04 μs,0.174 μs,0.103 μs,2.36,0.03,7.2021,0.9766,118.02 KB,0.86 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,25.25 μs,0.395 μs,0.235 μs,1.61,0.03,8.9417,2.2278,146.8 KB,1.07 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ConditionalHeavyBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ConditionalHeavyBenchmarks-report.html new file mode 100644 index 00000000..aa53563d --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.ConditionalHeavyBenchmarks-report.html @@ -0,0 +1,47 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.ConditionalHeavyBenchmarks-20260808-021120 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + + + + + + + + + + + +
      Method TrackMeanErrorStdDevRatioRatioSDGen0Gen1AllocatedAlloc Ratio
      RenderHeddlecontrolled15.02 μs0.852 μs0.507 μs1.000.056.01200.656198.43 KB1.00
      RenderHeddleUtf8controlled18.18 μs0.277 μs0.165 μs1.210.042.1057-34.55 KB0.35
      RenderHeddleTextWritercontrolled14.53 μs0.332 μs0.197 μs0.970.032.1057-34.55 KB0.35
      RenderFluidcontrolled39.32 μs0.387 μs0.230 μs2.620.083.29590.122154.94 KB0.56
      RenderScribancontrolled105.60 μs2.632 μs1.566 μs7.040.2418.43263.0518301.81 KB3.07
      RenderDotLiquidcontrolled343.11 μs5.678 μs3.379 μs22.860.7690.8203-1485.26 KB15.09
      RenderHandlebarscontrolled34.51 μs0.641 μs0.382 μs2.300.084.08940.366267.08 KB0.68
      RenderRazorcontrolled37.65 μs0.257 μs0.153 μs2.510.085.61522.807693.04 KB0.95
      RenderHeddleidiomatic15.70 μs0.395 μs0.235 μs1.000.028.36181.3733136.98 KB1.00
      RenderHeddleUtf8idiomatic18.87 μs0.466 μs0.277 μs1.200.022.1057-34.55 KB0.25
      RenderHeddleTextWriteridiomatic14.86 μs0.205 μs0.122 μs0.950.022.1057-34.55 KB0.25
      RenderFluididiomatic40.62 μs0.369 μs0.219 μs2.590.044.6387-76.83 KB0.56
      RenderScribanidiomatic112.02 μs4.699 μs2.796 μs7.130.2020.75204.1504341.52 KB2.49
      RenderDotLiquididiomatic354.09 μs7.533 μs4.483 μs22.550.4293.750017.57811538.55 KB11.23
      RenderHandlebarsidiomatic37.04 μs0.174 μs0.103 μs2.360.037.20210.9766118.02 KB0.86
      RenderRazoridiomatic25.25 μs0.395 μs0.235 μs1.610.038.94172.2278146.8 KB1.07
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.EncodedLoopBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.EncodedLoopBenchmarks-report-github.md new file mode 100644 index 00000000..9ceb956d --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.EncodedLoopBenchmarks-report-github.md @@ -0,0 +1,31 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Track | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | +|----------------------- |----------- |-----------:|----------:|----------:|------:|--------:|----------:|---------:|---------:|----------:|------------:| +| **RenderHeddle** | **controlled** | **1,766.0 μs** | **29.51 μs** | **17.56 μs** | **1.00** | **0.01** | **275.3906** | **109.3750** | **109.3750** | **5.79 MB** | **1.00** | +| RenderHeddleUtf8 | controlled | 725.3 μs | 6.52 μs | 3.88 μs | 0.41 | 0.00 | 166.0156 | - | - | 2.66 MB | 0.46 | +| RenderHeddleTextWriter | controlled | 610.1 μs | 17.41 μs | 10.36 μs | 0.35 | 0.01 | 166.0156 | - | - | 2.66 MB | 0.46 | +| RenderFluid | controlled | 2,574.9 μs | 10.52 μs | 6.26 μs | 1.46 | 0.01 | 324.2188 | 214.8438 | 50.7813 | 5.86 MB | 1.01 | +| RenderScriban | controlled | 6,725.7 μs | 239.80 μs | 142.70 μs | 3.81 | 0.08 | 671.8750 | 445.3125 | 101.5625 | 12.15 MB | 2.10 | +| RenderDotLiquid | controlled | 7,823.7 μs | 374.27 μs | 222.72 μs | 4.43 | 0.13 | 1828.1250 | 828.1250 | 46.8750 | 29.99 MB | 5.18 | +| RenderHandlebars | controlled | 1,719.5 μs | 10.84 μs | 6.45 μs | 0.97 | 0.01 | 152.3438 | 111.3281 | 52.7344 | 3.11 MB | 0.54 | +| RenderRazor | controlled | 1,761.1 μs | 24.63 μs | 14.66 μs | 1.00 | 0.01 | 210.9375 | 207.0313 | - | 4.91 MB | 0.85 | +| | | | | | | | | | | | | +| **RenderHeddle** | **idiomatic** | **1,977.7 μs** | **47.15 μs** | **28.06 μs** | **1.00** | **0.02** | **289.0625** | **123.0469** | **123.0469** | **6.38 MB** | **1.00** | +| RenderHeddleUtf8 | idiomatic | 712.3 μs | 7.81 μs | 4.65 μs | 0.36 | 0.01 | 166.0156 | - | - | 2.66 MB | 0.42 | +| RenderHeddleTextWriter | idiomatic | 605.5 μs | 12.61 μs | 7.50 μs | 0.31 | 0.01 | 166.0156 | - | - | 2.66 MB | 0.42 | +| RenderFluid | idiomatic | 2,941.9 μs | 191.42 μs | 113.91 μs | 1.49 | 0.06 | 351.5625 | 242.1875 | 62.5000 | 6.47 MB | 1.01 | +| RenderScriban | idiomatic | 6,501.1 μs | 433.82 μs | 258.16 μs | 3.29 | 0.13 | 710.9375 | 398.4375 | 125.0000 | 12.97 MB | 2.03 | +| RenderDotLiquid | idiomatic | 7,900.6 μs | 157.76 μs | 93.88 μs | 4.00 | 0.07 | 1843.7500 | 921.8750 | 46.8750 | 30.61 MB | 4.80 | +| RenderHandlebars | idiomatic | 2,027.5 μs | 15.27 μs | 9.08 μs | 1.03 | 0.01 | 179.6875 | 128.9063 | 62.5000 | 3.64 MB | 0.57 | +| RenderRazor | idiomatic | 1,812.5 μs | 9.47 μs | 5.63 μs | 0.92 | 0.01 | 238.2813 | 234.3750 | - | 5.82 MB | 0.91 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.EncodedLoopBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.EncodedLoopBenchmarks-report.csv new file mode 100644 index 00000000..5408ab6b --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.EncodedLoopBenchmarks-report.csv @@ -0,0 +1,17 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Track,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Gen2,Allocated,Alloc Ratio +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"1,766.0 μs",29.51 μs,17.56 μs,1.00,0.01,275.3906,109.3750,109.3750,5.79 MB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,725.3 μs,6.52 μs,3.88 μs,0.41,0.00,166.0156,0.0000,0.0000,2.66 MB,0.46 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,610.1 μs,17.41 μs,10.36 μs,0.35,0.01,166.0156,0.0000,0.0000,2.66 MB,0.46 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"2,574.9 μs",10.52 μs,6.26 μs,1.46,0.01,324.2188,214.8438,50.7813,5.86 MB,1.01 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"6,725.7 μs",239.80 μs,142.70 μs,3.81,0.08,671.8750,445.3125,101.5625,12.15 MB,2.10 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"7,823.7 μs",374.27 μs,222.72 μs,4.43,0.13,1828.1250,828.1250,46.8750,29.99 MB,5.18 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"1,719.5 μs",10.84 μs,6.45 μs,0.97,0.01,152.3438,111.3281,52.7344,3.11 MB,0.54 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"1,761.1 μs",24.63 μs,14.66 μs,1.00,0.01,210.9375,207.0313,0.0000,4.91 MB,0.85 +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"1,977.7 μs",47.15 μs,28.06 μs,1.00,0.02,289.0625,123.0469,123.0469,6.38 MB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,712.3 μs,7.81 μs,4.65 μs,0.36,0.01,166.0156,0.0000,0.0000,2.66 MB,0.42 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,605.5 μs,12.61 μs,7.50 μs,0.31,0.01,166.0156,0.0000,0.0000,2.66 MB,0.42 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"2,941.9 μs",191.42 μs,113.91 μs,1.49,0.06,351.5625,242.1875,62.5000,6.47 MB,1.01 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"6,501.1 μs",433.82 μs,258.16 μs,3.29,0.13,710.9375,398.4375,125.0000,12.97 MB,2.03 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"7,900.6 μs",157.76 μs,93.88 μs,4.00,0.07,1843.7500,921.8750,46.8750,30.61 MB,4.80 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"2,027.5 μs",15.27 μs,9.08 μs,1.03,0.01,179.6875,128.9063,62.5000,3.64 MB,0.57 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"1,812.5 μs",9.47 μs,5.63 μs,0.92,0.01,238.2813,234.3750,0.0000,5.82 MB,0.91 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.EncodedLoopBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.EncodedLoopBenchmarks-report.html new file mode 100644 index 00000000..4846c63a --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.EncodedLoopBenchmarks-report.html @@ -0,0 +1,47 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.EncodedLoopBenchmarks-20260808-023932 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + + + + + + + + + + + +
      Method TrackMeanErrorStdDevRatioRatioSDGen0Gen1Gen2AllocatedAlloc Ratio
      RenderHeddlecontrolled1,766.0 μs29.51 μs17.56 μs1.000.01275.3906109.3750109.37505.79 MB1.00
      RenderHeddleUtf8controlled725.3 μs6.52 μs3.88 μs0.410.00166.0156--2.66 MB0.46
      RenderHeddleTextWritercontrolled610.1 μs17.41 μs10.36 μs0.350.01166.0156--2.66 MB0.46
      RenderFluidcontrolled2,574.9 μs10.52 μs6.26 μs1.460.01324.2188214.843850.78135.86 MB1.01
      RenderScribancontrolled6,725.7 μs239.80 μs142.70 μs3.810.08671.8750445.3125101.562512.15 MB2.10
      RenderDotLiquidcontrolled7,823.7 μs374.27 μs222.72 μs4.430.131828.1250828.125046.875029.99 MB5.18
      RenderHandlebarscontrolled1,719.5 μs10.84 μs6.45 μs0.970.01152.3438111.328152.73443.11 MB0.54
      RenderRazorcontrolled1,761.1 μs24.63 μs14.66 μs1.000.01210.9375207.0313-4.91 MB0.85
      RenderHeddleidiomatic1,977.7 μs47.15 μs28.06 μs1.000.02289.0625123.0469123.04696.38 MB1.00
      RenderHeddleUtf8idiomatic712.3 μs7.81 μs4.65 μs0.360.01166.0156--2.66 MB0.42
      RenderHeddleTextWriteridiomatic605.5 μs12.61 μs7.50 μs0.310.01166.0156--2.66 MB0.42
      RenderFluididiomatic2,941.9 μs191.42 μs113.91 μs1.490.06351.5625242.187562.50006.47 MB1.01
      RenderScribanidiomatic6,501.1 μs433.82 μs258.16 μs3.290.13710.9375398.4375125.000012.97 MB2.03
      RenderDotLiquididiomatic7,900.6 μs157.76 μs93.88 μs4.000.071843.7500921.875046.875030.61 MB4.80
      RenderHandlebarsidiomatic2,027.5 μs15.27 μs9.08 μs1.030.01179.6875128.906362.50003.64 MB0.57
      RenderRazoridiomatic1,812.5 μs9.47 μs5.63 μs0.920.01238.2813234.3750-5.82 MB0.91
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FortunesEncodedBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FortunesEncodedBenchmarks-report-github.md new file mode 100644 index 00000000..49662b1e --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FortunesEncodedBenchmarks-report-github.md @@ -0,0 +1,31 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Track | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio | +|----------------------- |----------- |------------:|------------:|------------:|------:|--------:|-------:|-------:|----------:|------------:| +| **RenderHeddle** | **controlled** | **739.1 ns** | **5.16 ns** | **3.07 ns** | **1.00** | **0.01** | **0.4253** | **0.0038** | **6.95 KB** | **1.00** | +| RenderHeddleUtf8 | controlled | 726.3 ns | 4.99 ns | 2.97 ns | 0.98 | 0.01 | 0.1373 | - | 2.25 KB | 0.32 | +| RenderHeddleTextWriter | controlled | 640.6 ns | 8.16 ns | 4.86 ns | 0.87 | 0.01 | 0.1364 | - | 2.24 KB | 0.32 | +| RenderFluid | controlled | 2,182.3 ns | 120.30 ns | 71.59 ns | 2.95 | 0.09 | 0.3433 | - | 5.61 KB | 0.81 | +| RenderScriban | controlled | 15,308.6 ns | 3,805.09 ns | 2,264.35 ns | 20.71 | 2.91 | 4.7302 | 0.5188 | 77.42 KB | 11.13 | +| RenderDotLiquid | controlled | 25,655.3 ns | 386.31 ns | 229.89 ns | 34.71 | 0.33 | 4.4556 | 0.2747 | 73.22 KB | 10.53 | +| RenderHandlebars | controlled | 1,660.4 ns | 194.35 ns | 115.66 ns | 2.25 | 0.15 | 0.1354 | - | 2.22 KB | 0.32 | +| RenderRazor | controlled | 8,279.2 ns | 154.23 ns | 91.78 ns | 11.20 | 0.13 | 1.3275 | 0.6561 | 21.87 KB | 3.15 | +| | | | | | | | | | | | +| **RenderHeddle** | **idiomatic** | **763.2 ns** | **7.03 ns** | **4.19 ns** | **1.00** | **0.01** | **0.5007** | **0.0057** | **8.18 KB** | **1.00** | +| RenderHeddleUtf8 | idiomatic | 734.9 ns | 22.65 ns | 13.48 ns | 0.96 | 0.02 | 0.1373 | - | 2.25 KB | 0.28 | +| RenderHeddleTextWriter | idiomatic | 648.3 ns | 27.29 ns | 16.24 ns | 0.85 | 0.02 | 0.1364 | - | 2.24 KB | 0.27 | +| RenderFluid | idiomatic | 2,189.8 ns | 69.50 ns | 41.36 ns | 2.87 | 0.05 | 0.3662 | - | 6 KB | 0.73 | +| RenderScriban | idiomatic | 16,562.8 ns | 485.71 ns | 289.04 ns | 21.70 | 0.38 | 4.7607 | 0.3662 | 78.61 KB | 9.61 | +| RenderDotLiquid | idiomatic | 25,677.9 ns | 571.67 ns | 340.19 ns | 33.65 | 0.46 | 4.5471 | 0.2136 | 74.37 KB | 9.09 | +| RenderHandlebars | idiomatic | 1,563.6 ns | 23.87 ns | 14.21 ns | 2.05 | 0.02 | 0.1488 | - | 2.46 KB | 0.30 | +| RenderRazor | idiomatic | 8,434.6 ns | 183.55 ns | 109.22 ns | 11.05 | 0.15 | 1.3580 | 0.6714 | 22.26 KB | 2.72 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FortunesEncodedBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FortunesEncodedBenchmarks-report.csv new file mode 100644 index 00000000..da79e386 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FortunesEncodedBenchmarks-report.csv @@ -0,0 +1,17 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Track,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Allocated,Alloc Ratio +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,739.1 ns,5.16 ns,3.07 ns,1.00,0.01,0.4253,0.0038,6.95 KB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,726.3 ns,4.99 ns,2.97 ns,0.98,0.01,0.1373,0.0000,2.25 KB,0.32 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,640.6 ns,8.16 ns,4.86 ns,0.87,0.01,0.1364,0.0000,2.24 KB,0.32 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"2,182.3 ns",120.30 ns,71.59 ns,2.95,0.09,0.3433,0.0000,5.61 KB,0.81 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"15,308.6 ns","3,805.09 ns","2,264.35 ns",20.71,2.91,4.7302,0.5188,77.42 KB,11.13 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"25,655.3 ns",386.31 ns,229.89 ns,34.71,0.33,4.4556,0.2747,73.22 KB,10.53 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"1,660.4 ns",194.35 ns,115.66 ns,2.25,0.15,0.1354,0.0000,2.22 KB,0.32 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"8,279.2 ns",154.23 ns,91.78 ns,11.20,0.13,1.3275,0.6561,21.87 KB,3.15 +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,763.2 ns,7.03 ns,4.19 ns,1.00,0.01,0.5007,0.0057,8.18 KB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,734.9 ns,22.65 ns,13.48 ns,0.96,0.02,0.1373,0.0000,2.25 KB,0.28 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,648.3 ns,27.29 ns,16.24 ns,0.85,0.02,0.1364,0.0000,2.24 KB,0.27 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"2,189.8 ns",69.50 ns,41.36 ns,2.87,0.05,0.3662,0.0000,6 KB,0.73 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"16,562.8 ns",485.71 ns,289.04 ns,21.70,0.38,4.7607,0.3662,78.61 KB,9.61 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"25,677.9 ns",571.67 ns,340.19 ns,33.65,0.46,4.5471,0.2136,74.37 KB,9.09 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"1,563.6 ns",23.87 ns,14.21 ns,2.05,0.02,0.1488,0.0000,2.46 KB,0.30 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"8,434.6 ns",183.55 ns,109.22 ns,11.05,0.15,1.3580,0.6714,22.26 KB,2.72 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FortunesEncodedBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FortunesEncodedBenchmarks-report.html new file mode 100644 index 00000000..e0cc6e13 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FortunesEncodedBenchmarks-report.html @@ -0,0 +1,47 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.FortunesEncodedBenchmarks-20260808-022921 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + + + + + + + + + + + +
      Method TrackMean ErrorStdDevRatioRatioSDGen0Gen1AllocatedAlloc Ratio
      RenderHeddlecontrolled739.1 ns5.16 ns3.07 ns1.000.010.42530.00386.95 KB1.00
      RenderHeddleUtf8controlled726.3 ns4.99 ns2.97 ns0.980.010.1373-2.25 KB0.32
      RenderHeddleTextWritercontrolled640.6 ns8.16 ns4.86 ns0.870.010.1364-2.24 KB0.32
      RenderFluidcontrolled2,182.3 ns120.30 ns71.59 ns2.950.090.3433-5.61 KB0.81
      RenderScribancontrolled15,308.6 ns3,805.09 ns2,264.35 ns20.712.914.73020.518877.42 KB11.13
      RenderDotLiquidcontrolled25,655.3 ns386.31 ns229.89 ns34.710.334.45560.274773.22 KB10.53
      RenderHandlebarscontrolled1,660.4 ns194.35 ns115.66 ns2.250.150.1354-2.22 KB0.32
      RenderRazorcontrolled8,279.2 ns154.23 ns91.78 ns11.200.131.32750.656121.87 KB3.15
      RenderHeddleidiomatic763.2 ns7.03 ns4.19 ns1.000.010.50070.00578.18 KB1.00
      RenderHeddleUtf8idiomatic734.9 ns22.65 ns13.48 ns0.960.020.1373-2.25 KB0.28
      RenderHeddleTextWriteridiomatic648.3 ns27.29 ns16.24 ns0.850.020.1364-2.24 KB0.27
      RenderFluididiomatic2,189.8 ns69.50 ns41.36 ns2.870.050.3662-6 KB0.73
      RenderScribanidiomatic16,562.8 ns485.71 ns289.04 ns21.700.384.76070.366278.61 KB9.61
      RenderDotLiquididiomatic25,677.9 ns571.67 ns340.19 ns33.650.464.54710.213674.37 KB9.09
      RenderHandlebarsidiomatic1,563.6 ns23.87 ns14.21 ns2.050.020.1488-2.46 KB0.30
      RenderRazoridiomatic8,434.6 ns183.55 ns109.22 ns11.050.151.35800.671422.26 KB2.72
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FragmentHeavyBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FragmentHeavyBenchmarks-report-github.md new file mode 100644 index 00000000..b78f94f2 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FragmentHeavyBenchmarks-report-github.md @@ -0,0 +1,31 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Track | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio | +|----------------------- |----------- |-----------:|----------:|----------:|------:|--------:|--------:|-------:|-----------:|------------:| +| **RenderHeddle** | **controlled** | **3.081 μs** | **0.1664 μs** | **0.0990 μs** | **1.00** | **0.04** | **1.3771** | **0.0496** | **22.54 KB** | **1.00** | +| RenderHeddleUtf8 | controlled | 3.460 μs | 0.2422 μs | 0.1441 μs | 1.12 | 0.06 | 0.1831 | - | 3.05 KB | 0.14 | +| RenderHeddleTextWriter | controlled | 2.817 μs | 0.1876 μs | 0.1117 μs | 0.92 | 0.04 | 0.1831 | - | 3.04 KB | 0.13 | +| RenderFluid | controlled | 11.220 μs | 0.4969 μs | 0.2957 μs | 3.64 | 0.14 | 2.0905 | 0.0153 | 34.37 KB | 1.52 | +| RenderScriban | controlled | 46.476 μs | 1.3660 μs | 0.8129 μs | 15.10 | 0.53 | 11.2305 | 1.4648 | 190.42 KB | 8.45 | +| RenderDotLiquid | controlled | 170.223 μs | 1.3890 μs | 0.8266 μs | 55.30 | 1.71 | 57.3730 | 4.1504 | 937.89 KB | 41.61 | +| RenderHandlebars | controlled | 20.692 μs | 0.3136 μs | 0.1866 μs | 6.72 | 0.21 | 29.1443 | 2.4719 | 476.2 KB | 21.13 | +| RenderRazor | controlled | 44.056 μs | 1.4609 μs | 0.8694 μs | 14.31 | 0.51 | 8.0566 | 1.9531 | 135.57 KB | 6.02 | +| | | | | | | | | | | | +| **RenderHeddle** | **idiomatic** | **3.285 μs** | **0.4394 μs** | **0.2615 μs** | **1.01** | **0.10** | **1.8349** | **0.0839** | **30.04 KB** | **1.00** | +| RenderHeddleUtf8 | idiomatic | 3.515 μs | 0.2909 μs | 0.1731 μs | 1.08 | 0.09 | 0.1831 | - | 3.05 KB | 0.10 | +| RenderHeddleTextWriter | idiomatic | 2.899 μs | 0.3339 μs | 0.1987 μs | 0.89 | 0.09 | 0.1831 | - | 3.04 KB | 0.10 | +| RenderFluid | idiomatic | 11.798 μs | 0.2033 μs | 0.1210 μs | 3.61 | 0.26 | 2.2430 | 0.0153 | 36.82 KB | 1.23 | +| RenderScriban | idiomatic | 52.684 μs | 1.5357 μs | 0.9139 μs | 16.12 | 1.19 | 12.2070 | 1.9531 | 201.28 KB | 6.70 | +| RenderDotLiquid | idiomatic | 278.300 μs | 5.1166 μs | 3.0448 μs | 85.17 | 6.18 | 91.7969 | 7.3242 | 1503.44 KB | 50.05 | +| RenderHandlebars | idiomatic | 21.373 μs | 0.8808 μs | 0.5241 μs | 6.54 | 0.49 | 29.2358 | 2.5635 | 477.89 KB | 15.91 | +| RenderRazor | idiomatic | 36.889 μs | 0.4233 μs | 0.2519 μs | 11.29 | 0.81 | 8.2397 | 2.0752 | 135.15 KB | 4.50 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FragmentHeavyBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FragmentHeavyBenchmarks-report.csv new file mode 100644 index 00000000..ce284be2 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FragmentHeavyBenchmarks-report.csv @@ -0,0 +1,17 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Track,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Allocated,Alloc Ratio +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,3.081 μs,0.1664 μs,0.0990 μs,1.00,0.04,1.3771,0.0496,22.54 KB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,3.460 μs,0.2422 μs,0.1441 μs,1.12,0.06,0.1831,0.0000,3.05 KB,0.14 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,2.817 μs,0.1876 μs,0.1117 μs,0.92,0.04,0.1831,0.0000,3.04 KB,0.13 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,11.220 μs,0.4969 μs,0.2957 μs,3.64,0.14,2.0905,0.0153,34.37 KB,1.52 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,46.476 μs,1.3660 μs,0.8129 μs,15.10,0.53,11.2305,1.4648,190.42 KB,8.45 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,170.223 μs,1.3890 μs,0.8266 μs,55.30,1.71,57.3730,4.1504,937.89 KB,41.61 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,20.692 μs,0.3136 μs,0.1866 μs,6.72,0.21,29.1443,2.4719,476.2 KB,21.13 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,44.056 μs,1.4609 μs,0.8694 μs,14.31,0.51,8.0566,1.9531,135.57 KB,6.02 +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,3.285 μs,0.4394 μs,0.2615 μs,1.01,0.10,1.8349,0.0839,30.04 KB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,3.515 μs,0.2909 μs,0.1731 μs,1.08,0.09,0.1831,0.0000,3.05 KB,0.10 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,2.899 μs,0.3339 μs,0.1987 μs,0.89,0.09,0.1831,0.0000,3.04 KB,0.10 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,11.798 μs,0.2033 μs,0.1210 μs,3.61,0.26,2.2430,0.0153,36.82 KB,1.23 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,52.684 μs,1.5357 μs,0.9139 μs,16.12,1.19,12.2070,1.9531,201.28 KB,6.70 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,278.300 μs,5.1166 μs,3.0448 μs,85.17,6.18,91.7969,7.3242,1503.44 KB,50.05 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,21.373 μs,0.8808 μs,0.5241 μs,6.54,0.49,29.2358,2.5635,477.89 KB,15.91 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,36.889 μs,0.4233 μs,0.2519 μs,11.29,0.81,8.2397,2.0752,135.15 KB,4.50 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FragmentHeavyBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FragmentHeavyBenchmarks-report.html new file mode 100644 index 00000000..03c7db1d --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.FragmentHeavyBenchmarks-report.html @@ -0,0 +1,47 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.FragmentHeavyBenchmarks-20260808-022108 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + + + + + + + + + + + +
      Method TrackMeanErrorStdDevRatioRatioSDGen0Gen1AllocatedAlloc Ratio
      RenderHeddlecontrolled3.081 μs0.1664 μs0.0990 μs1.000.041.37710.049622.54 KB1.00
      RenderHeddleUtf8controlled3.460 μs0.2422 μs0.1441 μs1.120.060.1831-3.05 KB0.14
      RenderHeddleTextWritercontrolled2.817 μs0.1876 μs0.1117 μs0.920.040.1831-3.04 KB0.13
      RenderFluidcontrolled11.220 μs0.4969 μs0.2957 μs3.640.142.09050.015334.37 KB1.52
      RenderScribancontrolled46.476 μs1.3660 μs0.8129 μs15.100.5311.23051.4648190.42 KB8.45
      RenderDotLiquidcontrolled170.223 μs1.3890 μs0.8266 μs55.301.7157.37304.1504937.89 KB41.61
      RenderHandlebarscontrolled20.692 μs0.3136 μs0.1866 μs6.720.2129.14432.4719476.2 KB21.13
      RenderRazorcontrolled44.056 μs1.4609 μs0.8694 μs14.310.518.05661.9531135.57 KB6.02
      RenderHeddleidiomatic3.285 μs0.4394 μs0.2615 μs1.010.101.83490.083930.04 KB1.00
      RenderHeddleUtf8idiomatic3.515 μs0.2909 μs0.1731 μs1.080.090.1831-3.05 KB0.10
      RenderHeddleTextWriteridiomatic2.899 μs0.3339 μs0.1987 μs0.890.090.1831-3.04 KB0.10
      RenderFluididiomatic11.798 μs0.2033 μs0.1210 μs3.610.262.24300.015336.82 KB1.23
      RenderScribanidiomatic52.684 μs1.5357 μs0.9139 μs16.121.1912.20701.9531201.28 KB6.70
      RenderDotLiquididiomatic278.300 μs5.1166 μs3.0448 μs85.176.1891.79697.32421503.44 KB50.05
      RenderHandlebarsidiomatic21.373 μs0.8808 μs0.5241 μs6.540.4929.23582.5635477.89 KB15.91
      RenderRazoridiomatic36.889 μs0.4233 μs0.2519 μs11.290.818.23972.0752135.15 KB4.50
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LanguageServiceBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LanguageServiceBenchmarks-report-github.md new file mode 100644 index 00000000..4ca9c367 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LanguageServiceBenchmarks-report-github.md @@ -0,0 +1,16 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | +|--------------- |---------:|----------:|----------:|------:|--------:|--------:|--------:|-------:|----------:|------------:| +| CompileFlagOff | 483.3 μs | 51.50 μs | 30.65 μs | 1.00 | 0.08 | 11.7188 | 9.7656 | 0.9766 | 186.61 KB | 1.00 | +| CompileFlagOn | 762.4 μs | 258.81 μs | 154.01 μs | 1.58 | 0.32 | 29.2969 | 19.5313 | 1.9531 | 478.38 KB | 2.56 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LanguageServiceBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LanguageServiceBenchmarks-report.csv new file mode 100644 index 00000000..80d8fd80 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LanguageServiceBenchmarks-report.csv @@ -0,0 +1,3 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Gen2,Allocated,Alloc Ratio +CompileFlagOff,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,483.3 μs,51.50 μs,30.65 μs,1.00,0.08,11.7188,9.7656,0.9766,186.61 KB,1.00 +CompileFlagOn,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,762.4 μs,258.81 μs,154.01 μs,1.58,0.32,29.2969,19.5313,1.9531,478.38 KB,2.56 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LanguageServiceBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LanguageServiceBenchmarks-report.html new file mode 100644 index 00000000..0389c39d --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LanguageServiceBenchmarks-report.html @@ -0,0 +1,33 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.LanguageServiceBenchmarks-20260808-031049 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + +
      Method MeanErrorStdDevRatioRatioSDGen0Gen1Gen2AllocatedAlloc Ratio
      CompileFlagOff483.3 μs51.50 μs30.65 μs1.000.0811.71889.76560.9766186.61 KB1.00
      CompileFlagOn762.4 μs258.81 μs154.01 μs1.580.3229.296919.53131.9531478.38 KB2.56
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LargeLoopBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LargeLoopBenchmarks-report-github.md new file mode 100644 index 00000000..2b588bd0 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LargeLoopBenchmarks-report-github.md @@ -0,0 +1,31 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Track | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | +|----------------------- |----------- |-----------:|----------:|----------:|------:|--------:|----------:|---------:|--------:|-----------:|------------:| +| **RenderHeddle** | **controlled** | **492.1 μs** | **3.46 μs** | **2.06 μs** | **1.00** | **0.01** | **53.7109** | **30.7617** | **30.7617** | **1172.35 KB** | **1.00** | +| RenderHeddleUtf8 | controlled | 157.3 μs | 1.83 μs | 1.09 μs | 0.32 | 0.00 | 23.1934 | - | - | 381.41 KB | 0.33 | +| RenderHeddleTextWriter | controlled | 131.1 μs | 0.60 μs | 0.36 μs | 0.27 | 0.00 | 23.1934 | - | - | 381.41 KB | 0.33 | +| RenderFluid | controlled | 790.1 μs | 22.49 μs | 13.38 μs | 1.61 | 0.03 | 93.7500 | 50.7813 | 15.6250 | 1668.61 KB | 1.42 | +| RenderScriban | controlled | 1,562.8 μs | 30.07 μs | 17.89 μs | 3.18 | 0.04 | 156.2500 | 80.0781 | 31.2500 | 2819.21 KB | 2.40 | +| RenderDotLiquid | controlled | 3,735.0 μs | 231.22 μs | 137.59 μs | 7.59 | 0.27 | 1042.9688 | 449.2188 | 11.7188 | 17257.6 KB | 14.72 | +| RenderHandlebars | controlled | 742.2 μs | 26.84 μs | 15.97 μs | 1.51 | 0.03 | 55.6641 | 30.2734 | 15.6250 | 1033.68 KB | 0.88 | +| RenderRazor | controlled | 744.1 μs | 5.92 μs | 3.52 μs | 1.51 | 0.01 | 58.5938 | 56.6406 | - | 1363.37 KB | 1.16 | +| | | | | | | | | | | | | +| **RenderHeddle** | **idiomatic** | **566.1 μs** | **7.08 μs** | **4.21 μs** | **1.00** | **0.01** | **57.6172** | **35.1563** | **35.1563** | **1295.42 KB** | **1.00** | +| RenderHeddleUtf8 | idiomatic | 158.0 μs | 5.31 μs | 3.16 μs | 0.28 | 0.01 | 23.1934 | - | - | 381.41 KB | 0.29 | +| RenderHeddleTextWriter | idiomatic | 131.7 μs | 2.63 μs | 1.56 μs | 0.23 | 0.00 | 23.1934 | - | - | 381.41 KB | 0.29 | +| RenderFluid | idiomatic | 859.7 μs | 10.35 μs | 6.16 μs | 1.52 | 0.01 | 99.6094 | 54.6875 | 17.5781 | 1790.02 KB | 1.38 | +| RenderScriban | idiomatic | 1,615.7 μs | 75.75 μs | 45.08 μs | 2.85 | 0.08 | 156.2500 | 78.1250 | 31.2500 | 2920.92 KB | 2.25 | +| RenderDotLiquid | idiomatic | 3,795.1 μs | 28.20 μs | 16.78 μs | 6.70 | 0.05 | 1050.7813 | 453.1250 | 15.6250 | 17363.3 KB | 13.40 | +| RenderHandlebars | idiomatic | 780.0 μs | 33.19 μs | 19.75 μs | 1.38 | 0.03 | 58.5938 | 32.2266 | 16.6016 | 1104.14 KB | 0.85 | +| RenderRazor | idiomatic | 569.7 μs | 8.76 μs | 5.21 μs | 1.01 | 0.01 | 54.6875 | 41.0156 | - | 1351.8 KB | 1.04 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LargeLoopBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LargeLoopBenchmarks-report.csv new file mode 100644 index 00000000..a96eae0f --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LargeLoopBenchmarks-report.csv @@ -0,0 +1,17 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Track,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Gen2,Allocated,Alloc Ratio +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,492.1 μs,3.46 μs,2.06 μs,1.00,0.01,53.7109,30.7617,30.7617,1172.35 KB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,157.3 μs,1.83 μs,1.09 μs,0.32,0.00,23.1934,0.0000,0.0000,381.41 KB,0.33 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,131.1 μs,0.60 μs,0.36 μs,0.27,0.00,23.1934,0.0000,0.0000,381.41 KB,0.33 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,790.1 μs,22.49 μs,13.38 μs,1.61,0.03,93.7500,50.7813,15.6250,1668.61 KB,1.42 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"1,562.8 μs",30.07 μs,17.89 μs,3.18,0.04,156.2500,80.0781,31.2500,2819.21 KB,2.40 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"3,735.0 μs",231.22 μs,137.59 μs,7.59,0.27,1042.9688,449.2188,11.7188,17257.6 KB,14.72 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,742.2 μs,26.84 μs,15.97 μs,1.51,0.03,55.6641,30.2734,15.6250,1033.68 KB,0.88 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,744.1 μs,5.92 μs,3.52 μs,1.51,0.01,58.5938,56.6406,0.0000,1363.37 KB,1.16 +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,566.1 μs,7.08 μs,4.21 μs,1.00,0.01,57.6172,35.1563,35.1563,1295.42 KB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,158.0 μs,5.31 μs,3.16 μs,0.28,0.01,23.1934,0.0000,0.0000,381.41 KB,0.29 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,131.7 μs,2.63 μs,1.56 μs,0.23,0.00,23.1934,0.0000,0.0000,381.41 KB,0.29 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,859.7 μs,10.35 μs,6.16 μs,1.52,0.01,99.6094,54.6875,17.5781,1790.02 KB,1.38 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"1,615.7 μs",75.75 μs,45.08 μs,2.85,0.08,156.2500,78.1250,31.2500,2920.92 KB,2.25 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"3,795.1 μs",28.20 μs,16.78 μs,6.70,0.05,1050.7813,453.1250,15.6250,17363.3 KB,13.40 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,780.0 μs,33.19 μs,19.75 μs,1.38,0.03,58.5938,32.2266,16.6016,1104.14 KB,0.85 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,569.7 μs,8.76 μs,5.21 μs,1.01,0.01,54.6875,41.0156,0.0000,1351.8 KB,1.04 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LargeLoopBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LargeLoopBenchmarks-report.html new file mode 100644 index 00000000..e4fd64d2 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.LargeLoopBenchmarks-report.html @@ -0,0 +1,47 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.LargeLoopBenchmarks-20260808-015136 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + + + + + + + + + + + +
      Method TrackMeanErrorStdDevRatioRatioSDGen0Gen1Gen2AllocatedAlloc Ratio
      RenderHeddlecontrolled492.1 μs3.46 μs2.06 μs1.000.0153.710930.761730.76171172.35 KB1.00
      RenderHeddleUtf8controlled157.3 μs1.83 μs1.09 μs0.320.0023.1934--381.41 KB0.33
      RenderHeddleTextWritercontrolled131.1 μs0.60 μs0.36 μs0.270.0023.1934--381.41 KB0.33
      RenderFluidcontrolled790.1 μs22.49 μs13.38 μs1.610.0393.750050.781315.62501668.61 KB1.42
      RenderScribancontrolled1,562.8 μs30.07 μs17.89 μs3.180.04156.250080.078131.25002819.21 KB2.40
      RenderDotLiquidcontrolled3,735.0 μs231.22 μs137.59 μs7.590.271042.9688449.218811.718817257.6 KB14.72
      RenderHandlebarscontrolled742.2 μs26.84 μs15.97 μs1.510.0355.664130.273415.62501033.68 KB0.88
      RenderRazorcontrolled744.1 μs5.92 μs3.52 μs1.510.0158.593856.6406-1363.37 KB1.16
      RenderHeddleidiomatic566.1 μs7.08 μs4.21 μs1.000.0157.617235.156335.15631295.42 KB1.00
      RenderHeddleUtf8idiomatic158.0 μs5.31 μs3.16 μs0.280.0123.1934--381.41 KB0.29
      RenderHeddleTextWriteridiomatic131.7 μs2.63 μs1.56 μs0.230.0023.1934--381.41 KB0.29
      RenderFluididiomatic859.7 μs10.35 μs6.16 μs1.520.0199.609454.687517.57811790.02 KB1.38
      RenderScribanidiomatic1,615.7 μs75.75 μs45.08 μs2.850.08156.250078.125031.25002920.92 KB2.25
      RenderDotLiquididiomatic3,795.1 μs28.20 μs16.78 μs6.700.051050.7813453.125015.625017363.3 KB13.40
      RenderHandlebarsidiomatic780.0 μs33.19 μs19.75 μs1.380.0358.593832.226616.60161104.14 KB0.85
      RenderRazoridiomatic569.7 μs8.76 μs5.21 μs1.010.0154.687541.0156-1351.8 KB1.04
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.MixedPageBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.MixedPageBenchmarks-report-github.md new file mode 100644 index 00000000..b3595ce4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.MixedPageBenchmarks-report-github.md @@ -0,0 +1,31 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Track | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio | +|----------------------- |----------- |----------:|-----------:|-----------:|------:|--------:|--------:|-------:|----------:|------------:| +| **RenderHeddle** | **controlled** | **2.636 μs** | **0.0337 μs** | **0.0200 μs** | **1.00** | **0.01** | **2.6855** | **0.1755** | **43.96 KB** | **1.00** | +| RenderHeddleUtf8 | controlled | 2.788 μs | 0.1047 μs | 0.0623 μs | 1.06 | 0.02 | 0.2365 | - | 3.92 KB | 0.09 | +| RenderHeddleTextWriter | controlled | 2.265 μs | 0.0121 μs | 0.0072 μs | 0.86 | 0.01 | 0.2365 | - | 3.91 KB | 0.09 | +| RenderFluid | controlled | 8.918 μs | 0.2473 μs | 0.1472 μs | 3.38 | 0.06 | 1.7700 | - | 28.99 KB | 0.66 | +| RenderScriban | controlled | 71.202 μs | 24.5102 μs | 14.5856 μs | 27.01 | 5.25 | 27.3438 | 2.4414 | 453.25 KB | 10.31 | +| RenderDotLiquid | controlled | 56.338 μs | 2.6957 μs | 1.6042 μs | 21.37 | 0.60 | 17.3340 | 1.3428 | 283.67 KB | 6.45 | +| RenderHandlebars | controlled | 7.247 μs | 0.1362 μs | 0.0811 μs | 2.75 | 0.04 | 2.6779 | 0.2060 | 43.83 KB | 1.00 | +| RenderRazor | controlled | 20.131 μs | 0.4106 μs | 0.2444 μs | 7.64 | 0.10 | 3.7842 | 1.2207 | 62.54 KB | 1.42 | +| | | | | | | | | | | | +| **RenderHeddle** | **idiomatic** | **2.906 μs** | **0.0269 μs** | **0.0160 μs** | **1.00** | **0.01** | **3.8033** | **0.3777** | **62.3 KB** | **1.00** | +| RenderHeddleUtf8 | idiomatic | 2.754 μs | 0.0365 μs | 0.0217 μs | 0.95 | 0.01 | 0.2365 | - | 3.92 KB | 0.06 | +| RenderHeddleTextWriter | idiomatic | 2.304 μs | 0.0205 μs | 0.0122 μs | 0.79 | 0.01 | 0.2365 | - | 3.91 KB | 0.06 | +| RenderFluid | idiomatic | 9.115 μs | 0.4819 μs | 0.2868 μs | 3.14 | 0.10 | 2.1667 | - | 35.49 KB | 0.57 | +| RenderScriban | idiomatic | 68.265 μs | 13.4083 μs | 7.9790 μs | 23.49 | 2.61 | 29.2969 | 0.9766 | 481.21 KB | 7.72 | +| RenderDotLiquid | idiomatic | 59.112 μs | 1.9223 μs | 1.1439 μs | 20.34 | 0.39 | 18.7378 | 2.1973 | 306.88 KB | 4.93 | +| RenderHandlebars | idiomatic | 10.260 μs | 0.2998 μs | 0.1784 μs | 3.53 | 0.06 | 4.0588 | 0.4425 | 66.41 KB | 1.07 | +| RenderRazor | idiomatic | 15.505 μs | 0.2166 μs | 0.1289 μs | 5.34 | 0.05 | 5.2490 | 1.3123 | 85.91 KB | 1.38 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.MixedPageBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.MixedPageBenchmarks-report.csv new file mode 100644 index 00000000..8a55b21a --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.MixedPageBenchmarks-report.csv @@ -0,0 +1,17 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Track,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Allocated,Alloc Ratio +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,2.636 μs,0.0337 μs,0.0200 μs,1.00,0.01,2.6855,0.1755,43.96 KB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,2.788 μs,0.1047 μs,0.0623 μs,1.06,0.02,0.2365,0.0000,3.92 KB,0.09 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,2.265 μs,0.0121 μs,0.0072 μs,0.86,0.01,0.2365,0.0000,3.91 KB,0.09 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,8.918 μs,0.2473 μs,0.1472 μs,3.38,0.06,1.7700,0.0000,28.99 KB,0.66 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,71.202 μs,24.5102 μs,14.5856 μs,27.01,5.25,27.3438,2.4414,453.25 KB,10.31 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,56.338 μs,2.6957 μs,1.6042 μs,21.37,0.60,17.3340,1.3428,283.67 KB,6.45 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,7.247 μs,0.1362 μs,0.0811 μs,2.75,0.04,2.6779,0.2060,43.83 KB,1.00 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,20.131 μs,0.4106 μs,0.2444 μs,7.64,0.10,3.7842,1.2207,62.54 KB,1.42 +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,2.906 μs,0.0269 μs,0.0160 μs,1.00,0.01,3.8033,0.3777,62.3 KB,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,2.754 μs,0.0365 μs,0.0217 μs,0.95,0.01,0.2365,0.0000,3.92 KB,0.06 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,2.304 μs,0.0205 μs,0.0122 μs,0.79,0.01,0.2365,0.0000,3.91 KB,0.06 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,9.115 μs,0.4819 μs,0.2868 μs,3.14,0.10,2.1667,0.0000,35.49 KB,0.57 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,68.265 μs,13.4083 μs,7.9790 μs,23.49,2.61,29.2969,0.9766,481.21 KB,7.72 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,59.112 μs,1.9223 μs,1.1439 μs,20.34,0.39,18.7378,2.1973,306.88 KB,4.93 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,10.260 μs,0.2998 μs,0.1784 μs,3.53,0.06,4.0588,0.4425,66.41 KB,1.07 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,15.505 μs,0.2166 μs,0.1289 μs,5.34,0.05,5.2490,1.3123,85.91 KB,1.38 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.MixedPageBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.MixedPageBenchmarks-report.html new file mode 100644 index 00000000..2cf6f157 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.MixedPageBenchmarks-report.html @@ -0,0 +1,47 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.MixedPageBenchmarks-20260808-020201 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + + + + + + + + + + + +
      Method TrackMeanErrorStdDevRatioRatioSDGen0Gen1AllocatedAlloc Ratio
      RenderHeddlecontrolled2.636 μs0.0337 μs0.0200 μs1.000.012.68550.175543.96 KB1.00
      RenderHeddleUtf8controlled2.788 μs0.1047 μs0.0623 μs1.060.020.2365-3.92 KB0.09
      RenderHeddleTextWritercontrolled2.265 μs0.0121 μs0.0072 μs0.860.010.2365-3.91 KB0.09
      RenderFluidcontrolled8.918 μs0.2473 μs0.1472 μs3.380.061.7700-28.99 KB0.66
      RenderScribancontrolled71.202 μs24.5102 μs14.5856 μs27.015.2527.34382.4414453.25 KB10.31
      RenderDotLiquidcontrolled56.338 μs2.6957 μs1.6042 μs21.370.6017.33401.3428283.67 KB6.45
      RenderHandlebarscontrolled7.247 μs0.1362 μs0.0811 μs2.750.042.67790.206043.83 KB1.00
      RenderRazorcontrolled20.131 μs0.4106 μs0.2444 μs7.640.103.78421.220762.54 KB1.42
      RenderHeddleidiomatic2.906 μs0.0269 μs0.0160 μs1.000.013.80330.377762.3 KB1.00
      RenderHeddleUtf8idiomatic2.754 μs0.0365 μs0.0217 μs0.950.010.2365-3.92 KB0.06
      RenderHeddleTextWriteridiomatic2.304 μs0.0205 μs0.0122 μs0.790.010.2365-3.91 KB0.06
      RenderFluididiomatic9.115 μs0.4819 μs0.2868 μs3.140.102.1667-35.49 KB0.57
      RenderScribanidiomatic68.265 μs13.4083 μs7.9790 μs23.492.6129.29690.9766481.21 KB7.72
      RenderDotLiquididiomatic59.112 μs1.9223 μs1.1439 μs20.340.3918.73782.1973306.88 KB4.93
      RenderHandlebarsidiomatic10.260 μs0.2998 μs0.1784 μs3.530.064.05880.442566.41 KB1.07
      RenderRazoridiomatic15.505 μs0.2166 μs0.1289 μs5.340.055.24901.312385.91 KB1.38
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.PropsBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.PropsBenchmarks-report-github.md new file mode 100644 index 00000000..587d762c --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.PropsBenchmarks-report-github.md @@ -0,0 +1,18 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | +|------------------ |----------:|---------:|---------:|------:|--------:|-------:|----------:|------------:| +| DefinitionNoProps | 77.95 ns | 4.089 ns | 2.434 ns | 1.00 | 0.04 | 0.0248 | 416 B | 1.00 | +| AllConstantProps | 91.44 ns | 1.692 ns | 1.007 ns | 1.17 | 0.04 | 0.0310 | 520 B | 1.25 | +| DynamicProps | 118.12 ns | 2.798 ns | 1.665 ns | 1.52 | 0.05 | 0.0329 | 552 B | 1.33 | +| ParameterizedSlot | 218.24 ns | 3.371 ns | 2.006 ns | 2.80 | 0.08 | 0.0591 | 992 B | 2.38 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.PropsBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.PropsBenchmarks-report.csv new file mode 100644 index 00000000..8fb1275b --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.PropsBenchmarks-report.csv @@ -0,0 +1,5 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Allocated,Alloc Ratio +DefinitionNoProps,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,77.95 ns,4.089 ns,2.434 ns,1.00,0.04,0.0248,416 B,1.00 +AllConstantProps,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,91.44 ns,1.692 ns,1.007 ns,1.17,0.04,0.0310,520 B,1.25 +DynamicProps,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,118.12 ns,2.798 ns,1.665 ns,1.52,0.05,0.0329,552 B,1.33 +ParameterizedSlot,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,218.24 ns,3.371 ns,2.006 ns,2.80,0.08,0.0591,992 B,2.38 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.PropsBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.PropsBenchmarks-report.html new file mode 100644 index 00000000..33adb7bb --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.PropsBenchmarks-report.html @@ -0,0 +1,35 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.PropsBenchmarks-20260808-030740 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + +
      Method MeanErrorStdDevRatioRatioSDGen0AllocatedAlloc Ratio
      DefinitionNoProps77.95 ns4.089 ns2.434 ns1.000.040.0248416 B1.00
      AllConstantProps91.44 ns1.692 ns1.007 ns1.170.040.0310520 B1.25
      DynamicProps118.12 ns2.798 ns1.665 ns1.520.050.0329552 B1.33
      ParameterizedSlot218.24 ns3.371 ns2.006 ns2.800.080.0591992 B2.38
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniquePrecompiledBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniquePrecompiledBenchmarks-report-github.md new file mode 100644 index 00000000..fdb4e11e --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniquePrecompiledBenchmarks-report-github.md @@ -0,0 +1,33 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Workload | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | +|----------- |--------------------- |---------------:|-------------:|-------------:|------:|--------:|---------:|---------:|---------:|----------:|------------:| +| **Utf8** | **conditional-heavy** | **24,572.1 ns** | **1,663.03 ns** | **989.64 ns** | **1.00** | **0.05** | **2.1057** | **-** | **-** | **35352 B** | **1.00** | +| TextWriter | conditional-heavy | 17,830.6 ns | 226.52 ns | 134.80 ns | 0.73 | 0.03 | 2.1057 | - | - | 35344 B | 1.00 | +| String | conditional-heavy | 18,328.5 ns | 83.33 ns | 49.59 ns | 0.75 | 0.03 | 7.8735 | - | - | 131768 B | 3.73 | +| | | | | | | | | | | | | +| **Utf8** | **fragment-heavy** | **4,463.1 ns** | **295.72 ns** | **175.98 ns** | **1.00** | **0.05** | **0.1831** | **-** | **-** | **3088 B** | **1.00** | +| TextWriter | fragment-heavy | 2,968.3 ns | 34.99 ns | 20.82 ns | 0.67 | 0.02 | 0.1831 | - | - | 3080 B | 1.00 | +| String | fragment-heavy | 3,603.0 ns | 50.24 ns | 29.90 ns | 0.81 | 0.03 | 2.4376 | 0.3014 | - | 40768 B | 13.20 | +| | | | | | | | | | | | | +| **Utf8** | **large-loop** | **220,761.0 ns** | **4,742.24 ns** | **2,822.03 ns** | **1.00** | **0.02** | **23.1934** | **-** | **-** | **390536 B** | **1.00** | +| TextWriter | large-loop | 157,615.4 ns | 1,125.02 ns | 669.48 ns | 0.71 | 0.01 | 23.1934 | - | - | 390528 B | 1.00 | +| String | large-loop | 2,574,464.1 ns | 82,325.07 ns | 48,990.33 ns | 11.66 | 0.25 | 210.9375 | 167.9688 | 164.0625 | 1579378 B | 4.04 | +| | | | | | | | | | | | | +| **Utf8** | **mixed-page** | **4,376.7 ns** | **135.15 ns** | **80.43 ns** | **1.00** | **0.02** | **0.2365** | **-** | **-** | **3984 B** | **1.00** | +| TextWriter | mixed-page | 2,600.4 ns | 25.05 ns | 14.91 ns | 0.59 | 0.01 | 0.2365 | - | - | 3976 B | 1.00 | +| String | mixed-page | 3,336.8 ns | 63.24 ns | 37.64 ns | 0.76 | 0.02 | 4.2305 | 0.4692 | - | 70816 B | 17.78 | +| | | | | | | | | | | | | +| **Utf8** | **trivial-substitution** | **201.9 ns** | **2.34 ns** | **1.39 ns** | **1.00** | **0.01** | **0.0105** | **-** | **-** | **176 B** | **1.00** | +| TextWriter | trivial-substitution | 130.4 ns | 1.88 ns | 1.12 ns | 0.65 | 0.01 | 0.0100 | - | - | 168 B | 0.95 | +| String | trivial-substitution | 189.9 ns | 2.65 ns | 1.58 ns | 0.94 | 0.01 | 0.1721 | 0.0010 | - | 2880 B | 16.36 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniquePrecompiledBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniquePrecompiledBenchmarks-report.csv new file mode 100644 index 00000000..d90617ec --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniquePrecompiledBenchmarks-report.csv @@ -0,0 +1,16 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Workload,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Gen2,Allocated,Alloc Ratio +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,conditional-heavy,"24,572.1 ns","1,663.03 ns",989.64 ns,1.00,0.05,2.1057,0.0000,0.0000,35352 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,conditional-heavy,"17,830.6 ns",226.52 ns,134.80 ns,0.73,0.03,2.1057,0.0000,0.0000,35344 B,1.00 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,conditional-heavy,"18,328.5 ns",83.33 ns,49.59 ns,0.75,0.03,7.8735,0.0000,0.0000,131768 B,3.73 +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,fragment-heavy,"4,463.1 ns",295.72 ns,175.98 ns,1.00,0.05,0.1831,0.0000,0.0000,3088 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,fragment-heavy,"2,968.3 ns",34.99 ns,20.82 ns,0.67,0.02,0.1831,0.0000,0.0000,3080 B,1.00 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,fragment-heavy,"3,603.0 ns",50.24 ns,29.90 ns,0.81,0.03,2.4376,0.3014,0.0000,40768 B,13.20 +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,large-loop,"220,761.0 ns","4,742.24 ns","2,822.03 ns",1.00,0.02,23.1934,0.0000,0.0000,390536 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,large-loop,"157,615.4 ns","1,125.02 ns",669.48 ns,0.71,0.01,23.1934,0.0000,0.0000,390528 B,1.00 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,large-loop,"2,574,464.1 ns","82,325.07 ns","48,990.33 ns",11.66,0.25,210.9375,167.9688,164.0625,1579378 B,4.04 +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,mixed-page,"4,376.7 ns",135.15 ns,80.43 ns,1.00,0.02,0.2365,0.0000,0.0000,3984 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,mixed-page,"2,600.4 ns",25.05 ns,14.91 ns,0.59,0.01,0.2365,0.0000,0.0000,3976 B,1.00 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,mixed-page,"3,336.8 ns",63.24 ns,37.64 ns,0.76,0.02,4.2305,0.4692,0.0000,70816 B,17.78 +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,trivial-substitution,201.9 ns,2.34 ns,1.39 ns,1.00,0.01,0.0105,0.0000,0.0000,176 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,trivial-substitution,130.4 ns,1.88 ns,1.12 ns,0.65,0.01,0.0100,0.0000,0.0000,168 B,0.95 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,trivial-substitution,189.9 ns,2.65 ns,1.58 ns,0.94,0.01,0.1721,0.0010,0.0000,2880 B,16.36 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniquePrecompiledBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniquePrecompiledBenchmarks-report.html new file mode 100644 index 00000000..b1d30029 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniquePrecompiledBenchmarks-report.html @@ -0,0 +1,46 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.TechniquePrecompiledBenchmarks-20260808-025943 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + + + + + + + + + + +
      MethodWorkload Mean Error StdDevRatioRatioSDGen0Gen1Gen2AllocatedAlloc Ratio
      Utf8conditional-heavy24,572.1 ns1,663.03 ns989.64 ns1.000.052.1057--35352 B1.00
      TextWriterconditional-heavy17,830.6 ns226.52 ns134.80 ns0.730.032.1057--35344 B1.00
      Stringconditional-heavy18,328.5 ns83.33 ns49.59 ns0.750.037.8735--131768 B3.73
      Utf8fragment-heavy4,463.1 ns295.72 ns175.98 ns1.000.050.1831--3088 B1.00
      TextWriterfragment-heavy2,968.3 ns34.99 ns20.82 ns0.670.020.1831--3080 B1.00
      Stringfragment-heavy3,603.0 ns50.24 ns29.90 ns0.810.032.43760.3014-40768 B13.20
      Utf8large-loop220,761.0 ns4,742.24 ns2,822.03 ns1.000.0223.1934--390536 B1.00
      TextWriterlarge-loop157,615.4 ns1,125.02 ns669.48 ns0.710.0123.1934--390528 B1.00
      Stringlarge-loop2,574,464.1 ns82,325.07 ns48,990.33 ns11.660.25210.9375167.9688164.06251579378 B4.04
      Utf8mixed-page4,376.7 ns135.15 ns80.43 ns1.000.020.2365--3984 B1.00
      TextWritermixed-page2,600.4 ns25.05 ns14.91 ns0.590.010.2365--3976 B1.00
      Stringmixed-page3,336.8 ns63.24 ns37.64 ns0.760.024.23050.4692-70816 B17.78
      Utf8trivial-substitution201.9 ns2.34 ns1.39 ns1.000.010.0105--176 B1.00
      TextWritertrivial-substitution130.4 ns1.88 ns1.12 ns0.650.010.0100--168 B0.95
      Stringtrivial-substitution189.9 ns2.65 ns1.58 ns0.940.010.17210.0010-2880 B16.36
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniqueRuntimeBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniqueRuntimeBenchmarks-report-github.md new file mode 100644 index 00000000..441cade6 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniqueRuntimeBenchmarks-report-github.md @@ -0,0 +1,45 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Workload | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio | +|----------- |--------------------- |---------------:|-------------:|-------------:|------:|--------:|---------:|---------:|---------:|----------:|------------:| +| **Utf8** | **composed-page** | **1,872.6 ns** | **257.89 ns** | **153.47 ns** | **1.01** | **0.11** | **0.0076** | **-** | **-** | **184 B** | **1.00** | +| TextWriter | composed-page | 1,336.0 ns | 284.44 ns | 169.26 ns | 0.72 | 0.10 | 0.0076 | - | - | 128 B | 0.70 | +| String | composed-page | 23,666.9 ns | 598.02 ns | 355.87 ns | 12.72 | 1.06 | 7.3853 | 7.3853 | 7.3853 | 233411 B | 1,268.54 | +| | | | | | | | | | | | | +| **Utf8** | **conditional-heavy** | **18,405.1 ns** | **227.09 ns** | **135.14 ns** | **1.00** | **0.01** | **2.1057** | **-** | **-** | **35384 B** | **1.00** | +| TextWriter | conditional-heavy | 14,301.4 ns | 315.52 ns | 187.76 ns | 0.78 | 0.01 | 2.1057 | - | - | 35376 B | 1.00 | +| String | conditional-heavy | 14,777.3 ns | 375.31 ns | 223.34 ns | 0.80 | 0.01 | 6.0120 | 0.6561 | - | 100792 B | 2.85 | +| | | | | | | | | | | | | +| **Utf8** | **encoded-loop** | **723,383.6 ns** | **5,340.39 ns** | **3,177.98 ns** | **1.00** | **0.01** | **166.0156** | **-** | **-** | **2792016 B** | **1.00** | +| TextWriter | encoded-loop | 594,913.8 ns | 11,166.52 ns | 6,645.02 ns | 0.82 | 0.01 | 166.0156 | - | - | 2792008 B | 1.00 | +| String | encoded-loop | 3,949,423.1 ns | 19,537.72 ns | 11,626.59 ns | 5.46 | 0.03 | 406.2500 | 242.1875 | 242.1875 | 6075514 B | 2.18 | +| | | | | | | | | | | | | +| **Utf8** | **fortunes-encoded** | **710.3 ns** | **11.11 ns** | **6.61 ns** | **1.00** | **0.01** | **0.1373** | **-** | **-** | **2304 B** | **1.00** | +| TextWriter | fortunes-encoded | 629.6 ns | 7.77 ns | 4.63 ns | 0.89 | 0.01 | 0.1364 | - | - | 2296 B | 1.00 | +| String | fortunes-encoded | 736.8 ns | 4.43 ns | 2.64 ns | 1.04 | 0.01 | 0.4253 | 0.0038 | - | 7120 B | 3.09 | +| | | | | | | | | | | | | +| **Utf8** | **fragment-heavy** | **3,429.6 ns** | **225.93 ns** | **134.45 ns** | **1.00** | **0.05** | **0.1831** | **-** | **-** | **3120 B** | **1.00** | +| TextWriter | fragment-heavy | 2,953.8 ns | 276.04 ns | 164.27 ns | 0.86 | 0.06 | 0.1831 | - | - | 3112 B | 1.00 | +| String | fragment-heavy | 3,253.8 ns | 351.72 ns | 209.30 ns | 0.95 | 0.07 | 1.3771 | 0.0496 | - | 23080 B | 7.40 | +| | | | | | | | | | | | | +| **Utf8** | **large-loop** | **156,968.2 ns** | **1,842.46 ns** | **1,096.42 ns** | **1.00** | **0.01** | **23.1934** | **-** | **-** | **390568 B** | **1.00** | +| TextWriter | large-loop | 129,373.8 ns | 700.30 ns | 416.74 ns | 0.82 | 0.01 | 23.1934 | - | - | 390560 B | 1.00 | +| String | large-loop | 1,144,406.6 ns | 21,500.58 ns | 12,794.65 ns | 7.29 | 0.09 | 91.7969 | 70.3125 | 70.3125 | 1200421 B | 3.07 | +| | | | | | | | | | | | | +| **Utf8** | **mixed-page** | **2,797.3 ns** | **132.02 ns** | **78.56 ns** | **1.00** | **0.04** | **0.2365** | **-** | **-** | **4016 B** | **1.00** | +| TextWriter | mixed-page | 2,215.0 ns | 24.51 ns | 14.59 ns | 0.79 | 0.02 | 0.2365 | - | - | 4008 B | 1.00 | +| String | mixed-page | 2,558.0 ns | 17.94 ns | 10.68 ns | 0.92 | 0.02 | 2.6855 | 0.1755 | - | 45016 B | 11.21 | +| | | | | | | | | | | | | +| **Utf8** | **trivial-substitution** | **132.0 ns** | **3.11 ns** | **1.85 ns** | **1.00** | **0.02** | **0.0124** | **-** | **-** | **208 B** | **1.00** | +| TextWriter | trivial-substitution | 108.5 ns | 3.77 ns | 2.24 ns | 0.82 | 0.02 | 0.0119 | - | - | 200 B | 0.96 | +| String | trivial-substitution | 152.9 ns | 1.23 ns | 0.73 ns | 1.16 | 0.02 | 0.1028 | - | - | 1720 B | 8.27 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniqueRuntimeBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniqueRuntimeBenchmarks-report.csv new file mode 100644 index 00000000..bcca8b22 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniqueRuntimeBenchmarks-report.csv @@ -0,0 +1,25 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Workload,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Gen2,Allocated,Alloc Ratio +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,composed-page,"1,872.6 ns",257.89 ns,153.47 ns,1.01,0.11,0.0076,0.0000,0.0000,184 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,composed-page,"1,336.0 ns",284.44 ns,169.26 ns,0.72,0.10,0.0076,0.0000,0.0000,128 B,0.70 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,composed-page,"23,666.9 ns",598.02 ns,355.87 ns,12.72,1.06,7.3853,7.3853,7.3853,233411 B,"1,268.54" +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,conditional-heavy,"18,405.1 ns",227.09 ns,135.14 ns,1.00,0.01,2.1057,0.0000,0.0000,35384 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,conditional-heavy,"14,301.4 ns",315.52 ns,187.76 ns,0.78,0.01,2.1057,0.0000,0.0000,35376 B,1.00 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,conditional-heavy,"14,777.3 ns",375.31 ns,223.34 ns,0.80,0.01,6.0120,0.6561,0.0000,100792 B,2.85 +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,encoded-loop,"723,383.6 ns","5,340.39 ns","3,177.98 ns",1.00,0.01,166.0156,0.0000,0.0000,2792016 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,encoded-loop,"594,913.8 ns","11,166.52 ns","6,645.02 ns",0.82,0.01,166.0156,0.0000,0.0000,2792008 B,1.00 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,encoded-loop,"3,949,423.1 ns","19,537.72 ns","11,626.59 ns",5.46,0.03,406.2500,242.1875,242.1875,6075514 B,2.18 +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,fortunes-encoded,710.3 ns,11.11 ns,6.61 ns,1.00,0.01,0.1373,0.0000,0.0000,2304 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,fortunes-encoded,629.6 ns,7.77 ns,4.63 ns,0.89,0.01,0.1364,0.0000,0.0000,2296 B,1.00 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,fortunes-encoded,736.8 ns,4.43 ns,2.64 ns,1.04,0.01,0.4253,0.0038,0.0000,7120 B,3.09 +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,fragment-heavy,"3,429.6 ns",225.93 ns,134.45 ns,1.00,0.05,0.1831,0.0000,0.0000,3120 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,fragment-heavy,"2,953.8 ns",276.04 ns,164.27 ns,0.86,0.06,0.1831,0.0000,0.0000,3112 B,1.00 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,fragment-heavy,"3,253.8 ns",351.72 ns,209.30 ns,0.95,0.07,1.3771,0.0496,0.0000,23080 B,7.40 +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,large-loop,"156,968.2 ns","1,842.46 ns","1,096.42 ns",1.00,0.01,23.1934,0.0000,0.0000,390568 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,large-loop,"129,373.8 ns",700.30 ns,416.74 ns,0.82,0.01,23.1934,0.0000,0.0000,390560 B,1.00 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,large-loop,"1,144,406.6 ns","21,500.58 ns","12,794.65 ns",7.29,0.09,91.7969,70.3125,70.3125,1200421 B,3.07 +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,mixed-page,"2,797.3 ns",132.02 ns,78.56 ns,1.00,0.04,0.2365,0.0000,0.0000,4016 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,mixed-page,"2,215.0 ns",24.51 ns,14.59 ns,0.79,0.02,0.2365,0.0000,0.0000,4008 B,1.00 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,mixed-page,"2,558.0 ns",17.94 ns,10.68 ns,0.92,0.02,2.6855,0.1755,0.0000,45016 B,11.21 +Utf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,trivial-substitution,132.0 ns,3.11 ns,1.85 ns,1.00,0.02,0.0124,0.0000,0.0000,208 B,1.00 +TextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,trivial-substitution,108.5 ns,3.77 ns,2.24 ns,0.82,0.02,0.0119,0.0000,0.0000,200 B,0.96 +String,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,trivial-substitution,152.9 ns,1.23 ns,0.73 ns,1.16,0.02,0.1028,0.0000,0.0000,1720 B,8.27 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniqueRuntimeBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniqueRuntimeBenchmarks-report.html new file mode 100644 index 00000000..e989eebf --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TechniqueRuntimeBenchmarks-report.html @@ -0,0 +1,55 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.TechniqueRuntimeBenchmarks-20260808-025037 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      MethodWorkload Mean Error StdDevRatioRatioSDGen0Gen1Gen2AllocatedAlloc Ratio
      Utf8composed-page1,872.6 ns257.89 ns153.47 ns1.010.110.0076--184 B1.00
      TextWritercomposed-page1,336.0 ns284.44 ns169.26 ns0.720.100.0076--128 B0.70
      Stringcomposed-page23,666.9 ns598.02 ns355.87 ns12.721.067.38537.38537.3853233411 B1,268.54
      Utf8conditional-heavy18,405.1 ns227.09 ns135.14 ns1.000.012.1057--35384 B1.00
      TextWriterconditional-heavy14,301.4 ns315.52 ns187.76 ns0.780.012.1057--35376 B1.00
      Stringconditional-heavy14,777.3 ns375.31 ns223.34 ns0.800.016.01200.6561-100792 B2.85
      Utf8encoded-loop723,383.6 ns5,340.39 ns3,177.98 ns1.000.01166.0156--2792016 B1.00
      TextWriterencoded-loop594,913.8 ns11,166.52 ns6,645.02 ns0.820.01166.0156--2792008 B1.00
      Stringencoded-loop3,949,423.1 ns19,537.72 ns11,626.59 ns5.460.03406.2500242.1875242.18756075514 B2.18
      Utf8fortunes-encoded710.3 ns11.11 ns6.61 ns1.000.010.1373--2304 B1.00
      TextWriterfortunes-encoded629.6 ns7.77 ns4.63 ns0.890.010.1364--2296 B1.00
      Stringfortunes-encoded736.8 ns4.43 ns2.64 ns1.040.010.42530.0038-7120 B3.09
      Utf8fragment-heavy3,429.6 ns225.93 ns134.45 ns1.000.050.1831--3120 B1.00
      TextWriterfragment-heavy2,953.8 ns276.04 ns164.27 ns0.860.060.1831--3112 B1.00
      Stringfragment-heavy3,253.8 ns351.72 ns209.30 ns0.950.071.37710.0496-23080 B7.40
      Utf8large-loop156,968.2 ns1,842.46 ns1,096.42 ns1.000.0123.1934--390568 B1.00
      TextWriterlarge-loop129,373.8 ns700.30 ns416.74 ns0.820.0123.1934--390560 B1.00
      Stringlarge-loop1,144,406.6 ns21,500.58 ns12,794.65 ns7.290.0991.796970.312570.31251200421 B3.07
      Utf8mixed-page2,797.3 ns132.02 ns78.56 ns1.000.040.2365--4016 B1.00
      TextWritermixed-page2,215.0 ns24.51 ns14.59 ns0.790.020.2365--4008 B1.00
      Stringmixed-page2,558.0 ns17.94 ns10.68 ns0.920.022.68550.1755-45016 B11.21
      Utf8trivial-substitution132.0 ns3.11 ns1.85 ns1.000.020.0124--208 B1.00
      TextWritertrivial-substitution108.5 ns3.77 ns2.24 ns0.820.020.0119--200 B0.96
      Stringtrivial-substitution152.9 ns1.23 ns0.73 ns1.160.020.1028--1720 B8.27
      + + diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TrivialSubstitutionBenchmarks-report-github.md b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TrivialSubstitutionBenchmarks-report-github.md new file mode 100644 index 00000000..fa457924 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TrivialSubstitutionBenchmarks-report-github.md @@ -0,0 +1,31 @@ +``` + +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2) +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores +.NET SDK 10.0.302 + [Host] : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4 + +Job=ShortRun IterationCount=3 LaunchCount=3 +WarmupCount=3 + +``` +| Method | Track | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio | +|----------------------- |----------- |------------:|------------:|------------:|-------:|--------:|--------:|-------:|----------:|------------:| +| **RenderHeddle** | **controlled** | **149.0 ns** | **7.75 ns** | **4.61 ns** | **1.00** | **0.04** | **0.1028** | **-** | **1720 B** | **1.00** | +| RenderHeddleUtf8 | controlled | 161.9 ns | 2.65 ns | 1.58 ns | 1.09 | 0.03 | 0.0124 | - | 208 B | 0.12 | +| RenderHeddleTextWriter | controlled | 142.7 ns | 13.55 ns | 8.06 ns | 0.96 | 0.06 | 0.0119 | - | 200 B | 0.12 | +| RenderFluid | controlled | 482.9 ns | 20.47 ns | 12.18 ns | 3.24 | 0.12 | 0.1392 | - | 2344 B | 1.36 | +| RenderScriban | controlled | 38,805.4 ns | 639.12 ns | 380.33 ns | 260.64 | 8.20 | 20.5078 | 1.7090 | 343936 B | 199.96 | +| RenderDotLiquid | controlled | 1,888.2 ns | 20.20 ns | 12.02 ns | 12.68 | 0.39 | 0.6199 | 0.0038 | 10384 B | 6.04 | +| RenderHandlebars | controlled | 385.8 ns | 7.23 ns | 4.30 ns | 2.59 | 0.08 | 0.0439 | - | 736 B | 0.43 | +| RenderRazor | controlled | 5,523.2 ns | 63.10 ns | 37.55 ns | 37.10 | 1.14 | 0.7935 | 0.2594 | 13360 B | 7.77 | +| | | | | | | | | | | | +| **RenderHeddle** | **idiomatic** | **148.1 ns** | **5.21 ns** | **3.10 ns** | **1.00** | **0.03** | **0.1147** | **-** | **1920 B** | **1.00** | +| RenderHeddleUtf8 | idiomatic | 160.4 ns | 2.34 ns | 1.39 ns | 1.08 | 0.02 | 0.0124 | - | 208 B | 0.11 | +| RenderHeddleTextWriter | idiomatic | 141.6 ns | 13.85 ns | 8.24 ns | 0.96 | 0.06 | 0.0119 | - | 200 B | 0.10 | +| RenderFluid | idiomatic | 491.4 ns | 21.52 ns | 12.81 ns | 3.32 | 0.10 | 0.1440 | - | 2424 B | 1.26 | +| RenderScriban | idiomatic | 38,709.8 ns | 3,542.32 ns | 2,107.98 ns | 261.55 | 14.45 | 20.5078 | 1.8311 | 344024 B | 179.18 | +| RenderDotLiquid | idiomatic | 1,925.7 ns | 37.68 ns | 22.42 ns | 13.01 | 0.29 | 0.6218 | 0.0038 | 10464 B | 5.45 | +| RenderHandlebars | idiomatic | 461.2 ns | 4.16 ns | 2.48 ns | 3.12 | 0.06 | 0.0486 | - | 816 B | 0.42 | +| RenderRazor | idiomatic | 4,833.0 ns | 49.84 ns | 29.66 ns | 32.65 | 0.67 | 0.7858 | 0.2594 | 13200 B | 6.88 | diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TrivialSubstitutionBenchmarks-report.csv b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TrivialSubstitutionBenchmarks-report.csv new file mode 100644 index 00000000..a9cc4857 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TrivialSubstitutionBenchmarks-report.csv @@ -0,0 +1,17 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Track,Mean,Error,StdDev,Ratio,RatioSD,Gen0,Gen1,Allocated,Alloc Ratio +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,149.0 ns,7.75 ns,4.61 ns,1.00,0.04,0.1028,0.0000,1720 B,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,161.9 ns,2.65 ns,1.58 ns,1.09,0.03,0.0124,0.0000,208 B,0.12 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,142.7 ns,13.55 ns,8.06 ns,0.96,0.06,0.0119,0.0000,200 B,0.12 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,482.9 ns,20.47 ns,12.18 ns,3.24,0.12,0.1392,0.0000,2344 B,1.36 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"38,805.4 ns",639.12 ns,380.33 ns,260.64,8.20,20.5078,1.7090,343936 B,199.96 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"1,888.2 ns",20.20 ns,12.02 ns,12.68,0.39,0.6199,0.0038,10384 B,6.04 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,385.8 ns,7.23 ns,4.30 ns,2.59,0.08,0.0439,0.0000,736 B,0.43 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,controlled,"5,523.2 ns",63.10 ns,37.55 ns,37.10,1.14,0.7935,0.2594,13360 B,7.77 +RenderHeddle,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,148.1 ns,5.21 ns,3.10 ns,1.00,0.03,0.1147,0.0000,1920 B,1.00 +RenderHeddleUtf8,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,160.4 ns,2.34 ns,1.39 ns,1.08,0.02,0.0124,0.0000,208 B,0.11 +RenderHeddleTextWriter,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,141.6 ns,13.85 ns,8.24 ns,0.96,0.06,0.0119,0.0000,200 B,0.10 +RenderFluid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,491.4 ns,21.52 ns,12.81 ns,3.32,0.10,0.1440,0.0000,2424 B,1.26 +RenderScriban,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"38,709.8 ns","3,542.32 ns","2,107.98 ns",261.55,14.45,20.5078,1.8311,344024 B,179.18 +RenderDotLiquid,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"1,925.7 ns",37.68 ns,22.42 ns,13.01,0.29,0.6218,0.0038,10464 B,5.45 +RenderHandlebars,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,461.2 ns,4.16 ns,2.48 ns,3.12,0.06,0.0486,0.0000,816 B,0.42 +RenderRazor,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111111111111111111111111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 10.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,3,Default,Default,Default,Default,Default,Default,16,3,idiomatic,"4,833.0 ns",49.84 ns,29.66 ns,32.65,0.67,0.7858,0.2594,13200 B,6.88 diff --git a/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TrivialSubstitutionBenchmarks-report.html b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TrivialSubstitutionBenchmarks-report.html new file mode 100644 index 00000000..d0d141e3 --- /dev/null +++ b/docs/benchmarks/2026-08-08/dotnet/results/Heddle.Benchmarks.Dotnet.Bench.TrivialSubstitutionBenchmarks-report.html @@ -0,0 +1,47 @@ + + + + +Heddle.Benchmarks.Dotnet.Bench.TrivialSubstitutionBenchmarks-20260808-014308 + + + + +
      
      +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8894/25H2/2025Update/HudsonValley2)
      +AMD Ryzen 9 9950X 4.30GHz, 1 CPU, 32 logical and 16 physical cores
      +.NET SDK 10.0.302
      +  [Host]   : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +  ShortRun : .NET 10.0.10 (10.0.10, 10.0.1026.32716), X64 RyuJIT x86-64-v4
      +
      +
      Job=ShortRun  IterationCount=3  LaunchCount=3  
      +WarmupCount=3  
      +
      + + + + + + + + + + + + + + + + + + + + +
      Method TrackMean ErrorStdDevRatioRatioSDGen0Gen1AllocatedAlloc Ratio
      RenderHeddlecontrolled149.0 ns7.75 ns4.61 ns1.000.040.1028-1720 B1.00
      RenderHeddleUtf8controlled161.9 ns2.65 ns1.58 ns1.090.030.0124-208 B0.12
      RenderHeddleTextWritercontrolled142.7 ns13.55 ns8.06 ns0.960.060.0119-200 B0.12
      RenderFluidcontrolled482.9 ns20.47 ns12.18 ns3.240.120.1392-2344 B1.36
      RenderScribancontrolled38,805.4 ns639.12 ns380.33 ns260.648.2020.50781.7090343936 B199.96
      RenderDotLiquidcontrolled1,888.2 ns20.20 ns12.02 ns12.680.390.61990.003810384 B6.04
      RenderHandlebarscontrolled385.8 ns7.23 ns4.30 ns2.590.080.0439-736 B0.43
      RenderRazorcontrolled5,523.2 ns63.10 ns37.55 ns37.101.140.79350.259413360 B7.77
      RenderHeddleidiomatic148.1 ns5.21 ns3.10 ns1.000.030.1147-1920 B1.00
      RenderHeddleUtf8idiomatic160.4 ns2.34 ns1.39 ns1.080.020.0124-208 B0.11
      RenderHeddleTextWriteridiomatic141.6 ns13.85 ns8.24 ns0.960.060.0119-200 B0.10
      RenderFluididiomatic491.4 ns21.52 ns12.81 ns3.320.100.1440-2424 B1.26
      RenderScribanidiomatic38,709.8 ns3,542.32 ns2,107.98 ns261.5514.4520.50781.8311344024 B179.18
      RenderDotLiquididiomatic1,925.7 ns37.68 ns22.42 ns13.010.290.62180.003810464 B5.45
      RenderHandlebarsidiomatic461.2 ns4.16 ns2.48 ns3.120.060.0486-816 B0.42
      RenderRazoridiomatic4,833.0 ns49.84 ns29.66 ns32.650.670.78580.259413200 B6.88
      + + diff --git a/docs/benchmarks/2026-08-08/go/bench-coldparse-20260722.txt b/docs/benchmarks/2026-08-08/go/bench-coldparse-20260722.txt new file mode 100644 index 00000000..18885c0c --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/bench-coldparse-20260722.txt @@ -0,0 +1,45 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor +BenchmarkColdParse/stdlib-text-32 30027 39946 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31117 39138 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30806 40147 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29354 41055 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 28920 41257 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29134 41492 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29766 40316 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29216 40353 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29986 40434 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 28166 41460 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 28969 41416 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29230 40589 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29748 40597 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29160 40896 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29319 41056 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29469 40154 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30477 40183 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29944 40305 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29619 40520 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29974 40574 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-html-32 180472 6094 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 175222 6743 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 202586 6237 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 199506 6363 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 184910 6406 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 195705 6559 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 199135 6229 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 190362 6479 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 201326 6474 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 187563 6495 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 192411 6632 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 201589 6523 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 192201 6367 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 170646 6446 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 196143 6479 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 183381 6508 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 201074 6436 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 200470 6261 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 172131 6536 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 192820 6470 ns/op 10096 B/op 147 allocs/op +PASS diff --git a/docs/benchmarks/2026-08-08/go/bench-coldparse-20260802.txt b/docs/benchmarks/2026-08-08/go/bench-coldparse-20260802.txt new file mode 100644 index 00000000..0412f96d --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/bench-coldparse-20260802.txt @@ -0,0 +1,61 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor +BenchmarkColdParse/stdlib-text-32 30336 40664 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30146 40004 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30667 39426 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30402 39830 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30404 40810 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 28723 40745 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30006 39728 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30426 39727 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29166 41201 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30656 39504 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 28273 40877 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30452 39701 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30009 39619 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29612 40942 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29664 40698 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29158 41035 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29964 39716 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29727 40527 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29847 40376 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30490 39644 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29898 40518 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30368 39683 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29494 39621 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29414 40998 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29644 40222 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 28965 40435 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 29498 40017 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30102 40410 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-html-32 204636 7104 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 194073 6849 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 183098 7071 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 159997 6776 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 198939 6777 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 186478 6868 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 186615 6902 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 165216 6973 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 175854 6973 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 196506 7285 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 148530 7201 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 175339 7028 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 198597 7088 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 192260 6835 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 200083 7152 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 192772 6984 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 181664 7016 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 173610 7021 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 158013 7312 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 181588 7222 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 193792 7258 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 150681 7062 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 173196 6831 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 186706 7156 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 183920 6860 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 173973 6599 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 188278 6662 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 176265 6929 ns/op 10096 B/op 147 allocs/op +PASS diff --git a/docs/benchmarks/2026-08-08/go/bench-coldparse-20260803.txt b/docs/benchmarks/2026-08-08/go/bench-coldparse-20260803.txt new file mode 100644 index 00000000..900aae4d --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/bench-coldparse-20260803.txt @@ -0,0 +1,61 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor +BenchmarkColdParse/stdlib-text-32 30418 39142 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30898 39214 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31492 38784 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30759 39408 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31143 38711 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31191 38640 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30589 39324 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31056 39048 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31297 38804 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31056 38697 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31052 38312 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30733 39328 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31321 39481 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30560 39370 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31495 39176 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30697 39065 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30944 38962 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31183 38533 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30675 39035 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30510 39346 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30501 40031 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30884 38764 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30589 39403 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30516 38772 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30450 39848 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30008 39292 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31042 39039 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31177 38465 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-html-32 201734 6571 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 194721 6551 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 207075 6814 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 196412 6422 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 206642 6490 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 169912 6806 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 196815 6734 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 202176 6631 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 204036 6424 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 191745 6709 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 194983 6564 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 188853 6838 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 204330 6750 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 184845 6453 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 173958 6314 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 184052 6567 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 179539 6514 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 163537 6643 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 202210 6608 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 177381 6773 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 193480 6613 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 205466 6523 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 149504 6997 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 207043 6911 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 196606 6922 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 181147 6788 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 205140 6678 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 146910 6975 ns/op 10096 B/op 147 allocs/op +PASS diff --git a/docs/benchmarks/2026-08-08/go/bench-coldparse-20260808.txt b/docs/benchmarks/2026-08-08/go/bench-coldparse-20260808.txt new file mode 100644 index 00000000..cdbcec51 --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/bench-coldparse-20260808.txt @@ -0,0 +1,61 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor +BenchmarkColdParse/stdlib-text-32 30926 38661 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31233 38627 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30909 38671 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31114 38698 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31178 38436 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30708 38698 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30588 38806 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31138 38817 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31290 38674 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30631 38862 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31196 38494 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30736 39050 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31092 38761 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31182 38861 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31322 38365 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31340 38647 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31395 38331 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30771 39162 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31132 38975 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31230 38415 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30926 38703 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31128 38580 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31334 38471 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31220 38711 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30656 38809 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 30828 38658 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31082 38513 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-text-32 31272 38856 ns/op 46576 B/op 764 allocs/op +BenchmarkColdParse/stdlib-html-32 203283 6073 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 197580 6206 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 201295 6136 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 208274 6052 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 207115 6314 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 172341 6116 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 204250 6176 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 205292 6080 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 203028 6279 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 204180 6185 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 206458 6159 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 182149 6096 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 200377 6200 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 205093 6024 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 191929 6123 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 204360 6073 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 200725 6135 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 191883 6120 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 203616 6195 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 207850 6207 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 198230 6140 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 205768 6169 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 188858 6095 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 201484 6203 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 201903 6127 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 205653 6221 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 201178 6064 ns/op 10096 B/op 147 allocs/op +BenchmarkColdParse/stdlib-html-32 206042 5962 ns/op 10096 B/op 147 allocs/op +PASS diff --git a/docs/benchmarks/2026-08-08/go/bench-render-20260722.txt b/docs/benchmarks/2026-08-08/go/bench-render-20260722.txt new file mode 100644 index 00000000..8c825ca8 --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/bench-render-20260722.txt @@ -0,0 +1,645 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor +BenchmarkRender/controlled/composed-page/stdlib-text-32 88272 14300 ns/op 63100 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 86337 14764 ns/op 63101 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 81078 17973 ns/op 63119 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 66302 19325 ns/op 63123 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 62473 21597 ns/op 63128 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 65631 18158 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 63552 18251 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 66727 17872 ns/op 63128 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 70257 18537 ns/op 63128 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 70772 19225 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 67674 18892 ns/op 63126 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 57838 19855 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 70983 19962 ns/op 63130 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 62436 19962 ns/op 63135 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 67290 19476 ns/op 63130 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 57855 20379 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 52568 19716 ns/op 63127 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 53618 20151 ns/op 63126 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 66732 20353 ns/op 63139 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 66556 20053 ns/op 63118 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 77707 16314 ns/op 58694 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 75218 18119 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 72302 17233 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 115993 16190 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 172848 16835 ns/op 58694 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 82860 15722 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 76513 14949 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 76214 15698 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 83396 16049 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 61476 16767 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 108879 16434 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 62055 19582 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 74830 17272 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 105228 15414 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 63879 21077 ns/op 58694 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 58735 19367 ns/op 58694 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 63326 18016 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 87046 18861 ns/op 58694 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 73125 19680 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 108792 18722 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1063 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1052 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1034 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1020 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1027 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1046 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1058 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1063 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1054 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1040 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1047 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1036 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1044 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1029 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1026 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1076 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1025 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1034 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1039 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1044 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1576048 754.1 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1649535 751.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1587757 748.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1498688 782.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1576782 762.3 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1701952 725.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1592179 773.2 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1727922 710.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1551151 784.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1533090 773.9 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1594855 758.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1574493 758.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1637230 758.3 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1636028 764.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1608944 754.7 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1577457 770.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1619716 718.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1676850 745.4 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1691222 743.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1579854 756.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1039 1162061 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1018 1163878 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1054 1163530 ns/op 354905 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 979 1163611 ns/op 354907 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1042 1183758 ns/op 354908 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1042 1156355 ns/op 354908 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1024 1163707 ns/op 354904 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1050 1160409 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 997 1169774 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1039 1158388 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1048 1156038 ns/op 354898 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 975 1168201 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1036 1156284 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1015 1152993 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 988 1172831 ns/op 354911 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1056 1158009 ns/op 354906 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1012 1174541 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1056 1155891 ns/op 354904 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1040 1164402 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1059 1160695 ns/op 354904 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2364 528064 ns/op 394256 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2143 540873 ns/op 394273 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2313 525795 ns/op 394254 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2364 513123 ns/op 394251 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2184 527205 ns/op 394257 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2350 520646 ns/op 394246 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2269 528915 ns/op 394263 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2319 516003 ns/op 394249 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2061 538615 ns/op 394261 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2355 523257 ns/op 394252 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2290 527322 ns/op 394259 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2360 534004 ns/op 394264 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2125 521836 ns/op 394250 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2144 537189 ns/op 394260 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2166 541424 ns/op 394269 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2186 523632 ns/op 394252 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2361 533437 ns/op 394262 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2137 521074 ns/op 394250 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2347 527269 ns/op 394256 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2283 531632 ns/op 394252 B/op 19740 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55446 22224 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56683 21666 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54600 22216 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 57084 22002 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54804 21844 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55645 21835 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 52635 21745 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55696 22102 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55012 22332 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55246 21856 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54025 21452 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55610 21921 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53426 22172 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56781 21661 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56608 21570 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55224 21753 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55633 21823 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 50467 22118 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54474 21605 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54715 21753 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 98492 12205 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 111370 11646 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 108332 11324 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 112653 11356 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 105556 11631 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 102006 11473 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 89686 11678 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 104251 11623 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 103692 11803 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 98128 10823 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 107972 11463 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 91657 11400 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 101686 12042 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 100870 11678 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 106276 11471 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 95658 11811 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 95434 11845 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 103018 11199 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 109758 11374 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 103830 11404 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13154 91531 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12927 92954 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12990 92055 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13088 91719 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13066 91603 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13118 91653 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13074 91498 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13130 91625 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12790 93706 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12826 93099 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12962 92237 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13050 91791 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12944 92440 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12886 92883 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12878 92719 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12951 92608 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12999 92470 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13023 91957 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12936 92472 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13030 92579 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 52749 22947 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55605 22571 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55594 22468 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 51390 22708 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 51397 22926 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55082 22595 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53121 22621 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54164 22901 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53066 23177 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54662 22829 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 56544 22729 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 50588 22878 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53365 22643 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 51788 23210 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55396 22619 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 50816 22659 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 47415 22965 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53858 22179 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54808 23116 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 52441 22855 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59950 20490 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59558 20440 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57060 20855 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59583 20168 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 55215 20847 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56922 20520 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60372 20446 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60375 20676 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58148 20734 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57974 20738 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58756 20675 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58873 20590 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59481 20237 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58146 20466 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58868 20124 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60140 20959 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 55198 20744 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59602 20548 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59122 20587 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 55741 20743 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 101613 10802 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 116311 10356 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 118128 10742 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 105142 10669 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 106207 10587 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117784 10203 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 119288 10471 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117432 10613 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117829 10486 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 114501 10948 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 115686 10422 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 115856 10279 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 119691 10497 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 114933 10674 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 119337 10710 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 116571 10406 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 118746 10499 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 121798 10525 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 109747 10636 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 119950 10240 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 100929 11509 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105547 11516 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104800 11455 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102012 11734 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104946 11547 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99960 11457 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103292 11498 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 101259 11561 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105609 11551 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104492 11520 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105802 11457 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105591 11566 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104761 11496 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103612 11543 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 106065 11678 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103759 11749 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104860 11611 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 101054 11599 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105055 11583 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103796 11506 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 629662 1925 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 583600 1920 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 565171 1868 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 716101 1929 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 676154 1898 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 579799 1888 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 575318 1890 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 680322 1931 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 703226 1947 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 675812 1872 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 535228 1912 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 709861 1861 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 703651 1893 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 692492 1890 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 708319 1864 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 710185 1957 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 700450 1882 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 700569 1868 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 706946 1932 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 696560 1858 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7487829 ns/op 4103259 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7419631 ns/op 4103246 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7383461 ns/op 4103228 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7590680 ns/op 4103280 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7534560 ns/op 4103244 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7403549 ns/op 4103253 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7425839 ns/op 4103242 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7399765 ns/op 4103240 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7445591 ns/op 4103244 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7363067 ns/op 4103246 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7450011 ns/op 4103265 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 164 7305748 ns/op 4103222 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7404747 ns/op 4103218 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7563022 ns/op 4103288 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7436655 ns/op 4103186 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7358269 ns/op 4103237 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7414357 ns/op 4103204 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7548462 ns/op 4103276 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7556494 ns/op 4103253 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7369839 ns/op 4103264 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 856 1456647 ns/op 2660773 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 878 1382877 ns/op 2660718 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 818 1385565 ns/op 2660729 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 852 1404534 ns/op 2660707 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 831 1380188 ns/op 2660756 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 828 1376406 ns/op 2660719 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 890 1411018 ns/op 2660696 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 828 1433456 ns/op 2660757 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 771 1374116 ns/op 2660797 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 889 1390740 ns/op 2660746 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 904 1346494 ns/op 2660757 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 765 1439935 ns/op 2660748 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 745 1462708 ns/op 2660683 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 769 1437080 ns/op 2660776 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 850 1439433 ns/op 2660838 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 816 1406035 ns/op 2660759 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 805 1352131 ns/op 2660743 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 879 1391786 ns/op 2660757 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 800 1421375 ns/op 2660723 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 939 1375047 ns/op 2660704 B/op 50007 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 71708 17303 ns/op 63110 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 77808 19236 ns/op 63122 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 78709 17720 ns/op 63112 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 75835 17247 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 70083 17474 ns/op 63117 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 74637 18476 ns/op 63117 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 80232 16074 ns/op 63109 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 61426 17654 ns/op 63123 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 69619 17096 ns/op 63120 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 63822 17568 ns/op 63105 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 70976 16717 ns/op 63102 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 69615 16928 ns/op 63098 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 79171 16717 ns/op 63108 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 69409 17443 ns/op 63120 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 70756 17078 ns/op 63110 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 68677 16809 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 68846 16772 ns/op 63115 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 78320 16746 ns/op 63119 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 66792 17914 ns/op 63116 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 58555 20673 ns/op 63120 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 219228 4740 ns/op 58686 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 223214 4949 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 239889 4615 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 202178 5386 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 291265 4926 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 254676 5321 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 269433 4605 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 269677 4510 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 256196 4935 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 348746 4762 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 318680 4767 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 359481 4353 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 275542 4984 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 355640 4350 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 249388 4459 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 339253 4501 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 356570 4542 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 238641 4420 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 353168 4378 ns/op 58687 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 245260 4906 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1020 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1015 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1026 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1040 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1027 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1024 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1028 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1029 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1023 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1036 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1014 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1023 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1006 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1049 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1013 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1015 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1023 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1019 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1019 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1014 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1764058 675.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1801506 659.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1820880 666.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1788652 657.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1779603 668.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1780938 667.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1797544 661.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1830372 669.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1800868 660.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1717701 676.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1848262 653.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1741414 678.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1799053 671.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1861142 654.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1776931 676.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1820452 662.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1801618 660.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1834082 669.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1757240 681.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1789428 667.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1051 1165445 ns/op 395879 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1045 1156429 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1054 1148991 ns/op 395878 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1039 1157903 ns/op 395879 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1051 1163992 ns/op 395881 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1038 1166481 ns/op 395888 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1045 1161119 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 999 1157861 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1041 1148994 ns/op 395878 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 964 1165554 ns/op 395880 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 991 1165119 ns/op 395889 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 979 1163442 ns/op 395879 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1033 1153101 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1003 1176710 ns/op 395878 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1010 1158261 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1044 1167522 ns/op 395875 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1034 1161839 ns/op 395878 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1036 1183956 ns/op 395886 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1035 1159901 ns/op 395890 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1045 1155162 ns/op 395881 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1497 793453 ns/op 874670 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1581 774236 ns/op 874667 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1584 796013 ns/op 874670 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1561 773113 ns/op 874657 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1599 773852 ns/op 874671 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1591 801842 ns/op 874663 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1431 790333 ns/op 874673 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1566 797574 ns/op 874679 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1584 800652 ns/op 874673 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1542 804925 ns/op 874674 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1552 772889 ns/op 874660 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1550 825635 ns/op 874692 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1586 768469 ns/op 874652 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1582 768548 ns/op 874665 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1495 798594 ns/op 874701 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1548 803808 ns/op 874693 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1561 800357 ns/op 874666 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1560 801857 ns/op 874671 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1566 767786 ns/op 874669 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1552 820451 ns/op 874677 B/op 34740 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55479 21789 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54387 21744 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55566 21856 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56564 21638 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53634 21883 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54018 21863 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54246 21611 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55528 21789 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54984 21973 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56181 21599 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54374 22275 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56419 21825 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55699 21812 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56049 21657 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55416 21771 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56211 21918 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56359 21693 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56040 22147 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54760 21744 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54910 21918 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 89518 13088 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 100556 12618 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 96921 12384 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 100442 12252 ns/op 20417 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 99916 12836 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 86136 13225 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 100676 12468 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 90264 12949 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 97281 12843 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 96198 12978 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 90398 12500 ns/op 20417 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 91800 12760 ns/op 20417 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 81535 13071 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 100788 12788 ns/op 20417 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 100302 12555 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 89521 13054 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 83690 13256 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 96266 12588 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 99346 12781 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 92250 12708 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12882 92809 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12882 93080 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12943 92557 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12924 92713 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12817 93477 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12842 93324 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12729 93836 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12706 94372 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12956 93197 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12633 94531 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12950 92664 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 13035 92614 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 13047 92352 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12958 92717 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12900 92800 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12816 93831 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12742 93844 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12868 93034 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12973 92427 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12894 92839 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33748 35574 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33543 37198 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34209 36294 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33577 35137 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34538 35281 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32898 35774 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33698 35739 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33502 35700 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34470 35340 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34009 35237 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 31424 35972 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32330 35935 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34340 35874 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34250 35927 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33646 34938 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33000 35982 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 35078 35487 ns/op 46215 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34341 35704 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34683 35163 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34321 35273 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55188 21466 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56088 21575 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55844 21609 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 57168 21481 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56154 21766 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55092 21790 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56154 21780 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55251 21258 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56931 21313 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56500 21767 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 53096 21733 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55177 21911 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54802 21685 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 52964 21774 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55258 21685 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 57147 21614 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56977 21581 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56846 21758 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54978 21592 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55987 21654 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 112351 10204 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 117346 10189 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122685 10002 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122271 9943 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 119847 10174 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 116352 10196 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 117176 10245 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 124443 9939 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 116583 10376 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 121014 10371 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 117870 10280 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 123146 10158 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 115965 10209 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 123300 10101 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 116911 10280 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122780 10273 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 114873 10220 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122779 10242 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 113761 10016 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 113257 10306 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105471 11401 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100675 11699 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100710 11526 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103700 11471 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105399 11506 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105687 11530 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 99636 11658 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104194 11580 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 99387 11584 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104035 11456 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105745 11417 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104692 11638 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101838 11602 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 106062 11473 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104959 11572 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 98923 11640 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105068 11380 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104658 11578 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 99759 11563 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105364 11635 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 463557 2564 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 522313 2479 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 503914 2499 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 511124 2524 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 509155 2546 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 514252 2417 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 510661 2447 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 521565 2494 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 502498 2442 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 467828 2533 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 515324 2479 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 515416 2506 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 475844 2506 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 505278 2439 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 509175 2506 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 491715 2504 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 505732 2420 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 507742 2425 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 505437 2491 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 499030 2466 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7338032 ns/op 4176951 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7350092 ns/op 4176952 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7312991 ns/op 4176944 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7408577 ns/op 4176966 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7347097 ns/op 4176972 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7328003 ns/op 4176940 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7432342 ns/op 4177009 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7344575 ns/op 4176940 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7316242 ns/op 4176954 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7338901 ns/op 4176969 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7400307 ns/op 4177044 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7467052 ns/op 4177017 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7431672 ns/op 4177017 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7383324 ns/op 4177011 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7325473 ns/op 4176970 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7375753 ns/op 4176994 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7444964 ns/op 4176982 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7451801 ns/op 4176941 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7378485 ns/op 4176981 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7314622 ns/op 4176971 B/op 124852 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 730 1594406 ns/op 3301244 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 768 1611586 ns/op 3301250 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 744 1631019 ns/op 3301245 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 760 1642816 ns/op 3301296 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 697 1644054 ns/op 3301199 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 748 1628807 ns/op 3301293 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 690 1678693 ns/op 3301195 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 750 1606670 ns/op 3301263 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 726 1644449 ns/op 3301320 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 720 1608363 ns/op 3301263 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 734 1642493 ns/op 3301258 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 715 1605936 ns/op 3301238 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 751 1583905 ns/op 3301240 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 728 1613367 ns/op 3301308 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 738 1640979 ns/op 3301234 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 735 1624199 ns/op 3301218 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 771 1598955 ns/op 3301256 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 764 1613723 ns/op 3301262 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 710 1612914 ns/op 3301299 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 758 1604256 ns/op 3301210 B/op 65008 allocs/op +PASS diff --git a/docs/benchmarks/2026-08-08/go/bench-render-20260802.txt b/docs/benchmarks/2026-08-08/go/bench-render-20260802.txt new file mode 100644 index 00000000..6247d490 --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/bench-render-20260802.txt @@ -0,0 +1,901 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor +BenchmarkRender/controlled/composed-page/stdlib-text-32 89139 13483 ns/op 63081 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 89498 14946 ns/op 63100 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 81684 14840 ns/op 63092 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 77211 15330 ns/op 63101 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 77454 15272 ns/op 63106 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 80442 15226 ns/op 63105 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 68862 16044 ns/op 63099 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88045 14959 ns/op 63092 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88556 15168 ns/op 63099 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 90211 15174 ns/op 63094 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 81520 15261 ns/op 63088 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 79644 15147 ns/op 63105 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 77518 15345 ns/op 63092 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 85808 15710 ns/op 63102 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 66687 15527 ns/op 63091 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 81684 15241 ns/op 63095 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 83697 14760 ns/op 63100 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 71238 15188 ns/op 63094 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 86005 14383 ns/op 63096 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 80526 15323 ns/op 63103 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 72844 14884 ns/op 63098 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 86269 16121 ns/op 63095 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 78955 14905 ns/op 63102 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 81794 15048 ns/op 63108 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 86160 15514 ns/op 63101 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 76374 16051 ns/op 63102 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 85316 15218 ns/op 63092 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 75340 15485 ns/op 63099 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 205832 9786 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 178836 9445 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 126480 11749 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 182590 9488 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 309882 8869 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 183613 9183 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 195884 9457 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 141866 9396 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 189585 9532 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 98886 11835 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 109406 13154 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 152377 8185 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 94377 13195 ns/op 58695 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 91486 11615 ns/op 58694 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 107306 11642 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 194634 11634 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 120774 11859 ns/op 58694 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 250538 9970 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 216997 10945 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 92892 11700 ns/op 58694 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 134920 10266 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 133504 10744 ns/op 58694 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 126990 10331 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 367882 9159 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 192246 13924 ns/op 58695 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 205546 13050 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 120927 9171 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 103990 10616 ns/op 58695 B/op 23 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1024 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1018 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1017 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1010 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1019 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1016 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1026 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1013 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1012 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1033 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1027 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1022 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1028 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1043 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1036 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1021 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1029 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1036 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1018 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1011 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1019 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1012 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1003 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1036 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1009 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1006 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1012 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1008 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1724530 682.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1755414 679.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1711062 704.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1770758 693.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1730958 707.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1706458 688.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1778025 702.9 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1753585 688.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1766506 665.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1756266 708.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1798486 668.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1673278 692.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1766433 674.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1708257 704.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1714173 708.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1653424 734.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1772678 679.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1754614 686.8 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1710975 696.1 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1733953 688.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1739072 698.5 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1739613 681.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1809596 660.5 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1652348 707.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1763127 680.2 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1733254 689.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1646162 706.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1784396 673.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1022 1186118 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 991 1197775 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1014 1185168 ns/op 354898 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1016 1188511 ns/op 354898 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1011 1182585 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1000 1185538 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1016 1179950 ns/op 354898 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1024 1178530 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1027 1186558 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1009 1187063 ns/op 354904 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1011 1188580 ns/op 354897 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1014 1192750 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1028 1191019 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1026 1180317 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1015 1193983 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1015 1183316 ns/op 354896 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 973 1187300 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1000 1189922 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1005 1203337 ns/op 354905 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1012 1197420 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 998 1187864 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1028 1188158 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1012 1182812 ns/op 354898 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1021 1182047 ns/op 354896 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 985 1182356 ns/op 354897 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1034 1186345 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1029 1183751 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1026 1183563 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2348 535107 ns/op 394251 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2200 524563 ns/op 394246 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2228 520834 ns/op 394247 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2330 532843 ns/op 394250 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2036 528667 ns/op 394255 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2270 525642 ns/op 394246 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2098 534111 ns/op 394257 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2204 530144 ns/op 394262 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2306 525473 ns/op 394251 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2098 530121 ns/op 394252 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2298 524747 ns/op 394252 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2373 529888 ns/op 394245 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2218 538691 ns/op 394255 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2313 530758 ns/op 394261 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2332 542332 ns/op 394265 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2270 524341 ns/op 394251 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2090 535093 ns/op 394256 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2364 530387 ns/op 394248 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2292 521305 ns/op 394247 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2313 530088 ns/op 394253 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2343 529260 ns/op 394250 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2184 524336 ns/op 394263 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 1951 538043 ns/op 394252 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2356 519946 ns/op 394253 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2328 526185 ns/op 394245 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2353 523360 ns/op 394247 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2299 523051 ns/op 394255 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2317 524946 ns/op 394253 B/op 19740 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56439 21816 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53918 21869 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55590 21707 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55504 21785 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54376 21666 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55034 21704 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55335 21694 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56754 21661 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54124 22014 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55687 21621 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55668 21457 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55807 21703 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54123 21813 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55862 21672 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54738 21785 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54574 22111 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54741 22118 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55682 21927 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54739 22053 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54910 21695 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54920 21720 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54836 21732 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53619 22015 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54368 21766 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53019 21873 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 52678 22051 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54856 21727 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54477 21929 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 106328 11486 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 114939 11209 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 98842 11283 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 117913 10582 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 101322 11312 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 106970 11500 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 102579 11511 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 102627 11119 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 93199 11403 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 103849 11027 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 113847 11084 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 120357 10720 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 122073 10994 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 111166 11549 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 111942 11104 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 102487 11391 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 118052 11244 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 120090 11039 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 112908 10890 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 115234 10728 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 114856 11321 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 102782 10994 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 114205 10972 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 109798 10996 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 100296 11103 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 102613 11710 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 102648 11189 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 117842 10848 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12648 95169 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12656 95122 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12740 94744 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12711 94509 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12602 94786 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12609 94932 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12591 95329 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12745 94106 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12638 95177 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12738 94039 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12705 94952 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12664 94360 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12435 96468 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12555 95330 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12663 94561 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12612 95271 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12507 95755 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12632 95415 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12730 94599 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12602 95365 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12826 93427 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12704 94131 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12636 94561 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12676 94947 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12729 94108 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12727 94345 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12759 94081 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12789 93639 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 56217 22158 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54492 22138 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53374 22310 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54256 22267 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55141 22696 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53338 22109 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53949 22412 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54372 22341 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54111 22245 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 52826 22815 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53276 22277 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55792 22387 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54999 22105 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53826 22719 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53274 22462 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55275 22543 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53485 22649 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 51654 22447 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53404 22128 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 52726 22668 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 51831 22748 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53462 23064 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54670 22055 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54930 22298 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53319 22412 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 50265 22901 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54430 22270 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53520 22949 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56619 21001 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57718 20827 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57390 20719 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58533 20534 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57339 20502 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58518 20776 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 55366 20857 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 53732 21189 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57822 20703 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58408 20665 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59770 20799 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59278 20613 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58712 20722 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57259 21095 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59302 20923 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58424 20647 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56808 21009 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57240 20697 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56124 21086 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58381 20720 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57375 20837 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 55549 20727 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56144 21303 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56731 21082 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56670 20881 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59181 20827 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56971 20882 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56588 20685 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 114999 10356 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 121648 10505 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117865 10471 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117590 10533 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 121885 10319 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 118395 10632 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 105015 10390 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 123422 10484 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 116409 10567 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 119583 10450 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 114160 10418 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 109494 10446 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 108868 10152 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 114514 10454 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 114206 10535 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 114795 10203 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 122624 10248 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117249 10485 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 121866 10364 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 120375 10194 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 116340 10493 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117046 10540 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117855 10400 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 108697 10484 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 114177 10330 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 120584 10118 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 111906 10548 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 122566 10218 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103197 11893 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 100305 11723 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102542 11679 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 100192 11926 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102267 11818 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99990 11825 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105578 11774 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99306 11834 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 101613 11845 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99937 11812 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99240 11894 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 100890 11902 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 100132 11867 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99260 11897 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104170 11846 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99925 11869 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 97550 11904 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 98592 11851 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104139 11756 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102634 11987 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99099 11844 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 100584 11916 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99452 12019 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 98971 12043 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99354 11861 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 98377 12016 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 101260 12027 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 100450 11948 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 713538 1899 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 678852 1886 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 675705 1799 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 697369 1869 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 684856 1875 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 560352 1853 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 684118 1851 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 739557 1912 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 652758 1827 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 712233 1836 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 683650 1893 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 561138 1839 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 714234 1874 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 719091 1835 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 671752 1876 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 690289 1836 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 629500 1843 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 698770 1816 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 674793 1796 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 733280 1828 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 707367 1799 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 707888 1838 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 595030 1860 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 710071 1862 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 678042 1832 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 689250 1867 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 727161 1834 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 671305 1859 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7466671 ns/op 4103133 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7547525 ns/op 4103190 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7475778 ns/op 4103217 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7551771 ns/op 4103157 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7495212 ns/op 4103181 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7510453 ns/op 4103180 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7562053 ns/op 4103168 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7523839 ns/op 4103188 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7591237 ns/op 4103187 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7541791 ns/op 4103183 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 156 7605969 ns/op 4103183 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7657675 ns/op 4103207 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7558856 ns/op 4103192 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7519426 ns/op 4103208 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 156 7592024 ns/op 4103231 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7533292 ns/op 4103190 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7550494 ns/op 4103198 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7650645 ns/op 4103207 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7582371 ns/op 4103195 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7560852 ns/op 4103190 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 156 7644267 ns/op 4103206 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 156 7651673 ns/op 4103211 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7659579 ns/op 4103157 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 154 7623940 ns/op 4103245 B/op 124852 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7656111 ns/op 4103140 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7603605 ns/op 4103183 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7532099 ns/op 4103197 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7564793 ns/op 4103233 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 826 1425592 ns/op 2660762 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 840 1417270 ns/op 2660741 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 898 1498687 ns/op 2660765 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 834 1455081 ns/op 2660801 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 932 1409971 ns/op 2660810 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 921 1430776 ns/op 2660769 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 770 1450388 ns/op 2660761 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 744 1460095 ns/op 2660757 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 865 1496588 ns/op 2660793 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 757 1505148 ns/op 2660834 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 813 1427241 ns/op 2660755 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 900 1436287 ns/op 2660815 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 874 1489793 ns/op 2660777 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 900 1464663 ns/op 2660742 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 786 1495415 ns/op 2660779 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 879 1524137 ns/op 2660764 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 895 1413100 ns/op 2660742 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 943 1475379 ns/op 2660802 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 805 1433217 ns/op 2660739 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 748 1466152 ns/op 2660769 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 910 1513665 ns/op 2660797 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 898 1476040 ns/op 2660759 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 745 1477558 ns/op 2660778 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 852 1437957 ns/op 2660785 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 787 1439433 ns/op 2660803 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 805 1486159 ns/op 2660723 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 858 1443337 ns/op 2660782 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 880 1473160 ns/op 2660786 B/op 50007 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 72820 20055 ns/op 63108 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 62348 21436 ns/op 63127 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 54273 23186 ns/op 63122 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 55860 21125 ns/op 63107 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 52470 21040 ns/op 63110 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 54321 20848 ns/op 63123 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 62606 18753 ns/op 63108 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 54988 23409 ns/op 63126 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 55550 19953 ns/op 63118 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 56976 21175 ns/op 63124 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 54084 21992 ns/op 63118 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 73057 19888 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 59288 20657 ns/op 63123 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 65587 20337 ns/op 63117 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 54972 21492 ns/op 63125 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 58466 20721 ns/op 63129 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 50362 21348 ns/op 63104 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 54669 21899 ns/op 63116 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 54540 22378 ns/op 63120 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 53959 21232 ns/op 63099 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 65740 20184 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 61444 22332 ns/op 63111 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 51972 23999 ns/op 63133 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 71208 21143 ns/op 63110 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 48336 21573 ns/op 63109 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 64473 21735 ns/op 63120 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 56214 21227 ns/op 63117 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 49041 24003 ns/op 63110 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 188774 6397 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 278817 5654 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 183403 5958 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 191745 6274 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 214386 5547 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 191086 5691 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 266720 5189 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 172586 6701 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 213832 5904 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 371792 5494 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 253268 5195 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 220288 5872 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 232561 5137 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 311898 6341 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 217951 5408 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 183254 5937 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 309790 5983 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 198330 6018 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 213450 5670 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 273754 5722 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 234126 5303 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 215294 5412 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 206066 5267 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 232317 5227 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 379975 5506 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 219378 5846 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 251396 5824 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 329826 5737 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1034 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1035 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1017 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1022 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1019 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1024 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1033 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1016 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1039 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1029 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1035 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1021 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1030 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1031 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1015 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1031 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1030 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1009 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1028 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1028 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1033 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1038 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1029 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1027 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1036 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1039 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1039 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1034 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1745322 693.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1652754 705.5 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1845350 687.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1833406 668.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1795054 668.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1765815 694.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1674650 727.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1798287 665.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1767704 674.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1756812 680.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1776210 703.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1692783 711.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1701141 699.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1678164 694.1 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1798014 676.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1613362 722.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1703211 697.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1745991 687.9 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1723990 692.9 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1705495 704.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1728726 701.9 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1720954 696.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1604922 742.7 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1758586 701.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1746164 693.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1701385 713.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1664274 711.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1754900 705.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1014 1178536 ns/op 395875 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 996 1195376 ns/op 395879 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1010 1195056 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 999 1182250 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 967 1189460 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1012 1186947 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1011 1185108 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1015 1202720 ns/op 395881 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1024 1183110 ns/op 395879 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1010 1185739 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1005 1195953 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1005 1192498 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1021 1190728 ns/op 395881 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 969 1193917 ns/op 395880 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1036 1184161 ns/op 395878 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1002 1186563 ns/op 395879 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1011 1187994 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1016 1182182 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 981 1193400 ns/op 395875 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1018 1179301 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1008 1194766 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1036 1188137 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 937 1202894 ns/op 395882 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1004 1173731 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 993 1184679 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1035 1183030 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1026 1175115 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1029 1173202 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1539 778872 ns/op 874677 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1564 789554 ns/op 874688 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1498 791166 ns/op 874681 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1568 808467 ns/op 874691 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1536 776485 ns/op 874667 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1573 772798 ns/op 874666 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1321 804984 ns/op 874687 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1531 810057 ns/op 874698 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1518 779699 ns/op 874666 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1518 795016 ns/op 874675 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1279 802934 ns/op 874661 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1572 810834 ns/op 874685 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1465 812403 ns/op 874686 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1526 797135 ns/op 874680 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1460 801525 ns/op 874675 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1512 798687 ns/op 874679 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1549 788255 ns/op 874667 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1395 801947 ns/op 874682 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1596 786041 ns/op 874673 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1502 787870 ns/op 874673 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1477 795753 ns/op 874674 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1450 806729 ns/op 874695 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1572 786224 ns/op 874669 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1560 801588 ns/op 874684 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1546 788627 ns/op 874672 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1509 797364 ns/op 874670 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1489 809635 ns/op 874674 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1513 808837 ns/op 874686 B/op 34740 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54046 22452 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53521 22600 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53872 22285 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53931 22675 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53904 22335 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53510 22800 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 51872 22837 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 52884 22430 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53930 22479 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53328 22526 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 52240 22685 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 52993 22492 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53082 22493 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54158 22496 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53511 22255 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 52902 22502 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 52050 22663 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55641 22510 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55611 22276 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56012 22175 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53852 22178 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 52082 22680 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53908 22544 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55533 22244 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53870 22104 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54303 22082 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55232 21992 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55896 22005 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 91614 13348 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 97768 13310 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 76520 13946 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 85042 13659 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 88407 12982 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 89798 13906 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 84649 12891 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 85880 13918 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 98588 13078 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 90127 13432 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 92674 13487 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 88711 13110 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 90174 13547 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 94359 13621 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 90477 13510 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 86144 13992 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 89527 13571 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 80370 13718 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 84288 14113 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 94240 13288 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 98263 13624 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 90998 13448 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 98916 13233 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 98233 12782 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 94280 13340 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 92413 13346 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 76004 13535 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 97875 13274 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12429 96415 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12507 96258 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12536 95663 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12492 95807 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12540 95563 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12495 95881 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12325 97063 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12543 95978 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12507 96027 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12450 96703 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12444 96500 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12441 95983 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12307 97135 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12420 96294 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12453 96308 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12464 96786 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12451 96561 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12428 96874 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12471 96562 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12375 97025 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12259 97434 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12495 96227 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12528 95945 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12481 95921 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12391 97019 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12374 96671 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12424 96262 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12602 95797 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32472 36551 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32635 36777 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33181 35905 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33937 35186 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33270 35993 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33475 35843 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32175 37278 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32415 36639 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33382 35922 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 31438 36524 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33496 35700 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32169 36982 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32965 36859 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 31401 36555 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32607 36112 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 31545 36500 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32428 36006 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32659 36504 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32679 36448 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34536 35329 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33163 36019 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 31551 36470 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32977 36331 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33643 36759 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33866 35314 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34366 35409 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32354 36232 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34201 35316 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56072 21611 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55515 21607 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54816 21671 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56146 21911 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55750 21773 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55718 21430 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56146 21575 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55819 21705 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56778 21794 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54711 22129 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54992 22143 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55117 21871 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55425 21750 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55250 21882 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54728 22178 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54160 21943 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56067 21707 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56474 21415 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55705 21747 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54246 21988 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54159 21979 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55094 21960 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55372 21859 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54482 22162 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54106 21771 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54015 21793 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54532 21917 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55135 21689 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122914 10508 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 118855 10288 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 115122 10441 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 111805 10417 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 111690 10690 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 118016 10453 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 120193 10312 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 111621 10332 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 112928 10068 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 116742 10239 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 121368 10302 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 113418 10296 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 110877 10619 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 116838 10446 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 121830 10457 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 110454 10366 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 115082 10229 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 119988 10272 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 117942 10436 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 107642 10427 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 116396 10495 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 112897 10426 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 112863 10640 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 96846 10820 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 105548 10565 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 120477 10203 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 108890 10624 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 108032 10609 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100623 11881 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101830 11926 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102409 11817 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103963 11877 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100508 11964 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100045 11877 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101914 11957 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 98269 11771 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103292 11778 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101702 11854 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100436 11989 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101379 11838 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102824 11861 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101610 11786 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102394 11833 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100864 11813 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 99650 11715 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 97575 11847 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101732 11763 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100203 11828 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100794 11894 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101547 11803 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103658 11694 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 99735 11728 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101706 11813 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102097 11859 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100753 11760 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 99148 11786 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 402048 2518 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 523886 2569 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 452241 2697 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 514350 2552 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 414244 2618 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 506533 2629 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 451303 2617 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 525973 2521 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 509101 2599 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 523052 2611 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 431593 2634 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 485218 2610 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 517832 2657 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 461912 2591 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 452653 2631 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 496912 2596 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 520442 2520 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 441399 2532 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 492726 2540 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 506642 2539 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 499082 2550 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 486313 2640 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 426630 2506 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 519742 2617 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 480855 2704 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 504956 2594 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 514273 2559 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 398126 2582 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7568338 ns/op 4176928 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7584204 ns/op 4176957 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7537005 ns/op 4176908 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7569982 ns/op 4176933 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7542489 ns/op 4176927 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7586980 ns/op 4176936 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7495865 ns/op 4176899 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7486138 ns/op 4176905 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7530102 ns/op 4176958 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7502287 ns/op 4176902 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7535739 ns/op 4176909 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7564866 ns/op 4176936 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7494565 ns/op 4176934 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7542578 ns/op 4176893 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7589984 ns/op 4176939 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7565784 ns/op 4176902 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 156 7659431 ns/op 4176935 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7576752 ns/op 4176934 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7578710 ns/op 4176958 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7600024 ns/op 4176918 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7638738 ns/op 4176956 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7560352 ns/op 4176921 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7599522 ns/op 4176888 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 156 7654188 ns/op 4177000 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7547829 ns/op 4176940 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7535684 ns/op 4176943 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7483303 ns/op 4176912 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7623085 ns/op 4176898 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 753 1655318 ns/op 3301230 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 636 1718282 ns/op 3301237 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 754 1708149 ns/op 3301207 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 758 1680376 ns/op 3301248 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 727 1701950 ns/op 3301255 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 672 1697265 ns/op 3301261 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 682 1662388 ns/op 3301236 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 686 1672126 ns/op 3301224 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 682 1629310 ns/op 3301234 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 716 1735134 ns/op 3301221 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 736 1769239 ns/op 3301273 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 703 1634757 ns/op 3301225 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 738 1717787 ns/op 3301235 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 727 1672457 ns/op 3301209 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 736 1652039 ns/op 3301206 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 750 1686507 ns/op 3301215 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 753 1679549 ns/op 3301230 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 712 1653823 ns/op 3301211 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 729 1647038 ns/op 3301213 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 688 1680171 ns/op 3301214 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 778 1626654 ns/op 3301260 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 639 1698525 ns/op 3301283 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 754 1734665 ns/op 3301257 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 752 1669843 ns/op 3301289 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 762 1656298 ns/op 3301251 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 754 1645513 ns/op 3301261 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 775 1590594 ns/op 3301175 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 744 1621988 ns/op 3301221 B/op 65008 allocs/op +PASS diff --git a/docs/benchmarks/2026-08-08/go/bench-render-20260803.txt b/docs/benchmarks/2026-08-08/go/bench-render-20260803.txt new file mode 100644 index 00000000..1a49d63c --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/bench-render-20260803.txt @@ -0,0 +1,901 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor +BenchmarkRender/controlled/composed-page/stdlib-text-32 87936 14575 ns/op 63103 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 87973 14352 ns/op 63100 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88900 14610 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 77265 14262 ns/op 63105 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 87975 14225 ns/op 63117 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 89482 14686 ns/op 63113 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 85586 14066 ns/op 63103 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 74378 14421 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 79420 14312 ns/op 63105 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 89491 13964 ns/op 63111 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 83252 14344 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 80506 14241 ns/op 63102 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 89763 14370 ns/op 63103 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88840 14127 ns/op 63110 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 90237 14517 ns/op 63113 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 86440 14406 ns/op 63112 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 86076 14188 ns/op 63113 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 83350 14590 ns/op 63129 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 78511 15195 ns/op 63117 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 81748 14070 ns/op 63117 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 70188 14620 ns/op 63098 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 83389 14681 ns/op 63107 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88310 14228 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 80707 14872 ns/op 63116 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 87813 14341 ns/op 63109 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 83671 15414 ns/op 63125 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 86144 14055 ns/op 63113 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 85803 14539 ns/op 63124 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 202838 5032 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 192842 6251 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 390663 5442 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 264176 6411 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 270165 6543 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 160310 6522 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 214273 6465 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 184894 5815 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 188464 6124 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 232885 6898 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 181696 8201 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 175498 6685 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 217732 8255 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 135200 7642 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 286807 6474 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 220075 8264 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 175360 6874 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 197085 5792 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 163106 10170 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 163148 7149 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 254991 7372 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 370129 7477 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 166003 8171 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 199904 7046 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 261700 6265 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 277006 7833 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 129570 10559 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 384814 7014 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1003 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1211686 990.8 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1006 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1003 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1001 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1200894 995.8 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1002 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1005 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1203723 994.2 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1004 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1204045 1005 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1006 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1005 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1202436 997.3 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1012 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1206890 992.5 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1003 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1204515 997.0 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1003 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1003 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1201262 997.1 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1211182 990.1 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1201688 998.0 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1210186 994.9 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1206246 1000 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1212142 995.2 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1003 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1007 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1682449 699.6 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1803298 669.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1863339 691.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1763713 705.0 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1781149 680.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1698790 693.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1730881 700.7 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1736268 678.6 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1771272 680.8 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1808764 678.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1772392 680.2 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1677120 717.4 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1750802 678.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1752624 689.5 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1801304 672.2 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1777695 703.6 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1685220 741.2 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1793934 680.0 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1730138 689.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1650825 711.1 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1709647 685.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1637295 711.7 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1767194 680.0 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1638204 703.8 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1743495 696.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1646314 722.2 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1768254 681.0 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1724049 702.3 ns/op 945 B/op 24 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1045 1148815 ns/op 354897 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1034 1147577 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1059 1148692 ns/op 354896 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1054 1141580 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1047 1159488 ns/op 354905 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1052 1156895 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1053 1147246 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1040 1144243 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1048 1148988 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1040 1142905 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1060 1147869 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1047 1145738 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1048 1142336 ns/op 354897 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1051 1138424 ns/op 354896 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1056 1153752 ns/op 354898 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1056 1149287 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1051 1153618 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1034 1155372 ns/op 354905 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1051 1148720 ns/op 354897 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1053 1142504 ns/op 354897 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1054 1143753 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1046 1159543 ns/op 354905 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1040 1157394 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1057 1146888 ns/op 354896 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1057 1142191 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1062 1165810 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1060 1147115 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1045 1147342 ns/op 354904 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2346 511427 ns/op 394255 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2382 510294 ns/op 394247 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2323 518519 ns/op 394260 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2359 512818 ns/op 394255 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2295 515245 ns/op 394260 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2356 511238 ns/op 394253 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2311 515711 ns/op 394252 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2300 513887 ns/op 394251 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2368 518668 ns/op 394243 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2253 512350 ns/op 394257 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2312 513881 ns/op 394257 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2373 518279 ns/op 394263 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2314 518186 ns/op 394260 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2307 513677 ns/op 394251 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2248 514317 ns/op 394250 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2354 510905 ns/op 394251 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2358 511175 ns/op 394252 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2226 513637 ns/op 394254 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2270 516014 ns/op 394254 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2330 510778 ns/op 394248 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2385 516788 ns/op 394254 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2313 513509 ns/op 394248 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2364 522846 ns/op 394263 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2262 515588 ns/op 394252 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2401 515966 ns/op 394257 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2350 511602 ns/op 394249 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2356 513555 ns/op 394262 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2294 512976 ns/op 394249 B/op 19740 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56259 21465 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56283 21543 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56565 21441 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55951 21439 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55731 21446 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55210 21340 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56073 21312 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56043 21461 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56346 21400 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56193 21660 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56326 21411 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56106 21597 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56199 21453 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56827 21684 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56460 21448 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56054 21578 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56474 21232 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56742 21266 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56518 21279 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54855 21360 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 56505 21516 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54057 22324 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 52879 22403 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55464 21888 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55820 22008 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 55045 21920 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54765 22198 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54128 21868 ns/op 12582 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 115496 10556 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 112572 11165 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 115088 11059 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 93048 12776 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 101949 11583 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 106917 12098 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 121566 11850 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 89473 12210 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 105918 11441 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 109262 11926 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 89656 12236 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 92878 11831 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 111504 11573 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 108430 11608 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 106285 11683 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 107014 11117 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 122565 11444 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 115350 10876 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 119646 11913 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 107582 11149 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 113316 11676 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 115530 11008 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 115833 11582 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 94441 12180 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 117660 11562 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 117081 11631 ns/op 17457 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 124095 11190 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 100468 11554 ns/op 17456 B/op 314 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13040 91815 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12928 92645 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13029 91946 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13126 91926 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13005 92021 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12946 92485 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13066 91733 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13029 91871 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13040 91875 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13062 92103 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13098 91395 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12957 92373 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13008 92232 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12858 93060 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13044 92026 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13022 91969 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13069 92147 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12886 93101 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13076 91676 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13046 92448 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13111 92001 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12930 92748 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13122 91445 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13069 91760 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13087 91972 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13098 91609 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 13123 91389 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12927 92422 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55350 22765 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54457 22531 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55387 22437 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55497 22669 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54242 22444 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55918 22597 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 50581 22445 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55842 22152 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 52813 22524 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53992 22122 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54380 22453 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55677 21999 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54246 22203 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 52815 22419 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53058 21977 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54260 22252 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 50018 22664 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 56431 21924 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 51297 22305 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55460 21933 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53364 22298 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 52942 22140 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55008 22048 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55498 22174 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 52659 22525 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53743 22471 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54806 22276 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 52844 22294 ns/op 23798 B/op 606 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59614 20130 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58621 20254 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59935 20279 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59868 20444 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58783 20223 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58066 20186 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59192 20165 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59864 20423 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59263 20421 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58722 20348 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60172 20050 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59854 20258 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59290 20196 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58608 20330 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60166 20062 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57627 20439 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60026 20304 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59774 20240 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59677 20292 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60152 20107 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59169 20100 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58515 20191 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60117 20072 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 58081 20190 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60091 20201 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 59442 20194 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60406 19977 ns/op 13118 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 60238 19936 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 111174 10294 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 111474 10356 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124820 10505 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 110637 10425 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 122280 10259 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 105799 10832 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 122424 10469 ns/op 12940 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 119389 10498 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 119864 10564 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124431 10280 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124201 10436 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 119625 10546 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 112532 10106 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117390 10408 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117289 10240 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 123876 10057 ns/op 12940 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 118752 10682 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 106230 10484 ns/op 12940 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 114056 10568 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 115077 10631 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 109880 10151 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 119810 10670 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 113097 10513 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 112297 10507 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117615 9973 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 120126 10522 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 116504 10498 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 112868 10563 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 98151 11592 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105808 11423 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103329 11542 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 101118 11450 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 100579 11497 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104841 11389 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105091 11516 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103966 11452 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103198 11511 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104654 11450 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103899 11476 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103563 11625 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104434 11556 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103354 11546 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103791 11425 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104760 11471 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104266 11467 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104536 11519 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105291 11398 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 106070 11536 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104340 11447 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105128 11576 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 105990 11433 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104338 11467 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103599 11496 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 100524 11531 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103026 11493 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104440 11473 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 721869 1843 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 679975 1840 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 715695 1838 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 663580 1821 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 722473 1802 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 632217 1856 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 718372 1834 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 724138 1791 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 714148 1873 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 706422 1845 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 726721 1849 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 724335 1814 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 585900 1810 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 719985 1920 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 715370 1847 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 702942 1889 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 709836 1824 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 696434 1816 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 712660 1809 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 700872 1860 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 640125 1839 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 641452 1869 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 713550 1855 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 736186 1845 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 619389 1859 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 718971 1782 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 713796 1888 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 694560 1809 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 163 7321939 ns/op 4103127 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7373172 ns/op 4103201 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7415477 ns/op 4103236 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7422112 ns/op 4103208 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 164 7306177 ns/op 4103182 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 163 7320244 ns/op 4103215 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7340415 ns/op 4103182 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7409639 ns/op 4103157 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7420038 ns/op 4103227 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7404134 ns/op 4103182 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7426597 ns/op 4103233 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 163 7356513 ns/op 4103203 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 163 7355188 ns/op 4103206 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7349230 ns/op 4103159 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7346124 ns/op 4103169 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7408838 ns/op 4103231 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 164 7297004 ns/op 4103179 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7359541 ns/op 4103185 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7404450 ns/op 4103173 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 163 7339087 ns/op 4103148 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7326838 ns/op 4103176 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7373711 ns/op 4103222 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7380193 ns/op 4103161 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 163 7364437 ns/op 4103176 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7397271 ns/op 4103213 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7452712 ns/op 4103232 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7356948 ns/op 4103198 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 162 7381946 ns/op 4103193 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 841 1406189 ns/op 2660795 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 837 1397802 ns/op 2660783 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 944 1362236 ns/op 2660805 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 902 1411351 ns/op 2660853 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 921 1358187 ns/op 2660787 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 849 1416175 ns/op 2660826 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 889 1393694 ns/op 2660803 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 902 1431900 ns/op 2660800 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 766 1443625 ns/op 2660813 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 811 1416329 ns/op 2660820 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 867 1412475 ns/op 2660788 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 740 1419131 ns/op 2660757 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 878 1406351 ns/op 2660722 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 962 1416016 ns/op 2660738 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 864 1393221 ns/op 2660773 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 817 1396054 ns/op 2660773 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 864 1370930 ns/op 2660738 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 844 1437138 ns/op 2660841 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 873 1388068 ns/op 2660792 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 825 1386233 ns/op 2660801 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 769 1395118 ns/op 2660773 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 822 1371961 ns/op 2660827 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 919 1399302 ns/op 2660824 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 900 1376497 ns/op 2660744 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 956 1386639 ns/op 2660798 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 921 1359027 ns/op 2660806 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 841 1446822 ns/op 2660777 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 840 1437920 ns/op 2660765 B/op 50007 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 66326 19214 ns/op 63119 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 58420 19224 ns/op 63120 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 66796 21053 ns/op 63124 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 58860 19702 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 58839 19152 ns/op 63110 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 66912 18417 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 58173 21387 ns/op 63125 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 66381 20704 ns/op 63115 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 63642 20814 ns/op 63125 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 71733 19528 ns/op 63123 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 64183 20224 ns/op 63133 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 71545 19759 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 47578 21038 ns/op 63116 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 56344 20381 ns/op 63119 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 57434 20079 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 64490 19029 ns/op 63123 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 71924 18809 ns/op 63111 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 59516 20353 ns/op 63116 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 62863 19892 ns/op 63116 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 61824 19862 ns/op 63118 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 65263 19073 ns/op 63125 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 67610 20724 ns/op 63100 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 70614 20120 ns/op 63115 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 55164 19763 ns/op 63120 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 59061 20979 ns/op 63123 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 52344 21352 ns/op 63133 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 69644 18296 ns/op 63104 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 56449 19087 ns/op 63102 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 271669 4939 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 193418 6184 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 334189 5964 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 211509 6180 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 184270 6841 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 384378 5473 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 217471 4847 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 222616 5428 ns/op 58693 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 174052 6458 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 204162 5634 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 203403 6026 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 283894 5866 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 215490 5614 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 258751 5916 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 205284 6032 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 184101 6082 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 371331 5306 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 239714 5724 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 318144 5560 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 358905 5920 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 217186 6021 ns/op 58692 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 319357 5477 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 266822 5868 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 193249 5839 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 159874 6495 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 213201 5930 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 277600 5496 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 317701 5205 ns/op 58691 B/op 23 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1006 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1201954 998.5 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1011 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1205008 996.0 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1201638 997.7 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1007 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1009 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1004 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1014 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1000 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1001 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1009 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1200038 1005 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1011 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1012 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1008 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1200906 1005 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1022 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1009 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1009 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1012 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1202226 998.2 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1008 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1004 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1006 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1014 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1000 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1009 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1837032 662.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1761724 688.4 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1869100 653.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1790590 664.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1832595 650.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1781606 686.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1772420 680.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1854720 649.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1766264 671.3 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1833487 649.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1719314 700.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1797030 682.3 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1797706 667.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1869385 642.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1806054 657.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1788452 682.0 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1662306 688.4 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1710974 685.2 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1818667 655.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1869846 668.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1796802 651.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1749724 672.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1903200 665.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1858137 654.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1865769 657.4 ns/op 945 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1866036 657.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1821982 660.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1821144 652.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1044 1148228 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1048 1150051 ns/op 395879 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1048 1144062 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1051 1151338 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1051 1147578 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1042 1148213 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1039 1157444 ns/op 395882 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1050 1145766 ns/op 395872 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1047 1148454 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1038 1151963 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1047 1145999 ns/op 395872 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1054 1147127 ns/op 395870 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1042 1146919 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1050 1158712 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 998 1175937 ns/op 395878 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1030 1151593 ns/op 395879 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1041 1150842 ns/op 395875 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1047 1152202 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1041 1146199 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1027 1152476 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1040 1156580 ns/op 395881 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1026 1153803 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1028 1153860 ns/op 395879 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1046 1150710 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1045 1145889 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1054 1145610 ns/op 395870 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1057 1150490 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1048 1145537 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1594 760293 ns/op 874678 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1580 764459 ns/op 874669 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1436 772484 ns/op 874669 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1550 784916 ns/op 874689 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1615 780026 ns/op 874684 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1604 756102 ns/op 874671 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1598 756745 ns/op 874667 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1534 764238 ns/op 874663 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1518 788576 ns/op 874676 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1610 776487 ns/op 874684 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1622 767133 ns/op 874693 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1615 761080 ns/op 874668 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1572 774479 ns/op 874673 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1502 757326 ns/op 874680 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1612 767513 ns/op 874682 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1569 801275 ns/op 874690 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1602 756275 ns/op 874669 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1580 755877 ns/op 874664 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1588 760694 ns/op 874671 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1628 766793 ns/op 874673 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1431 767713 ns/op 874680 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1603 773453 ns/op 874679 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1472 766653 ns/op 874682 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1467 774303 ns/op 874673 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1525 757618 ns/op 874673 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1616 759410 ns/op 874678 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1593 766901 ns/op 874672 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1455 798613 ns/op 874691 B/op 34740 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56534 21455 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55568 21552 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55832 21595 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55600 21482 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56340 21627 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56680 21580 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54520 21584 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56360 21376 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55880 21525 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55405 21535 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55563 21730 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56043 21418 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54856 21633 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54922 21567 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54806 21566 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56145 21562 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55866 21592 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55622 21739 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56070 21561 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56250 21578 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55478 21565 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55460 21582 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55754 21690 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55441 21878 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54918 21615 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56253 21691 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 55737 21784 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 56010 21783 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 90931 13290 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 96327 12704 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 95036 12832 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 94041 13068 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 101558 13216 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 101950 12868 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 89594 12977 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 88225 13460 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 93493 13223 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 78512 13175 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 97404 12502 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 101998 12621 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 99727 13160 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 101386 13217 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 93020 13525 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 97540 14187 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 90169 12950 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 86239 12942 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 89236 12709 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 93123 12819 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 90326 13235 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 85852 13296 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 101716 12700 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 96153 13392 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 94053 13374 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 82722 12812 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 91414 13665 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 96471 13078 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12866 93356 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12852 93362 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12938 93061 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12860 93551 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12939 92629 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12837 93223 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12874 93826 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12778 93626 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12895 92893 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12864 93082 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12914 93256 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12852 93346 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12879 93272 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12817 93934 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12834 93342 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12945 92846 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12842 93061 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12804 93506 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12859 93902 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12828 93575 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12858 93750 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12824 93517 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12984 92429 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12885 92997 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12729 94292 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12896 93211 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12933 92791 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12772 93647 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33834 36376 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32533 35861 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34244 35400 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33049 36416 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32186 35738 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33524 35320 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33314 36007 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 31573 36610 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34557 35038 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33664 35551 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32948 35673 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33004 35901 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34389 34977 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34521 34987 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32598 35808 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34068 35222 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34576 35746 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 35274 34838 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34864 35312 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34556 34979 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34509 34889 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34549 35619 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34069 36454 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34598 35475 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33757 35439 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33432 35685 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32630 36985 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32581 36083 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54537 21499 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56857 21417 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56091 21372 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54164 21474 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56552 21364 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56876 21651 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56724 21597 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 53731 21566 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56469 21517 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56793 21329 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56778 21625 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56042 21263 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 57204 21236 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56719 21210 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55968 21512 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56762 21347 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56942 21406 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56544 21317 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56198 21297 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56124 21465 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56600 21197 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56682 21482 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55242 21525 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56952 21248 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 57698 21283 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55386 21385 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 57031 21369 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 56674 21694 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122298 10161 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 119529 9891 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 121970 10085 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 124153 10115 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 123307 10072 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 125232 10264 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 116020 9897 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 115161 10257 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 119884 10297 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 113128 10219 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 113244 10203 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 121047 9858 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 108181 10196 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 123759 10091 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122719 10069 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 112359 10070 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 110738 10086 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 124588 10384 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 126054 10046 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122121 9732 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 115452 10172 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 124513 10126 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 111265 10303 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 119002 10262 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 123469 10037 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 126399 10125 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 117909 10140 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122953 9881 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102178 11416 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105118 11492 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105266 11458 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105429 11463 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103270 11474 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104587 11494 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103707 11451 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103605 11464 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105241 11391 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104895 11426 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105506 11481 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100149 11498 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104127 11500 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104311 11461 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103852 11446 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103988 11462 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104738 11450 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105141 11445 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103608 11467 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104391 11503 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 96956 11579 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103753 11485 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104292 11540 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103610 11570 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 104343 11467 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 105024 11580 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103171 11507 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102738 11555 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 509186 2480 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 506970 2571 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 471538 2543 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 453998 2449 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 479272 2506 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 409348 2620 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 516345 2463 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 421932 2579 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 458656 2585 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 519718 2532 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 514908 2504 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 491854 2561 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 454429 2611 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 522211 2576 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 511240 2497 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 497760 2485 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 512132 2535 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 518443 2565 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 489273 2501 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 525777 2479 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 521797 2551 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 515155 2585 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 463737 2515 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 512414 2577 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 513284 2511 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 508776 2470 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 519830 2586 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 526557 2534 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7479176 ns/op 4176941 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7417259 ns/op 4176944 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7334745 ns/op 4176945 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7367531 ns/op 4176913 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7344193 ns/op 4176904 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7384157 ns/op 4176945 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7350421 ns/op 4176941 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7378882 ns/op 4176947 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7368753 ns/op 4176917 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7344315 ns/op 4176887 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7369433 ns/op 4176935 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7439268 ns/op 4176989 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7354874 ns/op 4176922 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7439074 ns/op 4176983 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7361688 ns/op 4176917 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7429577 ns/op 4176923 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7402145 ns/op 4176934 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7353662 ns/op 4176934 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7358091 ns/op 4176937 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7320386 ns/op 4176941 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7432326 ns/op 4176932 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7316569 ns/op 4176924 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7402507 ns/op 4176957 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7385020 ns/op 4176938 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7388341 ns/op 4176920 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 163 7362409 ns/op 4176925 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7360781 ns/op 4176942 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 162 7340183 ns/op 4176902 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 703 1604349 ns/op 3301309 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 787 1631704 ns/op 3301319 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 735 1693603 ns/op 3301347 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 714 1688930 ns/op 3301288 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 686 1649870 ns/op 3301284 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 747 1665694 ns/op 3301266 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 756 1659251 ns/op 3301336 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 680 1690124 ns/op 3301257 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 675 1668120 ns/op 3301286 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 657 1655054 ns/op 3301250 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 711 1673004 ns/op 3301309 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 686 1643971 ns/op 3301364 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 759 1599029 ns/op 3301321 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 728 1631379 ns/op 3301287 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 686 1653226 ns/op 3301318 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 746 1616240 ns/op 3301279 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 650 1633513 ns/op 3301313 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 678 1691466 ns/op 3301328 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 699 1676248 ns/op 3301300 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 717 1597644 ns/op 3301281 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 759 1636815 ns/op 3301263 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 728 1707591 ns/op 3301299 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 771 1634587 ns/op 3301223 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 721 1659849 ns/op 3301374 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 792 1641383 ns/op 3301306 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 644 1628463 ns/op 3301350 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 730 1661496 ns/op 3301294 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 733 1654622 ns/op 3301279 B/op 65008 allocs/op +PASS diff --git a/docs/benchmarks/2026-08-08/go/bench-render-20260808.txt b/docs/benchmarks/2026-08-08/go/bench-render-20260808.txt new file mode 100644 index 00000000..3677af61 --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/bench-render-20260808.txt @@ -0,0 +1,901 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor +BenchmarkRender/controlled/composed-page/stdlib-text-32 88099 14043 ns/op 63093 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 86672 14051 ns/op 63093 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 87332 13764 ns/op 63104 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 87792 13627 ns/op 63110 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88357 14172 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 87926 13845 ns/op 63098 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 89418 13710 ns/op 63095 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88473 13653 ns/op 63102 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 86647 13708 ns/op 63102 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 79886 13943 ns/op 63108 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 89744 13838 ns/op 63103 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 84246 13688 ns/op 63100 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88671 14027 ns/op 63092 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 89180 13692 ns/op 63100 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88945 14003 ns/op 63101 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88110 13694 ns/op 63105 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 90548 13706 ns/op 63095 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88714 13957 ns/op 63101 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 90304 13833 ns/op 63106 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 82483 13736 ns/op 63099 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 82225 13855 ns/op 63110 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 89060 13956 ns/op 63108 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88392 13781 ns/op 63108 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 89100 13746 ns/op 63101 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 87598 13991 ns/op 63099 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 91087 13429 ns/op 63097 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 89950 13646 ns/op 63096 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/stdlib-text-32 88461 13776 ns/op 63095 B/op 187 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 292065 4075 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 361279 3933 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 326181 4238 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 381853 3952 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 301657 4145 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 290606 3503 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 323911 3616 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 366661 4002 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 281912 4190 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 391765 3920 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 230955 4430 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 397585 3882 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 333831 4202 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 387608 3992 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 355756 4270 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 289885 4057 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 310134 3966 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 385738 4224 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 402022 3768 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 343714 3816 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 351133 3946 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 393342 4087 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 392215 3675 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 394591 3862 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 315462 3775 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 287602 3929 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 396636 3954 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/controlled/composed-page/templ-32 373088 3889 ns/op 58687 B/op 23 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1041 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1043 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1045 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1043 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1040 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1044 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1039 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1041 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1049 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1041 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1041 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1044 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1041 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1045 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1050 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1039 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1042 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1042 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1041 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1046 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1038 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1040 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1047 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1046 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1040 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1042 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1040 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/stdlib-text-32 1000000 1041 ns/op 640 B/op 4 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1956828 615.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1930629 619.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1936358 617.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1962558 617.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1961553 615.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1925574 625.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1928467 622.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1956771 619.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1933962 617.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1951908 615.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1949199 615.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1962895 612.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1960533 616.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1905253 623.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1937892 619.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1925955 618.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1954568 619.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1944462 621.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1943595 617.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1928665 620.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1958722 619.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1943944 616.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1899722 620.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1955208 618.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1950511 613.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1917217 620.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1927390 618.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/trivial-substitution/templ-32 1959454 613.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 966 1208382 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 997 1200386 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 991 1201730 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 988 1204669 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1000 1206782 ns/op 354898 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 992 1202238 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 994 1198996 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 994 1207698 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 992 1201370 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1004 1198919 ns/op 354898 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1003 1199437 ns/op 354898 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 998 1198109 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 994 1202345 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 987 1207237 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 994 1198039 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 993 1208431 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 994 1203599 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 993 1204621 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1004 1197044 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 990 1205658 ns/op 354901 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1003 1200080 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 993 1198716 ns/op 354902 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1006 1203080 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1000 1214742 ns/op 354900 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1002 1205097 ns/op 354898 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1002 1199801 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 1005 1203010 ns/op 354899 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/stdlib-text-32 996 1201389 ns/op 354903 B/op 14749 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2366 508932 ns/op 394244 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2358 511445 ns/op 394246 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2370 511027 ns/op 394250 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2340 508191 ns/op 394243 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2370 508921 ns/op 394243 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2385 508119 ns/op 394243 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2389 509562 ns/op 394247 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2331 515797 ns/op 394252 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2366 507664 ns/op 394247 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2352 509469 ns/op 394242 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2347 508929 ns/op 394243 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2343 508409 ns/op 394246 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2380 510924 ns/op 394245 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2382 511689 ns/op 394249 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2373 513300 ns/op 394246 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2355 510650 ns/op 394257 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2319 510693 ns/op 394244 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2374 508373 ns/op 394251 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2410 508345 ns/op 394243 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2340 512765 ns/op 394244 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2329 510585 ns/op 394248 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2398 508103 ns/op 394250 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2388 509039 ns/op 394245 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2346 511837 ns/op 394249 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2300 514568 ns/op 394257 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2358 508155 ns/op 394246 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2331 512584 ns/op 394247 B/op 19740 allocs/op +BenchmarkRender/controlled/large-loop/templ-32 2404 508860 ns/op 394244 B/op 19740 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53912 22249 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54057 22207 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54247 22146 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54120 22070 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54453 22184 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54112 22243 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54020 22100 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54231 22099 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54338 22091 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54040 22111 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54300 22105 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53859 22147 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53312 22323 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53643 22132 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54648 22089 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54052 22153 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 50608 22401 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54021 22313 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53160 22259 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54252 22243 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53620 22183 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54202 22147 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 53356 22183 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54314 22015 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54784 22068 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54501 22089 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54344 22185 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/stdlib-text-32 54487 22115 ns/op 12581 B/op 149 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 116389 9778 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 127075 9744 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 125299 10061 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 127470 9581 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 124477 9582 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 125220 9716 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 126699 9568 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 122650 9601 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 125176 9708 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 123768 9711 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 125094 9648 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 126049 9590 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 124837 9534 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 125978 9679 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 123462 9676 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 125930 9723 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 124842 9692 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 126758 9800 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 119527 9830 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 125469 9834 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 120118 9734 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 125458 9727 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 125216 9651 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 125590 9747 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 126982 9587 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 124330 9706 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 126406 9606 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/mixed-page/templ-32 117900 9818 ns/op 17455 B/op 314 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12709 94248 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12680 94543 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12754 94027 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12651 94881 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12663 94572 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12729 94675 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12600 94894 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12738 94092 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12681 94638 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12682 94404 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12640 94922 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12704 94440 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12660 94566 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12718 94149 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12632 94845 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12739 94179 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12709 94438 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12693 94357 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12682 94377 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12663 94717 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12700 94377 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12746 94264 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12610 94945 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12674 94711 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12675 94625 ns/op 21378 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12734 94232 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12644 94866 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/stdlib-text-32 12734 94235 ns/op 21377 B/op 305 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55684 21542 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55242 21497 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55897 21525 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55723 21495 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 56107 21505 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 56299 21501 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55834 21480 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55742 21721 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55546 21807 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55942 21657 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55183 21644 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 53983 21644 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55844 21637 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55963 21596 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55782 21652 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54386 21663 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55950 21664 ns/op 23797 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55959 21520 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55905 21578 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54921 21602 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 56041 21554 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 56010 21773 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55516 21604 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 54828 21539 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55773 21565 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 56026 21531 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 56202 21436 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/conditional-heavy/templ-32 55956 21546 ns/op 23796 B/op 606 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57302 20869 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57358 20988 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57534 20794 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57200 20983 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57778 20853 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57908 20940 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57136 20966 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57327 20827 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57444 20801 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57078 20825 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57834 20825 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56816 20879 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57500 20914 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 55588 21020 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57345 20868 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57978 20831 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57336 20879 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 56059 20950 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57294 20915 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57866 20839 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57382 20982 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57222 20889 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57063 20903 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57768 20858 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57850 20836 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57156 20846 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57090 20831 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/stdlib-text-32 57794 20882 ns/op 13117 B/op 245 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 125978 9711 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124803 9764 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 117735 9850 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124426 9702 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 125298 9744 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124767 9903 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 125481 9690 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124783 9808 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 123180 9799 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 122853 9745 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 123343 9832 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 121932 9793 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124201 9763 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 123410 9734 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 123925 9719 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124854 9721 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 123156 9751 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 125288 9762 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 125480 9685 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124142 9825 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124300 9688 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124486 9658 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124741 9762 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 125752 9716 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124117 9863 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124093 9662 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 124891 9815 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fragment-heavy/templ-32 122493 9735 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102192 11623 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103362 11627 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 101593 11652 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102466 11611 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103387 11602 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103173 11578 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102224 11628 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103822 11574 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102735 11641 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103444 11575 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102453 11665 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102909 11576 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103704 11552 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103071 11607 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102228 11612 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 99272 11622 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103839 11604 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102712 11621 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103106 11597 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103022 11586 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102436 11593 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103318 11577 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102940 11609 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103920 11561 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 104006 11569 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 97538 11694 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 103064 11647 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/stdlib-html-32 102204 11638 ns/op 4786 B/op 155 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 692084 1720 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 711709 1731 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 700308 1754 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 704596 1733 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 707888 1723 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 710432 1729 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 703580 1708 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 717771 1726 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 706767 1728 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 715792 1728 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 707280 1729 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 698217 1737 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 737730 1765 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 691351 1753 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 708637 1703 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 705255 1731 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 706226 1725 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 706052 1721 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 666474 1712 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 693300 1719 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 708307 1740 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 716383 1713 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 698542 1726 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 691789 1719 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 722329 1731 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 709584 1713 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 718416 1718 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/fortunes-encoded/templ-32 688057 1751 ns/op 2872 B/op 38 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7459986 ns/op 4103160 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7527599 ns/op 4103159 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 158 7507674 ns/op 4103160 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7474303 ns/op 4103136 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7464780 ns/op 4103163 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7486072 ns/op 4103156 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7457231 ns/op 4103151 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7462416 ns/op 4103186 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 157 7521492 ns/op 4103176 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7490421 ns/op 4103180 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7472334 ns/op 4103152 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7476901 ns/op 4103198 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7476331 ns/op 4103180 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7426666 ns/op 4103164 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7446679 ns/op 4103168 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7508509 ns/op 4103178 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7483474 ns/op 4103147 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7445280 ns/op 4103158 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7443882 ns/op 4103180 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7439635 ns/op 4103186 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7436960 ns/op 4103161 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7443416 ns/op 4103147 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7443414 ns/op 4103132 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7428938 ns/op 4103143 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7422454 ns/op 4103134 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 160 7515994 ns/op 4103185 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7493774 ns/op 4103194 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/stdlib-html-32 159 7491437 ns/op 4103167 B/op 124851 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 949 1278993 ns/op 2660755 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 956 1268464 ns/op 2660767 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 936 1279604 ns/op 2660728 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 962 1301310 ns/op 2660734 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 834 1292131 ns/op 2660767 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 907 1266911 ns/op 2660787 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 927 1275593 ns/op 2660748 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 958 1279823 ns/op 2660754 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 961 1285718 ns/op 2660722 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 902 1287223 ns/op 2660737 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 956 1258397 ns/op 2660736 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 921 1265257 ns/op 2660751 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 956 1295344 ns/op 2660723 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 886 1296678 ns/op 2660754 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 960 1279785 ns/op 2660756 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 956 1288230 ns/op 2660777 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 956 1286745 ns/op 2660749 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 958 1275926 ns/op 2660747 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 962 1276836 ns/op 2660731 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 847 1318735 ns/op 2660733 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 930 1294471 ns/op 2660826 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 961 1284347 ns/op 2660780 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 955 1305713 ns/op 2660769 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 949 1311725 ns/op 2660729 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 943 1305551 ns/op 2660766 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 861 1308400 ns/op 2660783 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 957 1304258 ns/op 2660774 B/op 50007 allocs/op +BenchmarkRender/controlled/encoded-loop/templ-32 950 1284828 ns/op 2660804 B/op 50007 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 77698 14697 ns/op 63105 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 80251 14427 ns/op 63116 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 84747 14556 ns/op 63109 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 80089 14569 ns/op 63093 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 85215 14863 ns/op 63113 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 73192 14720 ns/op 63106 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 72074 15396 ns/op 63111 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 70620 15060 ns/op 63121 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 83139 14898 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 83047 14775 ns/op 63120 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 89280 14625 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 82118 14317 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 89179 14100 ns/op 63107 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 78349 15102 ns/op 63114 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 83737 14402 ns/op 63106 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 83931 14122 ns/op 63109 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 84016 14863 ns/op 63109 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 87588 14375 ns/op 63103 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 77806 15206 ns/op 63120 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 81760 15494 ns/op 63095 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 85635 14955 ns/op 63116 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 81076 14292 ns/op 63117 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 87889 14778 ns/op 63110 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 80631 15133 ns/op 63111 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 85995 14775 ns/op 63109 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 87646 14786 ns/op 63115 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 79886 14913 ns/op 63112 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/stdlib-text-32 80017 14757 ns/op 63104 B/op 187 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 359616 4246 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 270542 4374 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 352563 4639 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 249698 4487 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 285130 4183 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 292122 4346 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 273022 4187 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 313078 4479 ns/op 58687 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 217426 4636 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 302508 4229 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 244928 4605 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 236697 4255 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 277046 4474 ns/op 58687 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 275397 4174 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 326904 4391 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 299181 4368 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 389176 3790 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 266893 3815 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 381284 4228 ns/op 58687 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 389721 4240 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 371901 4027 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 270448 4025 ns/op 58690 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 260457 4103 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 381736 4022 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 383955 4217 ns/op 58687 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 276416 4082 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 295429 4323 ns/op 58688 B/op 23 allocs/op +BenchmarkRender/idiomatic/composed-page/templ-32 349482 3840 ns/op 58689 B/op 23 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1047 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1060 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1051 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1055 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1063 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1049 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1066 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1048 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1057 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1049 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1047 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1056 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1052 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1051 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1049 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1048 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1058 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1052 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1055 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1059 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1049 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1062 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1059 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1055 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1056 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1048 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1056 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/stdlib-text-32 1000000 1057 ns/op 672 B/op 4 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1936526 624.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1913308 622.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1901505 626.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1952516 613.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1913640 630.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1868658 642.8 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1926825 622.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1934728 631.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1942140 631.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1934041 623.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1881271 632.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1882971 634.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1928773 624.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1909435 627.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1922212 623.3 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1922576 636.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1878543 632.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1925581 626.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1906472 631.2 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1880698 631.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1884258 629.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1913892 621.7 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1919259 620.5 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1928613 617.9 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1926012 628.4 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1919422 626.6 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1909831 623.0 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/trivial-substitution/templ-32 1912569 627.1 ns/op 944 B/op 24 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 984 1205432 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 999 1201359 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 998 1202706 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 985 1200698 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1004 1206005 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 992 1214811 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 991 1203168 ns/op 395870 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 984 1205344 ns/op 395875 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 994 1208187 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 978 1208782 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1003 1200977 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 992 1201888 ns/op 395875 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 999 1197163 ns/op 395874 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 996 1201953 ns/op 395875 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 987 1204777 ns/op 395871 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1002 1204884 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 988 1202317 ns/op 395871 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 998 1201618 ns/op 395875 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 994 1198799 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 1002 1203443 ns/op 395875 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 984 1207633 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 994 1204283 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 980 1201810 ns/op 395873 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 994 1204329 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 992 1212691 ns/op 395877 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 999 1199634 ns/op 395875 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 997 1200296 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/stdlib-text-32 992 1205269 ns/op 395876 B/op 14749 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1610 758465 ns/op 874663 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1617 752081 ns/op 874656 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1597 751381 ns/op 874665 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1617 764005 ns/op 874677 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1594 771552 ns/op 874678 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1603 758489 ns/op 874672 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1606 757412 ns/op 874666 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1588 751331 ns/op 874672 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1550 758927 ns/op 874679 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1599 759167 ns/op 874668 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1585 756706 ns/op 874665 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1605 755861 ns/op 874674 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1489 771817 ns/op 874676 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1624 761412 ns/op 874666 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1510 759689 ns/op 874658 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1622 755286 ns/op 874671 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1596 760672 ns/op 874674 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1590 762569 ns/op 874662 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1507 762666 ns/op 874664 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1594 756778 ns/op 874664 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1596 760483 ns/op 874666 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1599 761741 ns/op 874657 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1574 767205 ns/op 874670 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1584 771410 ns/op 874675 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1578 756102 ns/op 874673 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1590 753663 ns/op 874666 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1604 756986 ns/op 874678 B/op 34740 allocs/op +BenchmarkRender/idiomatic/large-loop/templ-32 1430 765305 ns/op 874670 B/op 34740 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53161 22586 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53500 22320 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 52152 22514 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 52258 22585 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53665 22293 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53283 22348 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53532 22568 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 52598 22539 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53212 22458 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 52984 22484 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53331 22400 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53365 22357 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53881 22423 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53092 22419 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53193 22397 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53839 22406 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53920 22387 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53221 22394 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53539 22402 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53463 22343 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53755 22464 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53263 22420 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53578 22291 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 54170 22358 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53803 22461 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53089 22511 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53702 22329 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/stdlib-text-32 53704 22535 ns/op 15911 B/op 149 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 97170 12645 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 100209 12984 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 100622 12685 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 90769 12890 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 99840 12995 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 100238 12407 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 100456 12610 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 94291 12778 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 86589 13200 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 85902 12793 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 93434 12683 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 101006 12980 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 89524 12863 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 86388 13461 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 101347 12750 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 94387 12723 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 94408 13181 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 95509 12979 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 101308 12690 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 99331 12755 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 88213 12907 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 101038 12757 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 93494 12986 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 89802 12457 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 96194 12689 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 89380 13499 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 94700 12985 ns/op 20419 B/op 373 allocs/op +BenchmarkRender/idiomatic/mixed-page/templ-32 93722 12611 ns/op 20418 B/op 373 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12512 95693 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12542 95505 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12518 95893 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12486 96093 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12512 96175 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12440 96347 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12562 95637 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12531 95765 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12559 95479 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12484 96205 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12531 96108 ns/op 26755 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12529 95819 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12512 95872 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12475 96170 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12486 96039 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12585 95436 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12561 95603 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12525 95811 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12526 96152 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12526 95916 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12492 96110 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12530 95955 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12484 95955 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12546 95612 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12480 96104 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12519 95933 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12528 95526 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/stdlib-text-32 12486 95953 ns/op 26756 B/op 305 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33849 35859 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33255 35838 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33806 36116 ns/op 46219 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33015 35852 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32439 37197 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 31176 37102 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 34596 35260 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33019 37176 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33728 35911 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33943 36181 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 35304 34610 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33321 36396 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32884 35883 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33438 36121 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 31988 35922 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 31945 36116 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33007 36463 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32725 35393 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33674 35432 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33682 35548 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32845 35981 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32502 36377 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32962 35798 ns/op 46216 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33014 36280 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33602 35789 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33093 36105 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 32446 36554 ns/op 46217 B/op 1206 allocs/op +BenchmarkRender/idiomatic/conditional-heavy/templ-32 33920 36085 ns/op 46218 B/op 1206 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54699 21875 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55414 21892 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54428 21942 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54345 21923 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55089 21945 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54193 22005 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54477 22014 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55039 21879 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 53679 22009 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54643 21941 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54912 21827 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55171 21748 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54759 21832 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55172 21920 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54739 21823 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54476 21882 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54777 21840 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55171 21924 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55003 21844 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54951 21809 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55224 21830 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 53650 22000 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55000 21999 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55207 21884 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55051 21900 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54434 21934 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 54478 21941 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/stdlib-text-32 55102 21885 ns/op 13758 B/op 247 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 117211 10428 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 115072 10346 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 123907 10133 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 105865 10485 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 119665 10432 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 121675 10206 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 117579 10457 ns/op 12940 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 113530 10707 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 115684 10404 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 104648 10342 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 123099 10054 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 124210 10107 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 108492 10276 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122876 10306 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 119920 10077 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 111032 10257 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122392 10207 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 123123 10171 ns/op 12940 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 110560 10450 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 112946 10430 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 110967 10258 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 124135 10333 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 121141 10466 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 122431 10439 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 116840 10486 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 110928 10424 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 123739 10613 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fragment-heavy/templ-32 120877 10287 ns/op 12939 B/op 413 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102976 11677 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101182 11676 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101988 11717 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103466 11638 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101178 11664 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103034 11672 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102363 11675 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102781 11760 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101844 11671 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103388 11683 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102421 11673 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102678 11687 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102919 11707 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103392 11635 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102266 11759 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103185 11625 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102483 11683 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 99128 11700 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102586 11767 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101806 11719 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103999 11642 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102278 11723 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 103500 11668 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101978 11681 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102561 11678 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 102742 11710 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 100862 11742 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/stdlib-html-32 101702 11682 ns/op 5298 B/op 155 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 524007 2621 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 517519 2716 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 509596 2565 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 405793 2661 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 494714 2614 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 513460 2616 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 501890 2680 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 516050 2732 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 510468 2815 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 514497 2658 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 519932 2677 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 424348 2776 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 389163 2697 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 419245 2616 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 472256 2595 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 498945 2642 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 465664 2761 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 520094 2623 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 510848 2649 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 504166 2620 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 460768 2588 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 412292 2716 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 512150 2629 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 495590 2693 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 511820 2718 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 511292 2779 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 404926 2585 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/fortunes-encoded/templ-32 511380 2723 ns/op 4025 B/op 74 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7443066 ns/op 4176930 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7468677 ns/op 4176896 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7499777 ns/op 4176897 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7446200 ns/op 4176924 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7512546 ns/op 4176925 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7440731 ns/op 4176895 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7454346 ns/op 4176897 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7430249 ns/op 4176899 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7447913 ns/op 4176938 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7478965 ns/op 4176920 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7489004 ns/op 4176907 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7508189 ns/op 4176930 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7472309 ns/op 4176896 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 157 7542892 ns/op 4176912 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7498686 ns/op 4176926 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7486501 ns/op 4176943 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7468008 ns/op 4176866 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7519645 ns/op 4176929 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7448056 ns/op 4176972 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7468011 ns/op 4176884 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7459821 ns/op 4176881 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7472895 ns/op 4176928 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7480399 ns/op 4176876 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7460930 ns/op 4176935 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 158 7529075 ns/op 4176922 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 159 7489424 ns/op 4176867 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7449304 ns/op 4176926 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/stdlib-html-32 160 7464418 ns/op 4176916 B/op 124851 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 709 1673914 ns/op 3301287 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 738 1807425 ns/op 3301301 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 759 1639645 ns/op 3301322 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 680 1776413 ns/op 3301324 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 691 1757008 ns/op 3301383 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 708 1777614 ns/op 3301368 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 636 1871076 ns/op 3301394 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 650 1746896 ns/op 3301292 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 702 1783726 ns/op 3301352 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 686 1761679 ns/op 3301287 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 690 1740849 ns/op 3301265 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 728 1776943 ns/op 3301284 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 696 1779441 ns/op 3301346 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 699 1805423 ns/op 3301313 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 724 1715984 ns/op 3301349 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 780 1806547 ns/op 3301272 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 590 1825566 ns/op 3301350 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 714 1886455 ns/op 3301308 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 589 1964116 ns/op 3301381 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 681 1747322 ns/op 3301299 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 652 1864778 ns/op 3301287 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 652 1818570 ns/op 3301332 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 631 1718702 ns/op 3301289 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 709 1800001 ns/op 3301364 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 720 1792012 ns/op 3301311 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 686 1837063 ns/op 3301360 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 651 1825495 ns/op 3301372 B/op 65008 allocs/op +BenchmarkRender/idiomatic/encoded-loop/templ-32 732 1755392 ns/op 3301304 B/op 65008 allocs/op +PASS diff --git a/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260722.txt b/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260722.txt new file mode 100644 index 00000000..c2da2cdc --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260722.txt @@ -0,0 +1,21 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor + Γöé results\bench-coldparse-20260722.txt Γöé + Γöé sec/op Γöé +ColdParse/stdlib-text-32 40.55┬╡ ┬▒ 1% +ColdParse/stdlib-html-32 6.472┬╡ ┬▒ 2% +geomean 16.20┬╡ + + Γöé results\bench-coldparse-20260722.txt Γöé + Γöé B/op Γöé +ColdParse/stdlib-text-32 45.48Ki ┬▒ 0% +ColdParse/stdlib-html-32 9.859Ki ┬▒ 0% +geomean 21.18Ki + + Γöé results\bench-coldparse-20260722.txt Γöé + Γöé allocs/op Γöé +ColdParse/stdlib-text-32 764.0 ┬▒ 0% +ColdParse/stdlib-html-32 147.0 ┬▒ 0% +geomean 335.1 diff --git a/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260802.txt b/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260802.txt new file mode 100644 index 00000000..b86ad756 --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260802.txt @@ -0,0 +1,21 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor + │ results\bench-coldparse-20260802.txt │ + │ sec/op │ +ColdParse/stdlib-text-32 40.30µ ± 1% +ColdParse/stdlib-html-32 7.000µ ± 2% +geomean 16.80µ + + │ results\bench-coldparse-20260802.txt │ + │ B/op │ +ColdParse/stdlib-text-32 45.48Ki ± 0% +ColdParse/stdlib-html-32 9.859Ki ± 0% +geomean 21.18Ki + + │ results\bench-coldparse-20260802.txt │ + │ allocs/op │ +ColdParse/stdlib-text-32 764.0 ± 0% +ColdParse/stdlib-html-32 147.0 ± 0% +geomean 335.1 diff --git a/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260803.txt b/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260803.txt new file mode 100644 index 00000000..c95752a6 --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260803.txt @@ -0,0 +1,21 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor + │ results\bench-coldparse-20260803.txt │ + │ sec/op │ +ColdParse/stdlib-text-32 39.06µ ± 1% +ColdParse/stdlib-html-32 6.637µ ± 2% +geomean 16.10µ + + │ results\bench-coldparse-20260803.txt │ + │ B/op │ +ColdParse/stdlib-text-32 45.48Ki ± 0% +ColdParse/stdlib-html-32 9.859Ki ± 0% +geomean 21.18Ki + + │ results\bench-coldparse-20260803.txt │ + │ allocs/op │ +ColdParse/stdlib-text-32 764.0 ± 0% +ColdParse/stdlib-html-32 147.0 ± 0% +geomean 335.1 diff --git a/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260808.txt b/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260808.txt new file mode 100644 index 00000000..ba365e07 --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/benchstat-coldparse-20260808.txt @@ -0,0 +1,21 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor + │ results\bench-coldparse-20260808.txt │ + │ sec/op │ +ColdParse/stdlib-text-32 38.69µ ± 0% +ColdParse/stdlib-html-32 6.136µ ± 1% +geomean 15.41µ + + │ results\bench-coldparse-20260808.txt │ + │ B/op │ +ColdParse/stdlib-text-32 45.48Ki ± 0% +ColdParse/stdlib-html-32 9.859Ki ± 0% +geomean 21.18Ki + + │ results\bench-coldparse-20260808.txt │ + │ allocs/op │ +ColdParse/stdlib-text-32 764.0 ± 0% +ColdParse/stdlib-html-32 147.0 ± 0% +geomean 335.1 diff --git a/docs/benchmarks/2026-08-08/go/benchstat-render-20260722.txt b/docs/benchmarks/2026-08-08/go/benchstat-render-20260722.txt new file mode 100644 index 00000000..85286955 --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/benchstat-render-20260722.txt @@ -0,0 +1,111 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor + Γöé results\bench-render-20260722.txt Γöé + Γöé sec/op Γöé +Render/controlled/composed-page/stdlib-text-32 19.40┬╡ ┬▒ 6% +Render/controlled/composed-page/templ-32 17.03┬╡ ┬▒ 10% +Render/controlled/trivial-substitution/stdlib-text-32 1.042┬╡ ┬▒ 1% +Render/controlled/trivial-substitution/templ-32 757.2n ┬▒ 1% +Render/controlled/large-loop/stdlib-text-32 1.163m ┬▒ 0% +Render/controlled/large-loop/templ-32 527.3┬╡ ┬▒ 1% +Render/controlled/mixed-page/stdlib-text-32 21.84┬╡ ┬▒ 1% +Render/controlled/mixed-page/templ-32 11.55┬╡ ┬▒ 1% +Render/controlled/conditional-heavy/stdlib-text-32 92.34┬╡ ┬▒ 1% +Render/controlled/conditional-heavy/templ-32 22.78┬╡ ┬▒ 1% +Render/controlled/fragment-heavy/stdlib-text-32 20.59┬╡ ┬▒ 1% +Render/controlled/fragment-heavy/templ-32 10.51┬╡ ┬▒ 1% +Render/controlled/fortunes-encoded/stdlib-html-32 11.55┬╡ ┬▒ 0% +Render/controlled/fortunes-encoded/templ-32 1.892┬╡ ┬▒ 2% +Render/controlled/encoded-loop/stdlib-html-32 7.423m ┬▒ 1% +Render/controlled/encoded-loop/templ-32 1.398m ┬▒ 3% +Render/idiomatic/composed-page/stdlib-text-32 17.28┬╡ ┬▒ 3% +Render/idiomatic/composed-page/templ-32 4.678┬╡ ┬▒ 5% +Render/idiomatic/trivial-substitution/stdlib-text-32 1.023┬╡ ┬▒ 1% +Render/idiomatic/trivial-substitution/templ-32 667.5n ┬▒ 1% +Render/idiomatic/large-loop/stdlib-text-32 1.161m ┬▒ 0% +Render/idiomatic/large-loop/templ-32 796.8┬╡ ┬▒ 3% +Render/idiomatic/mixed-page/stdlib-text-32 21.80┬╡ ┬▒ 0% +Render/idiomatic/mixed-page/templ-32 12.78┬╡ ┬▒ 2% +Render/idiomatic/conditional-heavy/stdlib-text-32 92.94┬╡ ┬▒ 1% +Render/idiomatic/conditional-heavy/templ-32 35.70┬╡ ┬▒ 1% +Render/idiomatic/fragment-heavy/stdlib-text-32 21.67┬╡ ┬▒ 0% +Render/idiomatic/fragment-heavy/templ-32 10.21┬╡ ┬▒ 1% +Render/idiomatic/fortunes-encoded/stdlib-html-32 11.57┬╡ ┬▒ 1% +Render/idiomatic/fortunes-encoded/templ-32 2.493┬╡ ┬▒ 2% +Render/idiomatic/encoded-loop/stdlib-html-32 7.363m ┬▒ 1% +Render/idiomatic/encoded-loop/templ-32 1.614m ┬▒ 2% +geomean 34.41┬╡ + + Γöé results\bench-render-20260722.txt Γöé + Γöé B/op Γöé +Render/controlled/composed-page/stdlib-text-32 61.65Ki ┬▒ 0% +Render/controlled/composed-page/templ-32 57.32Ki ┬▒ 0% +Render/controlled/trivial-substitution/stdlib-text-32 640.0 ┬▒ 0% +Render/controlled/trivial-substitution/templ-32 944.0 ┬▒ 0% +Render/controlled/large-loop/stdlib-text-32 346.6Ki ┬▒ 0% +Render/controlled/large-loop/templ-32 385.0Ki ┬▒ 0% +Render/controlled/mixed-page/stdlib-text-32 12.29Ki ┬▒ 0% +Render/controlled/mixed-page/templ-32 17.05Ki ┬▒ 0% +Render/controlled/conditional-heavy/stdlib-text-32 20.88Ki ┬▒ 0% +Render/controlled/conditional-heavy/templ-32 23.24Ki ┬▒ 0% +Render/controlled/fragment-heavy/stdlib-text-32 12.81Ki ┬▒ 0% +Render/controlled/fragment-heavy/templ-32 12.64Ki ┬▒ 0% +Render/controlled/fortunes-encoded/stdlib-html-32 4.674Ki ┬▒ 0% +Render/controlled/fortunes-encoded/templ-32 2.805Ki ┬▒ 0% +Render/controlled/encoded-loop/stdlib-html-32 3.913Mi ┬▒ 0% +Render/controlled/encoded-loop/templ-32 2.537Mi ┬▒ 0% +Render/idiomatic/composed-page/stdlib-text-32 61.64Ki ┬▒ 0% +Render/idiomatic/composed-page/templ-32 57.31Ki ┬▒ 0% +Render/idiomatic/trivial-substitution/stdlib-text-32 672.0 ┬▒ 0% +Render/idiomatic/trivial-substitution/templ-32 944.0 ┬▒ 0% +Render/idiomatic/large-loop/stdlib-text-32 386.6Ki ┬▒ 0% +Render/idiomatic/large-loop/templ-32 854.2Ki ┬▒ 0% +Render/idiomatic/mixed-page/stdlib-text-32 15.54Ki ┬▒ 0% +Render/idiomatic/mixed-page/templ-32 19.94Ki ┬▒ 0% +Render/idiomatic/conditional-heavy/stdlib-text-32 26.13Ki ┬▒ 0% +Render/idiomatic/conditional-heavy/templ-32 45.13Ki ┬▒ 0% +Render/idiomatic/fragment-heavy/stdlib-text-32 13.44Ki ┬▒ 0% +Render/idiomatic/fragment-heavy/templ-32 12.64Ki ┬▒ 0% +Render/idiomatic/fortunes-encoded/stdlib-html-32 5.174Ki ┬▒ 0% +Render/idiomatic/fortunes-encoded/templ-32 3.931Ki ┬▒ 0% +Render/idiomatic/encoded-loop/stdlib-html-32 3.983Mi ┬▒ 0% +Render/idiomatic/encoded-loop/templ-32 3.148Mi ┬▒ 0% +geomean 33.63Ki + + Γöé results\bench-render-20260722.txt Γöé + Γöé allocs/op Γöé +Render/controlled/composed-page/stdlib-text-32 187.0 ┬▒ 0% +Render/controlled/composed-page/templ-32 23.00 ┬▒ 0% +Render/controlled/trivial-substitution/stdlib-text-32 4.000 ┬▒ 0% +Render/controlled/trivial-substitution/templ-32 24.00 ┬▒ 0% +Render/controlled/large-loop/stdlib-text-32 14.75k ┬▒ 0% +Render/controlled/large-loop/templ-32 19.74k ┬▒ 0% +Render/controlled/mixed-page/stdlib-text-32 149.0 ┬▒ 0% +Render/controlled/mixed-page/templ-32 314.0 ┬▒ 0% +Render/controlled/conditional-heavy/stdlib-text-32 305.0 ┬▒ 0% +Render/controlled/conditional-heavy/templ-32 606.0 ┬▒ 0% +Render/controlled/fragment-heavy/stdlib-text-32 245.0 ┬▒ 0% +Render/controlled/fragment-heavy/templ-32 413.0 ┬▒ 0% +Render/controlled/fortunes-encoded/stdlib-html-32 155.0 ┬▒ 0% +Render/controlled/fortunes-encoded/templ-32 38.00 ┬▒ 0% +Render/controlled/encoded-loop/stdlib-html-32 124.9k ┬▒ 0% +Render/controlled/encoded-loop/templ-32 50.01k ┬▒ 0% +Render/idiomatic/composed-page/stdlib-text-32 187.0 ┬▒ 0% +Render/idiomatic/composed-page/templ-32 23.00 ┬▒ 0% +Render/idiomatic/trivial-substitution/stdlib-text-32 4.000 ┬▒ 0% +Render/idiomatic/trivial-substitution/templ-32 24.00 ┬▒ 0% +Render/idiomatic/large-loop/stdlib-text-32 14.75k ┬▒ 0% +Render/idiomatic/large-loop/templ-32 34.74k ┬▒ 0% +Render/idiomatic/mixed-page/stdlib-text-32 149.0 ┬▒ 0% +Render/idiomatic/mixed-page/templ-32 373.0 ┬▒ 0% +Render/idiomatic/conditional-heavy/stdlib-text-32 305.0 ┬▒ 0% +Render/idiomatic/conditional-heavy/templ-32 1.206k ┬▒ 0% +Render/idiomatic/fragment-heavy/stdlib-text-32 247.0 ┬▒ 0% +Render/idiomatic/fragment-heavy/templ-32 413.0 ┬▒ 0% +Render/idiomatic/fortunes-encoded/stdlib-html-32 155.0 ┬▒ 0% +Render/idiomatic/fortunes-encoded/templ-32 74.00 ┬▒ 0% +Render/idiomatic/encoded-loop/stdlib-html-32 124.9k ┬▒ 0% +Render/idiomatic/encoded-loop/templ-32 65.01k ┬▒ 0% +geomean 494.1 diff --git a/docs/benchmarks/2026-08-08/go/benchstat-render-20260802.txt b/docs/benchmarks/2026-08-08/go/benchstat-render-20260802.txt new file mode 100644 index 00000000..72da19e2 --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/benchstat-render-20260802.txt @@ -0,0 +1,111 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor + │ results\bench-render-20260802.txt │ + │ sec/op │ +Render/controlled/composed-page/stdlib-text-32 15.22µ ± 1% +Render/controlled/composed-page/templ-32 10.47µ ± 11% +Render/controlled/trivial-substitution/stdlib-text-32 1.019µ ± 1% +Render/controlled/trivial-substitution/templ-32 688.9n ± 2% +Render/controlled/large-loop/stdlib-text-32 1.186m ± 0% +Render/controlled/large-loop/templ-32 529.0µ ± 1% +Render/controlled/mixed-page/stdlib-text-32 21.78µ ± 0% +Render/controlled/mixed-page/templ-32 11.11µ ± 2% +Render/controlled/conditional-heavy/stdlib-text-32 94.77µ ± 0% +Render/controlled/conditional-heavy/templ-32 22.40µ ± 1% +Render/controlled/fragment-heavy/stdlib-text-32 20.81µ ± 0% +Render/controlled/fragment-heavy/templ-32 10.45µ ± 1% +Render/controlled/fortunes-encoded/stdlib-html-32 11.87µ ± 0% +Render/controlled/fortunes-encoded/templ-32 1.847µ ± 1% +Render/controlled/encoded-loop/stdlib-html-32 7.561m ± 1% +Render/controlled/encoded-loop/templ-32 1.462m ± 2% +Render/idiomatic/composed-page/stdlib-text-32 21.23µ ± 2% +Render/idiomatic/composed-page/templ-32 5.707µ ± 4% +Render/idiomatic/trivial-substitution/stdlib-text-32 1.030µ ± 0% +Render/idiomatic/trivial-substitution/templ-32 696.9n ± 1% +Render/idiomatic/large-loop/stdlib-text-32 1.187m ± 0% +Render/idiomatic/large-loop/templ-32 797.2µ ± 1% +Render/idiomatic/mixed-page/stdlib-text-32 22.49µ ± 1% +Render/idiomatic/mixed-page/templ-32 13.47µ ± 1% +Render/idiomatic/conditional-heavy/stdlib-text-32 96.30µ ± 0% +Render/idiomatic/conditional-heavy/templ-32 36.28µ ± 1% +Render/idiomatic/fragment-heavy/stdlib-text-32 21.79µ ± 1% +Render/idiomatic/fragment-heavy/templ-32 10.43µ ± 1% +Render/idiomatic/fortunes-encoded/stdlib-html-32 11.83µ ± 0% +Render/idiomatic/fortunes-encoded/templ-32 2.595µ ± 2% +Render/idiomatic/encoded-loop/stdlib-html-32 7.565m ± 0% +Render/idiomatic/encoded-loop/templ-32 1.672m ± 1% +geomean 34.39µ + + │ results\bench-render-20260802.txt │ + │ B/op │ +Render/controlled/composed-page/stdlib-text-32 61.62Ki ± 0% +Render/controlled/composed-page/templ-32 57.32Ki ± 0% +Render/controlled/trivial-substitution/stdlib-text-32 640.0 ± 0% +Render/controlled/trivial-substitution/templ-32 944.0 ± 0% +Render/controlled/large-loop/stdlib-text-32 346.6Ki ± 0% +Render/controlled/large-loop/templ-32 385.0Ki ± 0% +Render/controlled/mixed-page/stdlib-text-32 12.29Ki ± 0% +Render/controlled/mixed-page/templ-32 17.05Ki ± 0% +Render/controlled/conditional-heavy/stdlib-text-32 20.88Ki ± 0% +Render/controlled/conditional-heavy/templ-32 23.24Ki ± 0% +Render/controlled/fragment-heavy/stdlib-text-32 12.81Ki ± 0% +Render/controlled/fragment-heavy/templ-32 12.64Ki ± 0% +Render/controlled/fortunes-encoded/stdlib-html-32 4.674Ki ± 0% +Render/controlled/fortunes-encoded/templ-32 2.805Ki ± 0% +Render/controlled/encoded-loop/stdlib-html-32 3.913Mi ± 0% +Render/controlled/encoded-loop/templ-32 2.538Mi ± 0% +Render/idiomatic/composed-page/stdlib-text-32 61.64Ki ± 0% +Render/idiomatic/composed-page/templ-32 57.31Ki ± 0% +Render/idiomatic/trivial-substitution/stdlib-text-32 672.0 ± 0% +Render/idiomatic/trivial-substitution/templ-32 944.0 ± 0% +Render/idiomatic/large-loop/stdlib-text-32 386.6Ki ± 0% +Render/idiomatic/large-loop/templ-32 854.2Ki ± 0% +Render/idiomatic/mixed-page/stdlib-text-32 15.54Ki ± 0% +Render/idiomatic/mixed-page/templ-32 19.94Ki ± 0% +Render/idiomatic/conditional-heavy/stdlib-text-32 26.13Ki ± 0% +Render/idiomatic/conditional-heavy/templ-32 45.13Ki ± 0% +Render/idiomatic/fragment-heavy/stdlib-text-32 13.44Ki ± 0% +Render/idiomatic/fragment-heavy/templ-32 12.64Ki ± 0% +Render/idiomatic/fortunes-encoded/stdlib-html-32 5.174Ki ± 0% +Render/idiomatic/fortunes-encoded/templ-32 3.931Ki ± 0% +Render/idiomatic/encoded-loop/stdlib-html-32 3.983Mi ± 0% +Render/idiomatic/encoded-loop/templ-32 3.148Mi ± 0% +geomean 33.63Ki + + │ results\bench-render-20260802.txt │ + │ allocs/op │ +Render/controlled/composed-page/stdlib-text-32 187.0 ± 0% +Render/controlled/composed-page/templ-32 23.00 ± 0% +Render/controlled/trivial-substitution/stdlib-text-32 4.000 ± 0% +Render/controlled/trivial-substitution/templ-32 24.00 ± 0% +Render/controlled/large-loop/stdlib-text-32 14.75k ± 0% +Render/controlled/large-loop/templ-32 19.74k ± 0% +Render/controlled/mixed-page/stdlib-text-32 149.0 ± 0% +Render/controlled/mixed-page/templ-32 314.0 ± 0% +Render/controlled/conditional-heavy/stdlib-text-32 305.0 ± 0% +Render/controlled/conditional-heavy/templ-32 606.0 ± 0% +Render/controlled/fragment-heavy/stdlib-text-32 245.0 ± 0% +Render/controlled/fragment-heavy/templ-32 413.0 ± 0% +Render/controlled/fortunes-encoded/stdlib-html-32 155.0 ± 0% +Render/controlled/fortunes-encoded/templ-32 38.00 ± 0% +Render/controlled/encoded-loop/stdlib-html-32 124.9k ± 0% +Render/controlled/encoded-loop/templ-32 50.01k ± 0% +Render/idiomatic/composed-page/stdlib-text-32 187.0 ± 0% +Render/idiomatic/composed-page/templ-32 23.00 ± 0% +Render/idiomatic/trivial-substitution/stdlib-text-32 4.000 ± 0% +Render/idiomatic/trivial-substitution/templ-32 24.00 ± 0% +Render/idiomatic/large-loop/stdlib-text-32 14.75k ± 0% +Render/idiomatic/large-loop/templ-32 34.74k ± 0% +Render/idiomatic/mixed-page/stdlib-text-32 149.0 ± 0% +Render/idiomatic/mixed-page/templ-32 373.0 ± 0% +Render/idiomatic/conditional-heavy/stdlib-text-32 305.0 ± 0% +Render/idiomatic/conditional-heavy/templ-32 1.206k ± 0% +Render/idiomatic/fragment-heavy/stdlib-text-32 247.0 ± 0% +Render/idiomatic/fragment-heavy/templ-32 413.0 ± 0% +Render/idiomatic/fortunes-encoded/stdlib-html-32 155.0 ± 0% +Render/idiomatic/fortunes-encoded/templ-32 74.00 ± 0% +Render/idiomatic/encoded-loop/stdlib-html-32 124.9k ± 0% +Render/idiomatic/encoded-loop/templ-32 65.01k ± 0% +geomean 494.1 diff --git a/docs/benchmarks/2026-08-08/go/benchstat-render-20260803.txt b/docs/benchmarks/2026-08-08/go/benchstat-render-20260803.txt new file mode 100644 index 00000000..3140bd4e --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/benchstat-render-20260803.txt @@ -0,0 +1,111 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor + │ results\bench-render-20260803.txt │ + │ sec/op │ +Render/controlled/composed-page/stdlib-text-32 14.36µ ± 1% +Render/controlled/composed-page/templ-32 6.886µ ± 9% +Render/controlled/trivial-substitution/stdlib-text-32 1.003µ ± 1% +Render/controlled/trivial-substitution/templ-32 690.3n ± 2% +Render/controlled/large-loop/stdlib-text-32 1.148m ± 0% +Render/controlled/large-loop/templ-32 513.8µ ± 0% +Render/controlled/mixed-page/stdlib-text-32 21.46µ ± 1% +Render/controlled/mixed-page/templ-32 11.58µ ± 2% +Render/controlled/conditional-heavy/stdlib-text-32 91.99µ ± 0% +Render/controlled/conditional-heavy/templ-32 22.30µ ± 1% +Render/controlled/fragment-heavy/stdlib-text-32 20.20µ ± 0% +Render/controlled/fragment-heavy/templ-32 10.49µ ± 1% +Render/controlled/fortunes-encoded/stdlib-html-32 11.48µ ± 0% +Render/controlled/fortunes-encoded/templ-32 1.842µ ± 1% +Render/controlled/encoded-loop/stdlib-html-32 7.369m ± 0% +Render/controlled/encoded-loop/templ-32 1.399m ± 1% +Render/idiomatic/composed-page/stdlib-text-32 19.88µ ± 3% +Render/idiomatic/composed-page/templ-32 5.867µ ± 5% +Render/idiomatic/trivial-substitution/stdlib-text-32 1.008µ ± 0% +Render/idiomatic/trivial-substitution/templ-32 663.3n ± 1% +Render/idiomatic/large-loop/stdlib-text-32 1.150m ± 0% +Render/idiomatic/large-loop/templ-32 766.8µ ± 1% +Render/idiomatic/mixed-page/stdlib-text-32 21.58µ ± 0% +Render/idiomatic/mixed-page/templ-32 13.12µ ± 2% +Render/idiomatic/conditional-heavy/stdlib-text-32 93.34µ ± 0% +Render/idiomatic/conditional-heavy/templ-32 35.65µ ± 1% +Render/idiomatic/fragment-heavy/stdlib-text-32 21.40µ ± 0% +Render/idiomatic/fragment-heavy/templ-32 10.12µ ± 1% +Render/idiomatic/fortunes-encoded/stdlib-html-32 11.47µ ± 0% +Render/idiomatic/fortunes-encoded/templ-32 2.534µ ± 1% +Render/idiomatic/encoded-loop/stdlib-html-32 7.368m ± 0% +Render/idiomatic/encoded-loop/templ-32 1.654m ± 1% +geomean 33.19µ + + │ results\bench-render-20260803.txt │ + │ B/op │ +Render/controlled/composed-page/stdlib-text-32 61.63Ki ± 0% +Render/controlled/composed-page/templ-32 57.32Ki ± 0% +Render/controlled/trivial-substitution/stdlib-text-32 640.0 ± 0% +Render/controlled/trivial-substitution/templ-32 945.0 ± 0% +Render/controlled/large-loop/stdlib-text-32 346.6Ki ± 0% +Render/controlled/large-loop/templ-32 385.0Ki ± 0% +Render/controlled/mixed-page/stdlib-text-32 12.29Ki ± 0% +Render/controlled/mixed-page/templ-32 17.05Ki ± 0% +Render/controlled/conditional-heavy/stdlib-text-32 20.88Ki ± 0% +Render/controlled/conditional-heavy/templ-32 23.24Ki ± 0% +Render/controlled/fragment-heavy/stdlib-text-32 12.81Ki ± 0% +Render/controlled/fragment-heavy/templ-32 12.64Ki ± 0% +Render/controlled/fortunes-encoded/stdlib-html-32 4.674Ki ± 0% +Render/controlled/fortunes-encoded/templ-32 2.805Ki ± 0% +Render/controlled/encoded-loop/stdlib-html-32 3.913Mi ± 0% +Render/controlled/encoded-loop/templ-32 2.538Mi ± 0% +Render/idiomatic/composed-page/stdlib-text-32 61.64Ki ± 0% +Render/idiomatic/composed-page/templ-32 57.32Ki ± 0% +Render/idiomatic/trivial-substitution/stdlib-text-32 672.0 ± 0% +Render/idiomatic/trivial-substitution/templ-32 944.0 ± 0% +Render/idiomatic/large-loop/stdlib-text-32 386.6Ki ± 0% +Render/idiomatic/large-loop/templ-32 854.2Ki ± 0% +Render/idiomatic/mixed-page/stdlib-text-32 15.54Ki ± 0% +Render/idiomatic/mixed-page/templ-32 19.94Ki ± 0% +Render/idiomatic/conditional-heavy/stdlib-text-32 26.13Ki ± 0% +Render/idiomatic/conditional-heavy/templ-32 45.13Ki ± 0% +Render/idiomatic/fragment-heavy/stdlib-text-32 13.44Ki ± 0% +Render/idiomatic/fragment-heavy/templ-32 12.64Ki ± 0% +Render/idiomatic/fortunes-encoded/stdlib-html-32 5.174Ki ± 0% +Render/idiomatic/fortunes-encoded/templ-32 3.931Ki ± 0% +Render/idiomatic/encoded-loop/stdlib-html-32 3.983Mi ± 0% +Render/idiomatic/encoded-loop/templ-32 3.148Mi ± 0% +geomean 33.63Ki + + │ results\bench-render-20260803.txt │ + │ allocs/op │ +Render/controlled/composed-page/stdlib-text-32 187.0 ± 0% +Render/controlled/composed-page/templ-32 23.00 ± 0% +Render/controlled/trivial-substitution/stdlib-text-32 4.000 ± 0% +Render/controlled/trivial-substitution/templ-32 24.00 ± 0% +Render/controlled/large-loop/stdlib-text-32 14.75k ± 0% +Render/controlled/large-loop/templ-32 19.74k ± 0% +Render/controlled/mixed-page/stdlib-text-32 149.0 ± 0% +Render/controlled/mixed-page/templ-32 314.0 ± 0% +Render/controlled/conditional-heavy/stdlib-text-32 305.0 ± 0% +Render/controlled/conditional-heavy/templ-32 606.0 ± 0% +Render/controlled/fragment-heavy/stdlib-text-32 245.0 ± 0% +Render/controlled/fragment-heavy/templ-32 413.0 ± 0% +Render/controlled/fortunes-encoded/stdlib-html-32 155.0 ± 0% +Render/controlled/fortunes-encoded/templ-32 38.00 ± 0% +Render/controlled/encoded-loop/stdlib-html-32 124.9k ± 0% +Render/controlled/encoded-loop/templ-32 50.01k ± 0% +Render/idiomatic/composed-page/stdlib-text-32 187.0 ± 0% +Render/idiomatic/composed-page/templ-32 23.00 ± 0% +Render/idiomatic/trivial-substitution/stdlib-text-32 4.000 ± 0% +Render/idiomatic/trivial-substitution/templ-32 24.00 ± 0% +Render/idiomatic/large-loop/stdlib-text-32 14.75k ± 0% +Render/idiomatic/large-loop/templ-32 34.74k ± 0% +Render/idiomatic/mixed-page/stdlib-text-32 149.0 ± 0% +Render/idiomatic/mixed-page/templ-32 373.0 ± 0% +Render/idiomatic/conditional-heavy/stdlib-text-32 305.0 ± 0% +Render/idiomatic/conditional-heavy/templ-32 1.206k ± 0% +Render/idiomatic/fragment-heavy/stdlib-text-32 247.0 ± 0% +Render/idiomatic/fragment-heavy/templ-32 413.0 ± 0% +Render/idiomatic/fortunes-encoded/stdlib-html-32 155.0 ± 0% +Render/idiomatic/fortunes-encoded/templ-32 74.00 ± 0% +Render/idiomatic/encoded-loop/stdlib-html-32 124.9k ± 0% +Render/idiomatic/encoded-loop/templ-32 65.01k ± 0% +geomean 494.1 diff --git a/docs/benchmarks/2026-08-08/go/benchstat-render-20260808.txt b/docs/benchmarks/2026-08-08/go/benchstat-render-20260808.txt new file mode 100644 index 00000000..0028aabb --- /dev/null +++ b/docs/benchmarks/2026-08-08/go/benchstat-render-20260808.txt @@ -0,0 +1,111 @@ +goos: windows +goarch: amd64 +pkg: heddle.dev/benchmarks/go/suites +cpu: AMD Ryzen 9 9950X 16-Core Processor + │ results\bench-render-20260808.txt │ + │ sec/op │ +Render/controlled/composed-page/stdlib-text-32 13.78µ ± 1% +Render/controlled/composed-page/templ-32 3.953µ ± 3% +Render/controlled/trivial-substitution/stdlib-text-32 1.042µ ± 0% +Render/controlled/trivial-substitution/templ-32 618.3n ± 0% +Render/controlled/large-loop/stdlib-text-32 1.202m ± 0% +Render/controlled/large-loop/templ-32 509.5µ ± 0% +Render/controlled/mixed-page/stdlib-text-32 22.15µ ± 0% +Render/controlled/mixed-page/templ-32 9.707µ ± 1% +Render/controlled/conditional-heavy/stdlib-text-32 94.49µ ± 0% +Render/controlled/conditional-heavy/templ-32 21.57µ ± 0% +Render/controlled/fragment-heavy/stdlib-text-32 20.87µ ± 0% +Render/controlled/fragment-heavy/templ-32 9.748µ ± 0% +Render/controlled/fortunes-encoded/stdlib-html-32 11.61µ ± 0% +Render/controlled/fortunes-encoded/templ-32 1.727µ ± 0% +Render/controlled/encoded-loop/stdlib-html-32 7.469m ± 0% +Render/controlled/encoded-loop/templ-32 1.286m ± 1% +Render/idiomatic/composed-page/stdlib-text-32 14.78µ ± 1% +Render/idiomatic/composed-page/templ-32 4.234µ ± 3% +Render/idiomatic/trivial-substitution/stdlib-text-32 1.055µ ± 1% +Render/idiomatic/trivial-substitution/templ-32 626.9n ± 1% +Render/idiomatic/large-loop/stdlib-text-32 1.203m ± 0% +Render/idiomatic/large-loop/templ-32 759.0µ ± 0% +Render/idiomatic/mixed-page/stdlib-text-32 22.41µ ± 0% +Render/idiomatic/mixed-page/templ-32 12.79µ ± 2% +Render/idiomatic/conditional-heavy/stdlib-text-32 95.92µ ± 0% +Render/idiomatic/conditional-heavy/templ-32 36.03µ ± 1% +Render/idiomatic/fragment-heavy/stdlib-text-32 21.90µ ± 0% +Render/idiomatic/fragment-heavy/templ-32 10.34µ ± 1% +Render/idiomatic/fortunes-encoded/stdlib-html-32 11.68µ ± 0% +Render/idiomatic/fortunes-encoded/templ-32 2.660µ ± 2% +Render/idiomatic/encoded-loop/stdlib-html-32 7.470m ± 0% +Render/idiomatic/encoded-loop/templ-32 1.782m ± 1% +geomean 31.88µ + + │ results\bench-render-20260808.txt │ + │ B/op │ +Render/controlled/composed-page/stdlib-text-32 61.62Ki ± 0% +Render/controlled/composed-page/templ-32 57.31Ki ± 0% +Render/controlled/trivial-substitution/stdlib-text-32 640.0 ± 0% +Render/controlled/trivial-substitution/templ-32 944.0 ± 0% +Render/controlled/large-loop/stdlib-text-32 346.6Ki ± 0% +Render/controlled/large-loop/templ-32 385.0Ki ± 0% +Render/controlled/mixed-page/stdlib-text-32 12.29Ki ± 0% +Render/controlled/mixed-page/templ-32 17.05Ki ± 0% +Render/controlled/conditional-heavy/stdlib-text-32 20.88Ki ± 0% +Render/controlled/conditional-heavy/templ-32 23.24Ki ± 0% +Render/controlled/fragment-heavy/stdlib-text-32 12.81Ki ± 0% +Render/controlled/fragment-heavy/templ-32 12.64Ki ± 0% +Render/controlled/fortunes-encoded/stdlib-html-32 4.674Ki ± 0% +Render/controlled/fortunes-encoded/templ-32 2.805Ki ± 0% +Render/controlled/encoded-loop/stdlib-html-32 3.913Mi ± 0% +Render/controlled/encoded-loop/templ-32 2.537Mi ± 0% +Render/idiomatic/composed-page/stdlib-text-32 61.63Ki ± 0% +Render/idiomatic/composed-page/templ-32 57.31Ki ± 0% +Render/idiomatic/trivial-substitution/stdlib-text-32 672.0 ± 0% +Render/idiomatic/trivial-substitution/templ-32 944.0 ± 0% +Render/idiomatic/large-loop/stdlib-text-32 386.6Ki ± 0% +Render/idiomatic/large-loop/templ-32 854.2Ki ± 0% +Render/idiomatic/mixed-page/stdlib-text-32 15.54Ki ± 0% +Render/idiomatic/mixed-page/templ-32 19.94Ki ± 0% +Render/idiomatic/conditional-heavy/stdlib-text-32 26.13Ki ± 0% +Render/idiomatic/conditional-heavy/templ-32 45.13Ki ± 0% +Render/idiomatic/fragment-heavy/stdlib-text-32 13.44Ki ± 0% +Render/idiomatic/fragment-heavy/templ-32 12.64Ki ± 0% +Render/idiomatic/fortunes-encoded/stdlib-html-32 5.174Ki ± 0% +Render/idiomatic/fortunes-encoded/templ-32 3.931Ki ± 0% +Render/idiomatic/encoded-loop/stdlib-html-32 3.983Mi ± 0% +Render/idiomatic/encoded-loop/templ-32 3.148Mi ± 0% +geomean 33.63Ki + + │ results\bench-render-20260808.txt │ + │ allocs/op │ +Render/controlled/composed-page/stdlib-text-32 187.0 ± 0% +Render/controlled/composed-page/templ-32 23.00 ± 0% +Render/controlled/trivial-substitution/stdlib-text-32 4.000 ± 0% +Render/controlled/trivial-substitution/templ-32 24.00 ± 0% +Render/controlled/large-loop/stdlib-text-32 14.75k ± 0% +Render/controlled/large-loop/templ-32 19.74k ± 0% +Render/controlled/mixed-page/stdlib-text-32 149.0 ± 0% +Render/controlled/mixed-page/templ-32 314.0 ± 0% +Render/controlled/conditional-heavy/stdlib-text-32 305.0 ± 0% +Render/controlled/conditional-heavy/templ-32 606.0 ± 0% +Render/controlled/fragment-heavy/stdlib-text-32 245.0 ± 0% +Render/controlled/fragment-heavy/templ-32 413.0 ± 0% +Render/controlled/fortunes-encoded/stdlib-html-32 155.0 ± 0% +Render/controlled/fortunes-encoded/templ-32 38.00 ± 0% +Render/controlled/encoded-loop/stdlib-html-32 124.9k ± 0% +Render/controlled/encoded-loop/templ-32 50.01k ± 0% +Render/idiomatic/composed-page/stdlib-text-32 187.0 ± 0% +Render/idiomatic/composed-page/templ-32 23.00 ± 0% +Render/idiomatic/trivial-substitution/stdlib-text-32 4.000 ± 0% +Render/idiomatic/trivial-substitution/templ-32 24.00 ± 0% +Render/idiomatic/large-loop/stdlib-text-32 14.75k ± 0% +Render/idiomatic/large-loop/templ-32 34.74k ± 0% +Render/idiomatic/mixed-page/stdlib-text-32 149.0 ± 0% +Render/idiomatic/mixed-page/templ-32 373.0 ± 0% +Render/idiomatic/conditional-heavy/stdlib-text-32 305.0 ± 0% +Render/idiomatic/conditional-heavy/templ-32 1.206k ± 0% +Render/idiomatic/fragment-heavy/stdlib-text-32 247.0 ± 0% +Render/idiomatic/fragment-heavy/templ-32 413.0 ± 0% +Render/idiomatic/fortunes-encoded/stdlib-html-32 155.0 ± 0% +Render/idiomatic/fortunes-encoded/templ-32 74.00 ± 0% +Render/idiomatic/encoded-loop/stdlib-html-32 124.9k ± 0% +Render/idiomatic/encoded-loop/templ-32 65.01k ± 0% +geomean 494.1 diff --git a/docs/benchmarks/2026-08-08/index.md b/docs/benchmarks/2026-08-08/index.md new file mode 100644 index 00000000..6c3ba55e --- /dev/null +++ b/docs/benchmarks/2026-08-08/index.md @@ -0,0 +1,429 @@ +# Cross-stack benchmark run — 2026-08-08 + +This run measures **fifteen template engines across six ecosystems** — .NET, Rust, the JVM, +JS/Node, Python and Go — over the program's **eight protocol workloads**, in **two tracks**, on +one machine in one session finishing 2026-08-08 04:45:52. Each ranked table carries sixteen rows: +the .NET leg contributes six engines, and Go's standard library appears as `text/template` on raw +workloads and `html/template` on encoded ones. Every ecosystem ran its own standard harness +(BenchmarkDotNet, Criterion, JMH, mitata, pyperf, `go test` + benchstat) and contributed that +harness's default central-tendency statistic, per the +[metrics protocol](../../../benchmarks/docs/metrics-protocol.md). + +Reproduce the whole run: + +```powershell +powershell -ExecutionPolicy Bypass -File benchmarks\run-all.ps1 +``` + +Per-ecosystem invocations are in [benchmarks/README.md](../../../benchmarks/README.md); the +.NET anchor alone is +`dotnet run -c Release --project benchmarks/dotnet -- bench-crossstack --filter **`. + +> **This is the protocol machine.** The program pins its cross-compared runs to the AMD Ryzen 9 +> 9950X / Windows 11 box +> ([metrics-protocol Q1.6](../../../benchmarks/docs/metrics-protocol.md#machine-and-environment-q16)), +> and that is where this run executed. What Windows does **not** have is the Linux runner's +> captured tuned state: there is no governor/boost control and no CPU-isolation boot entry on this +> side, so the machine posture is procedural — quiet machine, AC power, High Performance power +> plan, per-harness High priority classes — printed by the runner as rules rather than recorded as +> state. And the run is **unreplicated**: no cross-check on a second platform is currently +> published, so treat the ordering as this run's result rather than as an established fact about +> the engines. See [Limitations](#limitations). + +**The gate.** Every controlled-track cell passed the byte gate under the parity contract's closed +normalization list **N1, N2, N3, N3b, N4, N5**. N3b is the program-wide comparison-time rule that +strips **every** whitespace run, anywhere, to nothing from both the oracle and the candidate — so +the gate compares **non-whitespace bytes only**, and "byte-identical" throughout this report means +byte-identical after that disclosed pipeline, with entity spellings canonicalized by N5. +Whitespace differences therefore never disqualify a cell anywhere in this program. Encoded cells +additionally cleared the security floor, and every idiomatic-track cell passed the +functional-equivalence verifier — **143 cells, 143 green**. Every recorded step — thirteen gates, +the full measurement phase, the artifact copies and the report consolidation — exited 0, see +[summary.txt](summary.txt). Unlike the replaced report there is no honesty caveat to attach: the +JS launcher defect that let an aborted repeat sequence report success was fixed before this run, +and the two JS render steps each ran their full 38-pass shape +([The JS leg ran its full 38-pass shape](#the-js-leg-ran-its-full-38-pass-shape-this-time)). + +**Earlier reports.** `docs/benchmarks` keeps the latest run only +(amendment E15). The reports of +2026-07-11, 2026-07-18, 2026-07-25, 2026-08-02 and 2026-08-03 are removed, not corrected; their +numbers were honest measurements of their own harnesses and toolchains, and nothing here may be +compared against them. + +## Environment + +``` +Windows 11 (10.0.26200.8894/25H2), AMD Ryzen 9 9950X, 1 CPU, 16 physical / 32 logical cores +protocol machine (metrics-protocol Q1.6) · no tuned-state capture on this platform (posture is procedural) +run finished 2026-08-08 04:45:52 · mode MEASUREMENT · budget short · six ecosystems +repo commit not captured by the runner; 7674be01 was the newest commit when the run started +``` + +| Ecosystem | Harness | Toolchain as run | +| --- | --- | --- | +| .NET | BenchmarkDotNet 0.15.8, `ShortRun(LaunchCount=3, WarmupCount=3, IterationCount=3)`, `[MemoryDiagnoser]` | SDK 10.0.302 · .NET 10.0.10, X64 RyuJIT x86-64-v4 | +| Rust | Criterion, warmup 5 s + measure 26 s, 100 samples | rustc 1.97.1 (pinned by `rust-toolchain.toml`) | +| JVM | JMH 1.37, `Mode.AverageTime`, 5 forks × (1×2 s warmup + 5×1 s measure), `-prof gc` | JDK 25.0.4 LTS | +| JS | mitata 1.0.34 — **38 aggregated passes per render track**, each a separate node process | node v24.19.0 | +| Python | pyperf 2.10.0, 20 processes × 6 values × 1 warmup, `--affinity=4` | CPython 3.14.7 | +| Go | `go test -bench -count=28 -benchtime=1s` + benchstat | go1.26.5, templ v0.3.1020 | + +Run lengths come from the **`short` measurement budget**, whose unit is **one engine, not one +ecosystem** (amendment E6/E13/E14): +each engine's sixteen cells get ~10 minutes, so the .NET leg — six engines plus the Heddle-only +techniques, cold and internal sidebars — is about three times the other legs by construction. The +session ran 01:34:09 → 04:45:52, **3 h 12 min**. These are the second measured leg durations on +the protocol machine and the first with a real JS figure — the replaced report's JS leg aborted +after one pass, so its 0.8 min told E14's projection nothing: + +| Ecosystem | Measure phase | | Ecosystem | Measure phase | +| --- | ---: | --- | --- | ---: | +| .NET | 96.5 min | | Python | 17.0 min | +| Rust | 18.5 min | | Go | 19.2 min | +| JVM | 19.9 min | | JS | 19.9 min | + +The .NET figure splits into 75.4 min for the eight cross-stack suites and 21.1 min for the three +Heddle-only sidebars. + +### Toolchains: on pin, no drift — a first + +Every row of [toolchain.json](toolchain.json) records `drift: false`. This is the **first +published run of this program in which no toolchain drifted from its pin**, and it follows two +maintainer rulings issued on 2026-08-08, before the run: + +- **Node.js is pinned to the major line `v24.x`** + (amendment E18). The property the + pin holds constant — the V8 generation the JS rows describe — is major-versioned, and the old + exact-string pin was only ever satisfiable by disabling engine enforcement. This run's + **v24.19.0** satisfies the pin with `engine-strict` ON. +- **CPython is pinned to the minor line `3.14.x`** + (amendment E19) — same reasoning, + minor-versioned: micro releases are bugfix. This run's **3.14.7** satisfies the pin. + +Exactness is relocated, not lost: the precise versions a run actually used are recorded in +[toolchain.json](toolchain.json) and in the table above, and cross-run comparisons quote the +recorded version, never the pin. + +| Toolchain | Pinned | Actually ran | Note | +| --- | --- | --- | --- | +| .NET SDK | (observed line recorded) | 10.0.302 · runtime .NET 10.0.10 | no drift | +| Rust | 1.97.1 | rustc 1.97.1 | exact | +| JDK | Temurin 25 | JDK 25.0.4 LTS | on pin (major); distribution differs — [toolchain.json](toolchain.json) records the `java version` banner of an Oracle JDK, where Temurin reports `openjdk version` | +| Node.js | v24.x (E18) | v24.19.0 | on pin, `engine-strict` enforced | +| CPython | 3.14.x (E19) | 3.14.7 | on pin | +| Go | go1.26.x | go1.26.5 | on pin | +| templ | v0.3.1020 | v0.3.1020 | exact | + +Two consequences for reading the tables, relative to the replaced report: the JS rows describe +the pinned node 24 / V8 generation rather than a newer runtime, and the Python rows describe the +pinned CPython 3.14 interpreter generation — the earlier caveat that Jinja2 and Mako were read +pessimistically on 3.13 no longer applies. + +### Priority and affinity are not symmetric across harnesses + +pyperf ran pinned to a single logical core via `--affinity=4`. The other five harnesses ran +unpinned at High priority class. This is an asymmetry in the measurement conditions, not a +property of the engines, and it is one reason the cross-stack Python rows carry the +`reach/context` label rather than fair-fight standing. Whether pyperf's elevated-priority path +(which needs an elevated shell) was active is not recorded in the artifacts. + +## The workloads, and why they are presented in two tiers + +Eight workloads. "Golden output" is the byte length of the shared oracle in +[benchmarks/dotnet/GoldenCorpus](../../../benchmarks/dotnet/GoldenCorpus/README.md), verified by +SHA-256 against `manifest.json` by every harness before it measures anything. + +This report presents them in **two tiers rather than the normative protocol order**, because three +of the eight produce outputs far outside the size of a real page, and at those sizes the +measurement stops being dominated by template execution and starts being dominated by the +allocator. The boundary is not editorial: it is the **85,000-byte Large Object Heap threshold** in +the CLR, and the five workloads below it behave in one regime while the three above it behave in +another. The evidence is in +[Sizing regimes and the 85,000-byte boundary](#sizing-regimes-and-the-85-000-byte-boundary). + +### Tier 1 — realistic sizing + +Outputs from 338 B to 15.5 KB — the range a real page, partial or fragment actually occupies. +**These are the primary results of this run.** + +| # | Workload | What it measures | Suite | Golden output | +| ---: | --- | --- | --- | ---: | +| 1 | **`trivial-substitution`** | the per-render fixed-overhead floor | raw | 338 B | +| 2 | **`fortunes-encoded`** | escaping correctness at micro scale, 12 rows | **encoded** | 1,156 B | +| 3 | **`fragment-heavy`** | per-call composition, 48 calls | raw | 4,730 B | +| 4 | **`mixed-page`** | a realistic mixture, 36 rows | raw | 9,712 B | +| 5 | **`conditional-heavy`** | branch dispatch, 200 branches | raw | 15,549 B | + +### Tier 2 — edge-case sizing + +Rendered outputs from 54 KB to 852 KB. Every one of them exceeds 85,000 bytes once materialised +as UTF-16, so for the .NET engines each render lands on the Large Object Heap. **Read these with +the caveats attached to each**; they are stress tests, not page renders. + +| # | Workload | What it measures | Suite | Golden output | Rendered | As UTF-16 | +| ---: | --- | --- | --- | ---: | ---: | ---: | +| 6 | **`composed-page`** | layout/section/component composition | raw | 34,847 B | 54,401 chars | 108,802 B | +| 7 | **`large-loop`** | bulk iteration over 5,000 rows | raw | 192,780 B | 192,780 chars | 385,560 B | +| 8 | **`encoded-loop`** | escaping throughput, 5,000 rows | **encoded** | 831,685 B | 851,685 chars | 1,703,370 B | + +`composed-page` carries a second, independent caveat beyond its size — it contains **no per-item +computation at all**. See [The `composed-page` caveat](#the-composed-page-caveat). + +Every workload carries a controlled byte gate and an idiomatic verifier; the two encoded workloads +additionally carry the security floor. The [consolidated tables](consolidated-tables.md) are the +machine-generated, `--check`-reproducible appendix; since +amendment E7 their ordering is also +tier-derived — computed from rendered size by `consolidate.py`, never declared per workload — +while the normative protocol numbering 1–8 stays recorded in `manifest.json` and the phase specs. + +> Encoded workloads confine untrusted data to HTML text and attribute-value contexts, where flat +> and contextual encoders emit the same escaped output. These numbers therefore measure escaping +> cost in confined contexts and cannot show the differentiating benefit of contextual encoding; a +> contextual encoder's encoded-suite result must not be read as 'context awareness is pure +> overhead.' + +## How to read these tables + +> **Controlled track** — byte-identical, equivalently-authored templates under the parity +> contract's closed normalization pipeline. These numbers answer *"how fast is the engine"* on +> identical work. They may be used to compare engine execution speed on a given workload — and +> nothing else. + +> **Idiomatic track** — functionally-equivalent templates written the way each engine's own +> documentation teaches, verified by the functional-equivalence gate. These numbers answer +> *"how fast is the practitioner experience."* They may be used to compare what a practitioner +> gets writing each engine's documented style; they must not be read as engine execution-speed +> rankings. + +There is **no aggregate score, no overall winner and no single-number verdict** in this program. +One ranking per workload, and that is all that may be quoted. + +> **The two `Heddle (utf8 sink)` / `Heddle (textwriter sink)` rows are techniques, not +> competitors.** They stream the render into a caller-owned buffer that is allocated once in +> untimed setup, pre-sized past the output's high-water mark, and reused across iterations — +> the sink's output is byte-verified against the gated string render in the same process before +> anything is timed, so the bytes are produced on every iteration, but nothing is materialised. +> Every competitor row, Heddle's own anchor included, materialises a string. Consequently their +> time is a streaming floor, their `Allocated` is steady-state GC pressure rather than the cost +> of owning the output (the buffer's working set is on the order of the output itself), and +> both columns compare different work from every other row. They are **excluded from every +> ranking and every margin** in this report; the tables mark them `‡` with the same caveat +> where they appear. + +Full tables, per workload and per ecosystem, plus the allocation sidebars and the plausibility +register: **[consolidated tables](consolidated-tables.md)**. + +## Findings + +The tables below are **generated** by `benchmarks/report/consolidate.py` and embedded here — no +figure on this page is transcribed by hand. Regenerate with +`python benchmarks/report/consolidate.py docs/benchmarks/2026-08-08`; verify with `--check`. + + + +### What Tier 1 shows + +Heddle is **fastest of the six .NET engines on all five** realistic-sized workloads, by **2.25× to +3.64×** — widest on `fragment-heavy` (per-call composition), narrowest on `fortunes-encoded` +(escaping at micro scale). + +Cross-stack it is **top-4 on all five**: **#2** on `fortunes-encoded` and `mixed-page` (behind +only **Askama**, the Rust compile-time engine), **#3** on `trivial-substitution` and +`fragment-heavy`, **#4** on `conditional-heavy`. The only engines ahead of it anywhere in Tier 1 +are Askama (on all five), **JTE** (JVM, compiled to Java source — on two) and **eta** (JS — on +two). It is ahead of Tera, templ, `text/template`, handlebars, Thymeleaf, Jinja2, Mako and every +other .NET engine on all five. + +**Askama is the only engine faster than Heddle on all eight workloads.** It is a Rust compile-time +template engine — the same architectural bet Heddle makes, compile the document rather than +interpret it, executed in a language without a managed runtime. + +**The .NET idiomatic anchor holds.** The rebuilt .NET leg measures both fairness tracks +(amendment E12 discharged Phase 1 +D15's controlled-only scope), and the idiomatic tables anchor to a real Heddle idiomatic row: on +every Tier 1 workload it prices Heddle's documented authoring style within 10% of the controlled +row (ratio 0.99–1.10 in the generated tables). + +### What this run replaces, and why + +This run replaces the 2026-08-03 report under +amendment E15's latest-run-only rule, +and the replacement is a **measurement-quality re-issue, not a new engine state**. Between the +two runs nothing under `src/` changed — every intervening commit touched the harness, the pins or +the report: the JS launcher fix (a null exit code no longer propagates as success), the E18/E19 +pin re-scopes, and report annotations. What this run repairs is the measurement itself: the JS +leg ran its full 38-pass aggregation instead of collapsing to one pass per track, and all seven +toolchains ran on pin instead of two drifting. The .NET field ordering this run reports matches +what the replaced report reported, but that is provenance, not a comparison: the program's +standing rule is that **figures are never mixed across runs**, the old directory is removed +rather than corrected, and no cross-run delta is quoted here. + +What this run's gate states about execution tiers: **five of the eight workloads render +precompiled** (`trivial-substitution`, `large-loop`, `mixed-page`, `conditional-heavy`, +`fragment-heavy`); `composed-page`, `fortunes-encoded` and `encoded-loop` are refused by +precompilation and render on the runtime backend — the two tiers are byte-identical by contract, +and the gate's `PRECOMPILED-COVERAGE` line records the split every run. + +### What Tier 2 shows, and how to read it + +- **`encoded-loop` is the one workload where Heddle is not the fastest .NET engine.** + Handlebars.Net leads it at 0.97×, and Razor sits at 1.00× (1,761.1 μs against Heddle's + 1.766 ms) — inside overlapping dispersion. Handlebars.Net led this workload on the removed + 2026-07-25, 2026-08-02 and 2026-08-03 runs as well — across two rebuilds of the .NET harness — + so the *ordering* is a reproduced result rather than noise. It is escaping throughput over a + 5,000-row payload — an 852 KB output no page produces, but a real signal about the encoder's + bulk path. +- **`composed-page` is where Heddle's cross-stack rank collapses to #11**, and that number is + *not* a statement about composition machinery. It is an allocator cliff plus a degenerate + workload — see [Sizing regimes](#sizing-regimes-and-the-85-000-byte-boundary) and + [The `composed-page` caveat](#the-composed-page-caveat). Do not quote the #11 without them. +- `large-loop` at #6 is the least distorted of the three: it crosses the LOH boundary, but it also + contains genuine per-row work, so the allocator is a smaller share of the measurement. + +### Razor is measured on every workload + +Since the .NET leg rebuild +(amendment E12), ASP.NET Core Razor is +a full member of all eight workloads and both tracks, under the same parity gate as every other +engine — the earlier single-workload Razor figure is superseded. On the controlled track Heddle +leads it by **2.51× to 37.07×** at Tier 1 sizes and **1.90×** on `composed-page`; on +`encoded-loop` Razor is marginally ahead (a 1.00× ratio in the generated tables, within +overlapping dispersion). Both engines pay the same Large Object Heap cost on the Tier 2 rows, +which compresses margins there relative to Tier 1. + +### The JS leg ran its full 38-pass shape this time + +The replaced report disclosed that its JS leg had collapsed to one mitata pass per track: the +`run.ps1` launcher read a null exit code back from its first pass, aborted the 38-pass sequence, +and propagated the null as success. That defect was fixed before this run, and this run executed +the intended shape (amendment E6/E14): **38 consecutive passes per render track, each a separate +node process** — ~588 s per track — with the Phase 4 D13 stability verdict computed from them. + +The verdicts, from the published stability artifacts: + +- **Controlled track — `STABILITY: verified-with-disclosure`** + ([stability-summary-controlled.md](js/stability-summary-controlled.md)): across 16 cells the + cross-pass RSD of mitata's `avg` is **median 1.41%, max 5.11%** — the max is handlebars on + `mixed-page`, the single cell in D13's 5–10% disclosure band (none above 10%, which would have + blocked publication). Per D13 that band is publishable **only if the report carries the table**, + so it is embedded below. +- **Idiomatic track — `STABILITY: verified`** + ([stability-summary-idiomatic.md](js/stability-summary-idiomatic.md)): **median 1.77%, max + 4.77%** (handlebars on `large-loop`); no cell above 5%. + +The published `controlled.json` / `idiomatic.json` carry the aggregate — `stats.avg` is the +median of the per-pass averages and `stats.min`/`stats.max` span the passes — so the JS +dispersion column in this report's tables is **cross-process variation**, not a single pass's +min…max. Every one of the 76 passes asserted `MATERIALISATION-CHECK: clean` before writing its +artifact, so every JS figure is materialised output, not the V8 `ConsString` rope artifact +(amendment E4). The JS rows keep +their `reach/context` evidence standing. The verdict is independently recomputable from the +published aggregates alone — each cell in [controlled.json](js/controlled.json) / +[idiomatic.json](js/idiomatic.json) carries its `perPassAvg` array, the 38 per-pass averages +the RSD is computed over; the raw per-pass captures stay with the run's out directory and are +not republished here, the same way the runner's logs are not. + + + +## Sizing regimes and the 85,000-byte boundary + +The CLR allocates any object of **85,000 bytes or more on the Large Object Heap**. .NET strings +are UTF-16, so a rendered page crosses that line at **42,500 characters** — and every render that +crosses it allocates on the LOH and drives a full, blocking Gen2 collection. Three of the eight +workloads are above the line once materialised; five are comfortably below it (31,098 B as UTF-16, +the largest), which is why the Tier 1 rows compare cleanly. + +The magnitude of the cliff was measured when the boundary was first identified, on the 2026-07-25 +run's box: string-copy throughput fell from 40.3 B/ns just below the threshold to 8.9 B/ns just +above it — a 4.5× step. That measurement is recorded in +amendment E7 and was **not re-derived +on this machine**; what this run's own artifacts show is the consequence: in the +[allocation sidebar](consolidated-tables.md#per-ecosystem-sidebars--not-cross-comparable), +Heddle's `composed-page` render reports Gen0, Gen1 and Gen2 collection counts that are **equal** +(3.1128 per thousand operations each) — essentially every collection is a full one. + +None of the other five ecosystems has this cliff. Their outputs are UTF-8 or Latin-1 and stay on +the normal heap. So on Tier 2, the .NET column is paying a cost that is structural to the runtime +and absent everywhere else. + +### The `composed-page` caveat + +Beyond its size, `composed-page` has a second problem: **it contains no per-item computation.** +The output is 17 pre-existing string fragments concatenated in order — no loop body, no branch, +no escaping, no formatting. Every compiled engine reduces it to about 17 `memcpy` calls, so the +row measures memory bandwidth and allocator behaviour, not template execution. +Amendment E7 records the floor +measurements behind that analysis (a hand-written .NET `string.Concat` of the same fragments sits +within ~2× of Heddle's figure); they were taken on the 2026-07-25 run's box and are cited here as +prior evidence, not re-measured. The `#11 of 16` rank is real as a measurement and misleading as a +statement about the engine. + +Two further notes on this row: + +- **The `implied B/ns` numerator is the rendered size, not the golden.** The golden oracle is + stored in its normalized form — inter-tag whitespace is collapsed before export — so on + `composed-page` it is 1.56× smaller than what the engines emit (34,847 B stored against 54,401 + chars rendered). The generated tables divide by the rendered size, carried in `consolidate.py`'s + `RENDERED_CHARS` constants. In this run the highest implied throughput anywhere is **43.9 B/ns** + — the `‡` Heddle textwriter-sink streaming row on `composed-page`, which is excluded from every + ranking; the highest *ranked* cell is Askama's `composed-page` controlled row at **37.4 B/ns** — + all under the 50 B/ns plausibility ceiling; **no cell trips the ceiling** — see the + [plausibility register](consolidated-tables.md#plausibility-register). +- The fixture also exercises a known `@<<` layout-extend limitation documented in + [GoldenCorpus/README.md](../../../benchmarks/dotnet/GoldenCorpus/README.md), which is why the + golden output is the fragment sequence rather than a full chrome-bearing page. + +## Limitations + +1. **The protocol machine, but unreplicated.** This run satisfies Q1.6's machine pin, but no + finding here has been reproduced on a second platform: the Linux cross-check (Phase 8) has no + current published run, and every earlier report is removed under + amendment E15. Treat the ordering + as this run's result. +2. **The `short` budget, not `baseline`.** Every leg ran the ~10 min-per-engine `short` shape + (E6/E13/E14): .NET at `ShortRun` with `LaunchCount 3`, JMH at 5 forks × 5×1 s, Criterion at + 26 s, Go at `-count=28`, pyperf at 6 values, mitata at 38 passes per track. The + ~30 min-per-engine `baseline` shape has never been measured on this machine, and E14's + projected durations are unchecked beyond the leg totals recorded above. +3. **Windows has no captured tuned state.** The Linux runner records governor/boost and offers an + isolation boot entry; this platform's runner prints procedural rules (quiet machine, AC power, + High Performance plan, priority classes) and records nothing about the machine state beyond + the toolchain block. Absolute times are not comparable with tuned boost-off runs on the same + physical box. +4. **Measurement conditions are not symmetric across harnesses** — pyperf pinned to one logical + core, the other five unpinned; whether pyperf's elevated-priority path was active is not + recorded in the artifacts. +5. **One controlled JS cell sits in the D13 disclosure band** — handlebars on `mixed-page` at + 5.11% cross-pass RSD, which is why the controlled verdict is `verified-with-disclosure` + rather than `verified` and why the stability table is carried in this report. No cell is + above 10%. +6. **Three workloads render on Heddle's runtime backend**, because precompilation refuses them + (`composed-page`, `fortunes-encoded`, `encoded-loop` — the gate's `PRECOMPILED-COVERAGE` + line). The two tiers are byte-identical by contract, but readers should know both encoded + workloads fall in this group. +7. **Encoded workloads are confined** — see the caveat under [The workloads](#the-workloads-and-why-they-are-presented-in-two-tiers). +8. **Go contributes one engine across two surfaces** — `text/template` on the six raw workloads + and `html/template` on the two encoded ones — plus templ. Read the Go rows accordingly. +9. **JS and Python carry `reach/context` evidence standing**, not `fair fight`; their rows answer + "what does this ecosystem reach" rather than ranking engines against the others. +10. **One machine, one date.** Numbers are hardware-, platform- and date-specific. Run the suite + on your own target with a page shaped like your real one before quoting anything. +11. **The two-tier presentation is a derived ordering, not a protocol change.** The normative + workload numbering is unchanged and still recorded in `manifest.json` and the phase specs. + `consolidate.py` classifies a workload by whether its rendered output reaches 85,000 bytes as + UTF-16 and orders every generated table accordingly; nothing in this report is ordered by + hand. +12. **The tier boundary depends on measured constants carried from an earlier run.** The + `RENDERED_CHARS` values in `consolidate.py` were measured on 2026-07-25 and were not + re-measured here; they must be re-measured if templates or models change. A workload missing + from them falls back to the golden size and is footnoted in the generated tables rather than + silently misclassified. +13. **The mitata heap column is not a materialisation test.** It reports a *net* heap delta across + a batch, so garbage reclaimed inside the batch is invisible to it and a correct render can + show a near-zero figure. The authoritative control is the harness-side + `MATERIALISATION-CHECK`; the [consolidated tables](consolidated-tables.md) state this in full. +14. **No figure here may be compared with any removed report.** The replaced 2026-08-03 run + measured the same engine code, but through a JS leg that collapsed to one pass per track and + with two toolchains off pin; it is removed under + amendment E15, not corrected. Do + not mix figures across runs — this run's tables are the only ones this repository publishes. diff --git a/docs/benchmarks/2026-08-08/js/cold-compile.json b/docs/benchmarks/2026-08-08/js/cold-compile.json new file mode 100644 index 00000000..23aa974e --- /dev/null +++ b/docs/benchmarks/2026-08-08/js/cold-compile.json @@ -0,0 +1,38383 @@ +[ + { + "kind": "static", + "args": {}, + "alias": "handlebars composed-page", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 150300, + 150300, + 150400, + 150400, + 150600, + 150600, + 150700, + 150700, + 150700, + 150700, + 150700, + 150800, + 150800, + 150800, + 150800, + 150900, + 150999.99999952316, + 151000, + 151000, + 151000, + 151100, + 151100, + 151100, + 151200, + 151200, + 151200, + 151200, + 151300, + 151300, + 151300, + 151300, + 151300, + 151300, + 151300, + 151300, + 151300, + 151300, + 151300, + 151300, + 151300, + 151399.99999952316, + 151400, + 151400, + 151400.00000095367, + 151500, + 151500, + 151500, + 151500, + 151500, + 151500, + 151500, + 151500, + 151500, + 151500, + 151500, + 151600, + 151600, + 151600, + 151600, + 151600, + 151600, + 151600, + 151600, + 151600, + 151600, + 151600, + 151600, + 151600, + 151600, + 151699.99999904633, + 151700, + 151700, + 151700, + 151700, + 151700, + 151700, + 151700.00000047684, + 151799.99999952316, + 151799.99999952316, + 151799.99999952316, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151800, + 151899.99999952316, + 151900, + 151900, + 151900, + 151900, + 151900, + 151900, + 151900, + 151900, + 151900, + 151900, + 151900, + 151900, + 151900, + 151900, + 151900.00000095367, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152000, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100, + 152100.00000047684, + 152100.00000047684, + 152100.00000047684, + 152199.99999952316, + 152199.99999952316, + 152199.99999952316, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200, + 152200.00000047684, + 152200.00000047684, + 152299.99999952316, + 152299.99999952316, + 152299.99999952316, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152300, + 152399.99999952316, + 152399.99999952316, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152400, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500, + 152500.00000047684, + 152500.00000047684, + 152500.00000047684, + 152500.00000047684, + 152599.99999952316, + 152599.99999952316, + 152599.99999952316, + 152599.99999952316, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600, + 152600.00000047684, + 152600.00000047684, + 152600.00000047684, + 152699.99999952316, + 152699.99999952316, + 152699.99999952316, + 152699.99999952316, + 152699.99999952316, + 152699.99999952316, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700, + 152700.00000047684, + 152700.00000047684, + 152700.00000047684, + 152700.00000047684, + 152700.00000047684, + 152700.00000047684, + 152799.99999952316, + 152799.99999952316, + 152799.99999952316, + 152799.99999952316, + 152799.99999952316, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152800, + 152899.99999904633, + 152899.99999904633, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900, + 152900.00000047684, + 152999.99999904633, + 152999.99999904633, + 152999.99999952316, + 152999.99999952316, + 152999.99999952316, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000, + 153000.00000047684, + 153000.00000047684, + 153000.00000047684, + 153000.00000047684, + 153000.00000047684, + 153000.00000047684, + 153000.00000047684, + 153000.00000047684, + 153000.00000047684, + 153000.00000047684, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153099.99999952316, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100, + 153100.00000047684, + 153100.00000047684, + 153100.00000047684, + 153100.00000047684, + 153100.00000047684, + 153100.00000047684, + 153100.00000047684, + 153199.99999952316, + 153199.99999952316, + 153199.99999952316, + 153199.99999952316, + 153199.99999952316, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200, + 153200.00000047684, + 153299.99999952316, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300, + 153300.00000047684, + 153300.00000095367, + 153300.00000095367, + 153300.00000095367, + 153399.99999904633, + 153399.99999904633, + 153399.99999904633, + 153399.99999904633, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400, + 153400.00000047684, + 153400.00000047684, + 153400.00000047684, + 153400.00000047684, + 153400.00000047684, + 153400.00000047684, + 153400.00000047684, + 153400.00000047684, + 153499.99999904633, + 153499.99999904633, + 153499.99999904633, + 153499.99999952316, + 153499.99999952316, + 153499.99999952316, + 153499.99999952316, + 153499.99999952316, + 153499.99999952316, + 153499.99999952316, + 153499.99999952316, + 153499.99999952316, + 153499.99999952316, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153500.00000047684, + 153599.99999952316, + 153599.99999952316, + 153599.99999952316, + 153599.99999952316, + 153599.99999952316, + 153599.99999952316, + 153599.99999952316, + 153599.99999952316, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600, + 153600.00000047684, + 153600.00000047684, + 153600.00000047684, + 153600.00000047684, + 153600.00000047684, + 153600.00000047684, + 153600.00000095367, + 153600.00000095367, + 153699.99999952316, + 153699.99999952316, + 153699.99999952316, + 153699.99999952316, + 153699.99999952316, + 153699.99999952316, + 153699.99999952316, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700, + 153700.00000095367, + 153700.00000095367, + 153700.00000095367, + 153700.00000095367, + 153700.00000095367, + 153700.00000095367, + 153700.00000095367, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800, + 153800.00000047684, + 153800.00000047684, + 153899.99999904633, + 153899.99999904633, + 153899.99999904633, + 153899.99999904633, + 153899.99999904633, + 153899.99999904633, + 153899.99999904633, + 153899.99999904633, + 153899.99999904633, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153900.00000047684, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 153999.99999952316, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154000.00000047684, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154099.99999952316, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100, + 154100.00000047684, + 154100.00000047684, + 154100.00000047684, + 154100.00000095367, + 154100.00000095367, + 154100.00000095367, + 154100.00000095367, + 154199.99999952316, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200, + 154200.00000095367, + 154299.99999904633, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300, + 154300.00000047684, + 154300.00000047684, + 154300.00000047684, + 154300.00000047684, + 154300.00000047684, + 154300.00000047684, + 154300.00000047684, + 154300.00000047684, + 154300.00000047684, + 154399.99999952316, + 154399.99999952316, + 154399.99999952316, + 154399.99999952316, + 154399.99999952316, + 154399.99999952316, + 154399.99999952316, + 154399.99999952316, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400, + 154400.00000047684, + 154400.00000047684, + 154400.00000047684, + 154400.00000047684, + 154400.00000047684, + 154400.00000047684, + 154400.00000047684, + 154400.00000047684, + 154400.00000047684, + 154400.00000047684, + 154400.00000047684, + 154400.00000047684, + 154499.99999952316, + 154499.99999952316, + 154499.99999952316, + 154499.99999952316, + 154499.99999952316, + 154499.99999952316, + 154499.99999952316, + 154499.99999952316, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500, + 154500.00000047684, + 154500.00000047684, + 154500.00000047684, + 154500.00000047684, + 154500.00000047684, + 154500.00000047684, + 154500.00000047684, + 154500.00000095367, + 154500.00000095367, + 154599.99999952316, + 154599.99999952316, + 154599.99999952316, + 154599.99999952316, + 154599.99999952316, + 154599.99999952316, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600, + 154600.00000095367, + 154600.00000095367, + 154600.00000095367, + 154699.99999904633, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700, + 154700.00000047684, + 154700.00000047684, + 154799.99999904633, + 154799.99999952316, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800, + 154800.00000047684, + 154800.00000047684, + 154800.00000047684, + 154800.00000047684, + 154800.00000047684, + 154800.00000047684, + 154800.00000047684, + 154800.00000047684, + 154800.00000047684, + 154899.99999952316, + 154899.99999952316, + 154899.99999952316, + 154899.99999952316, + 154899.99999952316, + 154899.99999952316, + 154899.99999952316, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900, + 154900.00000047684, + 154900.00000047684, + 154900.00000047684, + 154900.00000047684, + 154900.00000047684, + 154900.00000047684, + 154900.00000047684, + 154900.00000047684, + 154900.00000047684, + 154900.00000047684, + 154900.00000047684, + 154900.00000047684, + 154999.99999952316, + 154999.99999952316, + 154999.99999952316, + 154999.99999952316, + 154999.99999952316, + 154999.99999952316, + 154999.99999952316, + 154999.99999952316, + 154999.99999952316, + 154999.99999952316, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000, + 155000.00000047684, + 155000.00000095367, + 155000.00000095367, + 155000.00000095367, + 155099.99999952316, + 155099.99999952316, + 155099.99999952316, + 155099.99999952316, + 155099.99999952316, + 155099.99999952316, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100, + 155100.00000095367, + 155199.99999904633, + 155199.99999904633, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200, + 155200.00000047684, + 155200.00000047684, + 155200.00000047684, + 155200.00000047684, + 155299.99999952316, + 155299.99999952316, + 155299.99999952316, + 155299.99999952316, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300, + 155300.00000047684, + 155300.00000047684, + 155300.00000047684, + 155300.00000047684, + 155300.00000047684, + 155300.00000047684, + 155399.99999952316, + 155399.99999952316, + 155399.99999952316, + 155399.99999952316, + 155399.99999952316, + 155399.99999952316, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400, + 155400.00000047684, + 155400.00000095367, + 155499.99999952316, + 155499.99999952316, + 155499.99999952316, + 155499.99999952316, + 155499.99999952316, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155500, + 155599.99999904633, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600, + 155600.00000047684, + 155600.00000047684, + 155600.00000047684, + 155699.99999952316, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700, + 155700.00000047684, + 155700.00000047684, + 155799.99999952316, + 155799.99999952316, + 155799.99999952316, + 155799.99999952316, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800, + 155800.00000047684, + 155800.00000047684, + 155800.00000047684, + 155899.99999952316, + 155899.99999952316, + 155899.99999952316, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900, + 155900.00000095367, + 155999.99999952316, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000, + 156000.00000095367, + 156099.99999904633, + 156100, + 156100, + 156100, + 156100, + 156100, + 156100, + 156100, + 156100, + 156100, + 156100, + 156100, + 156100, + 156100.00000047684, + 156199.99999904633, + 156199.99999952316, + 156199.99999952316, + 156199.99999952316, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200, + 156200.00000047684, + 156200.00000047684, + 156299.99999952316, + 156299.99999952316, + 156299.99999952316, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300, + 156300.00000047684, + 156300.00000095367, + 156300.00000095367, + 156300.00000095367, + 156300.00000095367, + 156399.99999952316, + 156399.99999952316, + 156400, + 156400, + 156400, + 156400, + 156400, + 156400, + 156400, + 156400, + 156400, + 156400, + 156400, + 156400, + 156400, + 156400, + 156400.00000095367, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500, + 156500.00000047684, + 156599.99999952316, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600, + 156600.00000047684, + 156600.00000047684, + 156600.00000047684, + 156699.99999952316, + 156699.99999952316, + 156699.99999952316, + 156699.99999952316, + 156699.99999952316, + 156700, + 156700, + 156700, + 156700, + 156700, + 156700, + 156700, + 156700, + 156700, + 156700, + 156700, + 156700, + 156700, + 156700, + 156700.00000047684, + 156799.99999952316, + 156799.99999952316, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800, + 156800.00000047684, + 156800.00000095367, + 156899.99999952316, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156900, + 156999.99999904633, + 157000, + 157000, + 157000, + 157000, + 157000, + 157000, + 157000, + 157000, + 157000, + 157000, + 157000, + 157000, + 157000.00000047684, + 157000.00000047684, + 157000.00000047684, + 157099.99999904633, + 157100, + 157100, + 157100, + 157100, + 157100, + 157100, + 157100, + 157100, + 157100, + 157100, + 157100.00000047684, + 157100.00000047684, + 157199.99999952316, + 157199.99999952316, + 157199.99999952316, + 157200, + 157200, + 157200, + 157200, + 157200, + 157200, + 157200, + 157200, + 157200, + 157200, + 157200, + 157200, + 157200, + 157200, + 157200.00000047684, + 157299.99999952316, + 157299.99999952316, + 157299.99999952316, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157300, + 157399.99999904633, + 157400, + 157400, + 157400, + 157400, + 157400, + 157400, + 157400, + 157400, + 157400, + 157400, + 157400, + 157400, + 157400.00000047684, + 157400.00000047684, + 157499.99999904633, + 157499.99999904633, + 157499.99999904633, + 157500, + 157500, + 157500, + 157500, + 157500, + 157500, + 157500, + 157500, + 157500, + 157500.00000047684, + 157599.99999952316, + 157600, + 157600, + 157600, + 157600, + 157600, + 157600, + 157600, + 157600, + 157600, + 157600.00000047684, + 157600.00000047684, + 157600.00000047684, + 157600.00000047684, + 157699.99999952316, + 157699.99999952316, + 157699.99999952316, + 157699.99999952316, + 157700, + 157700, + 157700, + 157700, + 157700, + 157700, + 157700, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157800, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900, + 157900.00000047684, + 158000, + 158000, + 158000, + 158000, + 158000, + 158000, + 158000, + 158000, + 158000, + 158000, + 158000.00000047684, + 158099.99999952316, + 158100, + 158100, + 158100, + 158100, + 158100, + 158100, + 158100, + 158100, + 158100, + 158100, + 158100, + 158100.00000095367, + 158200, + 158200, + 158200, + 158200, + 158200, + 158200, + 158200, + 158200, + 158200, + 158200, + 158200, + 158200, + 158200, + 158300, + 158300, + 158300, + 158300, + 158300, + 158300, + 158300, + 158300, + 158300, + 158300, + 158300, + 158400, + 158400, + 158400, + 158400, + 158400, + 158400, + 158400, + 158400, + 158400, + 158400, + 158400, + 158400, + 158400.00000047684, + 158400.00000047684, + 158400.00000047684, + 158499.99999952316, + 158499.99999952316, + 158499.99999952316, + 158500, + 158500, + 158500, + 158500, + 158500, + 158500, + 158500, + 158500, + 158500, + 158500, + 158500, + 158500.00000047684, + 158500.00000047684, + 158599.99999952316, + 158599.99999952316, + 158600, + 158600, + 158600, + 158600, + 158600, + 158600, + 158600, + 158600, + 158600, + 158699.99999952316, + 158700, + 158700, + 158700, + 158700, + 158700, + 158700, + 158700, + 158700, + 158700, + 158700, + 158700, + 158700, + 158700, + 158700, + 158700, + 158800, + 158800, + 158800, + 158800, + 158800, + 158800, + 158800, + 158800, + 158800, + 158899.99999952316, + 158900, + 158900, + 158900, + 158900, + 158900, + 158900, + 158900, + 158900, + 158900.00000047684, + 159000, + 159000, + 159000, + 159000, + 159000, + 159000, + 159000, + 159000, + 159000, + 159000.00000095367, + 159099.99999952316, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159100, + 159200, + 159200, + 159200, + 159200, + 159200, + 159200, + 159300, + 159300, + 159300, + 159400, + 159400, + 159400, + 159400, + 159400, + 159400, + 159400, + 159400.00000047684, + 159500, + 159500, + 159500, + 159500, + 159500, + 159500, + 159500, + 159600, + 159600, + 159600, + 159600, + 159600, + 159700, + 159700, + 159700, + 159700, + 159700, + 159700, + 159700, + 159700, + 159800, + 159800, + 159800, + 159800, + 159800, + 159899.99999952316, + 159899.99999952316, + 159899.99999952316, + 159900, + 159900, + 159900, + 159900, + 159900, + 159900, + 159900, + 159900, + 159900, + 159900, + 159900, + 160000, + 160000, + 160000, + 160000, + 160000, + 160100, + 160100, + 160100, + 160100, + 160100, + 160100, + 160200, + 160200, + 160200, + 160200, + 160200, + 160200, + 160200, + 160200, + 160200, + 160200, + 160200.00000047684, + 160299.99999952316, + 160300, + 160300, + 160300, + 160300, + 160300, + 160300, + 160300.00000047684, + 160400, + 160400, + 160400, + 160400, + 160400, + 160500, + 160500, + 160500, + 160500, + 160500, + 160500, + 160500, + 160500, + 160500, + 160600, + 160600, + 160700, + 160700, + 160700, + 160700, + 160700, + 160799.99999952316, + 160800, + 160800, + 160800, + 160900, + 160900, + 160900, + 160900, + 160900, + 160900, + 160900, + 160900, + 161000, + 161000, + 161000, + 161100, + 161100, + 161100, + 161100, + 161100, + 161100, + 161100.00000047684, + 161200, + 161200, + 161200, + 161200, + 161200, + 161200, + 161200, + 161200.00000047684, + 161299.99999952316, + 161300, + 161300, + 161300, + 161300, + 161300.00000095367, + 161400, + 161400, + 161400, + 161500, + 161500, + 161600, + 161600, + 161600, + 161600, + 161600, + 161600, + 161600, + 161600, + 161600, + 161700, + 161700, + 161700, + 161700, + 161700, + 161700, + 161700, + 161700, + 161700, + 161800, + 161800, + 161800, + 161800, + 161900, + 161900, + 161900, + 161900, + 161900, + 161900, + 161900, + 161900, + 161900, + 161900, + 161900, + 161900, + 161900, + 161900, + 162000, + 162000, + 162000, + 162000, + 162000, + 162000, + 162000, + 162099.99999952316, + 162100, + 162100, + 162100, + 162100, + 162100, + 162100, + 162100, + 162100, + 162100, + 162100, + 162100, + 162100, + 162199.99999952316, + 162200, + 162200, + 162200, + 162200, + 162200, + 162200, + 162200, + 162200, + 162200, + 162200, + 162200, + 162200, + 162300, + 162300, + 162300, + 162300, + 162300, + 162300, + 162300, + 162300, + 162300, + 162300, + 162300, + 162300, + 162300, + 162300, + 162400, + 162400, + 162400, + 162499.99999952316, + 162500, + 162500, + 162500, + 162500, + 162500, + 162500, + 162500, + 162500, + 162500.00000047684, + 162500.00000047684, + 162600, + 162600, + 162600, + 162600, + 162600, + 162600, + 162600, + 162600, + 162600.00000047684, + 162700, + 162700, + 162700, + 162700, + 162700, + 162700, + 162700, + 162700, + 162700, + 162700, + 162700, + 162700, + 162700.00000095367, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162800, + 162899.99999952316, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900, + 162900.00000047684, + 162999.99999952316, + 162999.99999952316, + 163000, + 163000, + 163000, + 163000, + 163000, + 163000, + 163000, + 163000, + 163000, + 163000, + 163000.00000047684, + 163099.99999952316, + 163100, + 163100, + 163100, + 163100, + 163100, + 163100, + 163100, + 163100, + 163100, + 163100, + 163100, + 163100.00000047684, + 163100.00000047684, + 163100.00000047684, + 163100.00000095367, + 163100.00000095367, + 163200, + 163200, + 163200, + 163200, + 163200, + 163200, + 163200, + 163200, + 163200, + 163200, + 163200, + 163200, + 163300, + 163300, + 163300, + 163300, + 163300, + 163300.00000047684, + 163399.99999952316, + 163399.99999952316, + 163400, + 163400, + 163400, + 163400, + 163400, + 163400, + 163400, + 163400, + 163400, + 163400, + 163400, + 163400, + 163499.99999952316, + 163499.99999952316, + 163499.99999952316, + 163500, + 163500, + 163500, + 163500, + 163500, + 163500, + 163500, + 163500, + 163500, + 163500.00000047684, + 163500.00000047684, + 163500.00000047684, + 163500.00000095367, + 163599.99999952316, + 163599.99999952316, + 163600, + 163600, + 163600, + 163600, + 163600, + 163600, + 163600, + 163600, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163700, + 163799.99999952316, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800, + 163800.00000047684, + 163800.00000047684, + 163800.00000047684, + 163800.00000047684, + 163800.00000047684, + 163899.99999952316, + 163899.99999952316, + 163900, + 163900, + 163900, + 163999.99999952316, + 163999.99999952316, + 163999.99999952316, + 163999.99999952316, + 164000, + 164000, + 164000, + 164000, + 164000, + 164000, + 164000, + 164000, + 164000, + 164000, + 164000, + 164000, + 164000, + 164000.00000095367, + 164000.00000095367, + 164100, + 164100, + 164100, + 164100, + 164100, + 164100, + 164100, + 164100, + 164100, + 164100, + 164100, + 164100, + 164100, + 164100, + 164100.00000095367, + 164199.99999904633, + 164200, + 164200, + 164200, + 164200, + 164200, + 164200, + 164200, + 164200, + 164200, + 164200, + 164200, + 164200.00000047684, + 164200.00000047684, + 164200.00000047684, + 164300, + 164300, + 164300, + 164300, + 164300, + 164300, + 164300, + 164300, + 164300, + 164300.00000047684, + 164300.00000047684, + 164300.00000047684, + 164300.00000047684, + 164399.99999952316, + 164399.99999952316, + 164399.99999952316, + 164400, + 164400, + 164400, + 164400, + 164400, + 164400, + 164400, + 164400, + 164400, + 164400, + 164500, + 164500, + 164500, + 164500, + 164500, + 164500, + 164500, + 164500, + 164500.00000095367, + 164500.00000095367, + 164600, + 164600, + 164600, + 164600, + 164600, + 164600, + 164600, + 164600, + 164600, + 164600.00000047684, + 164699.99999904633, + 164699.99999904633, + 164700, + 164700, + 164700, + 164700, + 164700, + 164700, + 164700, + 164700.00000047684, + 164700.00000047684, + 164799.99999952316, + 164800, + 164800, + 164800, + 164800, + 164800, + 164800, + 164800, + 164800, + 164800.00000047684, + 164800.00000047684, + 164899.99999952316, + 164899.99999952316, + 164900, + 164900, + 164900, + 164900, + 164900, + 164900, + 164900, + 164900, + 164900, + 164900, + 164900, + 164999.99999952316, + 165000, + 165000, + 165000, + 165000, + 165000, + 165000, + 165000, + 165000, + 165000, + 165000, + 165000.00000095367, + 165099.99999904633, + 165099.99999904633, + 165100, + 165100, + 165100, + 165100, + 165100, + 165100, + 165100, + 165199.99999952316, + 165200, + 165200, + 165200, + 165200, + 165200.00000047684, + 165200.00000047684, + 165300, + 165300, + 165300, + 165300, + 165399.99999952316, + 165400, + 165400, + 165400, + 165400, + 165400, + 165400, + 165400, + 165400, + 165400, + 165500, + 165500, + 165500, + 165500, + 165500, + 165500, + 165500.00000047684, + 165599.99999904633, + 165600, + 165600, + 165600, + 165600, + 165600, + 165600, + 165600, + 165600, + 165600, + 165600, + 165600, + 165600.00000047684, + 165600.00000047684, + 165700, + 165700, + 165700.00000047684, + 165700.00000047684, + 165800, + 165800, + 165800, + 165800.00000095367, + 165800.00000095367, + 165900, + 165900, + 165900, + 165900, + 165900, + 165900, + 165900, + 165900, + 165999.99999904633, + 166000, + 166000, + 166000, + 166000, + 166000, + 166099.99999952316, + 166099.99999952316, + 166100, + 166100, + 166100, + 166100, + 166100.00000047684, + 166200, + 166200, + 166200, + 166200.00000047684, + 166300, + 166300, + 166300, + 166300, + 166300, + 166300, + 166300, + 166300, + 166300.00000095367, + 166400, + 166400, + 166400, + 166400, + 166400, + 166400, + 166400, + 166400, + 166500, + 166500, + 166500, + 166500, + 166500, + 166500.00000047684, + 166600, + 166600, + 166600, + 166600.00000047684, + 166700, + 166700, + 166700, + 166700, + 166700, + 166700, + 166700, + 166700.00000095367, + 166700.00000095367, + 166800, + 166800, + 166800, + 166800, + 166800, + 166800, + 166800, + 166800, + 166800, + 166900, + 166900, + 166900, + 166900, + 166900, + 166999.99999952316, + 167000, + 167000, + 167000, + 167000, + 167000, + 167099.99999952316, + 167100, + 167100, + 167100, + 167199.99999952316, + 167199.99999952316, + 167199.99999952316, + 167200, + 167200, + 167200.00000095367, + 167300, + 167300, + 167300, + 167400, + 167400, + 167400, + 167400, + 167400, + 167400, + 167400, + 167400, + 167400, + 167400, + 167400.00000047684, + 167400.00000047684, + 167499.99999952316, + 167499.99999952316, + 167500, + 167500, + 167500, + 167500, + 167500, + 167500.00000047684, + 167600, + 167600, + 167600, + 167600, + 167600, + 167700, + 167700, + 167700, + 167700, + 167700, + 167700.00000095367, + 167700.00000095367, + 167800, + 167800.00000047684, + 167900, + 167900, + 167900, + 167900, + 167900, + 167900, + 167900, + 167999.99999952316, + 168000, + 168000, + 168000, + 168000, + 168000, + 168100, + 168100, + 168100, + 168100, + 168100, + 168100, + 168100, + 168200, + 168200, + 168200, + 168200, + 168200, + 168300, + 168300, + 168300, + 168300, + 168300, + 168400, + 168400, + 168400, + 168400, + 168400, + 168500, + 168500, + 168600, + 168600, + 168600, + 168600, + 168600, + 168600, + 168700, + 168700, + 168800, + 168800, + 168800, + 168800, + 168800, + 168900, + 169000, + 169000, + 169000, + 169000, + 169200, + 169200, + 169200, + 169200, + 169299.99999952316, + 169300, + 169399.99999952316, + 169400, + 169400, + 169400, + 169400, + 169400, + 169400, + 169400.00000047684, + 169500, + 169600, + 169600, + 169600.00000047684, + 169699.99999952316, + 169700, + 169700, + 169700.00000047684, + 169700.00000047684, + 169799.99999952316, + 169800, + 169800, + 169900, + 169900, + 169900, + 169900, + 170000, + 170000, + 170100, + 170200, + 170200, + 170200.00000047684, + 170300, + 170300, + 170300, + 170300, + 170300, + 170300.00000095367, + 170400, + 170400, + 170500, + 170500, + 170500, + 170500, + 170500, + 170500.00000047684, + 170600, + 170600, + 170699.99999952316, + 170700, + 170700.00000047684, + 170800, + 170800, + 170900, + 171000, + 171000, + 171100, + 171100, + 171100, + 171200, + 171200, + 171300, + 171300, + 171300, + 171300, + 171300, + 171400, + 171400, + 171500, + 171500, + 171600, + 171600, + 171600, + 171600, + 171600, + 171999.99999952316, + 172100, + 172100, + 172100, + 172200, + 172300, + 172300.00000047684, + 172400, + 172400, + 172500, + 172600, + 172700, + 172800, + 172800, + 172900, + 172900, + 173000, + 173000, + 173000, + 173100, + 173100, + 173100, + 173199.99999904633, + 173200, + 173200, + 173200, + 173300, + 173400, + 173500, + 173500, + 173700, + 173700, + 173700, + 173799.99999952316, + 173799.99999952316, + 173900, + 173900, + 174000, + 174000, + 174200, + 174200, + 174200, + 174200, + 174200, + 174200, + 174300, + 174300, + 174300, + 174400, + 174400, + 174500, + 174600, + 174600, + 174600, + 174699.99999952316, + 174700, + 174700, + 174700.00000047684, + 174800, + 174800, + 174800, + 174900, + 174900, + 175000, + 175000, + 175000, + 175000, + 175100, + 175100, + 175300, + 175400, + 175400, + 175400, + 175500, + 175600.00000047684, + 175700, + 175700, + 175700, + 175800, + 175800, + 175800, + 175800, + 175900, + 176000, + 176000, + 176000, + 176100, + 176200, + 176200, + 176300, + 176300, + 176400, + 176499.99999952316, + 176500, + 176500, + 176899.99999952316, + 176900, + 176900, + 176900, + 176999.99999952316, + 176999.99999952316, + 177200, + 177200, + 177300, + 177300, + 177400, + 177400, + 177400.00000047684, + 177500, + 177500, + 177600, + 177799.99999904633, + 177800, + 177800, + 177899.99999952316, + 177900, + 177900, + 177900, + 178000, + 178100, + 178100, + 178100, + 178100, + 178200, + 178200, + 178400, + 178500, + 178800, + 178800, + 178800, + 178900, + 179000, + 179000, + 179100, + 179100, + 179400, + 179600, + 179700.00000095367, + 179799.99999952316, + 179800, + 179800, + 179900, + 180100, + 180100, + 180300, + 180400, + 180400, + 180400, + 180500, + 180600, + 180800, + 180800, + 180900, + 180900, + 181000, + 181000, + 181200, + 181200, + 181300, + 181500, + 181700, + 181800, + 181999.99999952316, + 182000, + 182100, + 182100, + 182200, + 182300, + 182300, + 182400.00000047684, + 182500, + 182700, + 182800.00000095367, + 182900, + 182900, + 183100, + 183200, + 183200, + 183300, + 183400, + 183500, + 183500, + 183500, + 183600, + 183700, + 183900, + 183900, + 184000, + 184000, + 184100, + 184100, + 184100, + 184200, + 184300, + 184300, + 184300, + 184400, + 184500, + 184500, + 184600, + 184700, + 184800, + 184800, + 184900, + 185000, + 185200, + 185200, + 185400, + 185400, + 185400, + 185500, + 185600, + 186000, + 186100, + 186200, + 186200, + 186400, + 186700, + 186700, + 186900, + 186900, + 187000, + 187200, + 187200, + 187300, + 187400, + 187500, + 187600, + 187600, + 187799.99999952316, + 187900, + 188000, + 188300, + 188400, + 188400, + 188400, + 188500, + 188599.99999952316, + 188600, + 188600, + 188700, + 188700, + 188900, + 189000, + 189100, + 189100, + 189200, + 189300, + 189600, + 189600, + 189600, + 189700, + 189899.99999952316, + 190300, + 190400, + 190400, + 190500.00000095367, + 190600, + 190800, + 190800, + 190900, + 190999.99999952316, + 191000, + 191200, + 191600, + 191700, + 191900, + 192100, + 192200.00000047684, + 192500, + 192699.99999952316, + 193000, + 193100, + 193500, + 193500, + 193600, + 193700, + 193700, + 193700, + 194000, + 194000, + 194100, + 194200, + 195000, + 195000, + 195100, + 195200, + 195400, + 195600, + 196000, + 196100, + 196400, + 196700, + 196900, + 197000, + 197200, + 197599.99999952316, + 197600, + 198500, + 198600, + 198700, + 198700.00000095367, + 199100, + 199200, + 199600, + 199700, + 199700, + 199900.00000047684, + 200100, + 200800, + 201000, + 201100, + 201100, + 202500, + 202600, + 202700, + 203100, + 203700, + 204400.00000047684, + 204600, + 204900, + 205400, + 206600, + 206700.00000047684, + 206900, + 207600, + 208399.99999952316, + 208700.00000047684, + 208800, + 210800, + 211700, + 211700, + 212000, + 212000, + 212099.99999952316, + 213000.00000095367, + 213100, + 213200, + 214000, + 214199.99999952316, + 214200, + 214700, + 216199.99999952316, + 216500, + 217000, + 217300, + 218500, + 219400, + 220000, + 220500, + 220700, + 221200, + 223300, + 223399.99999952316, + 223900, + 224099.99999952316, + 224200, + 224400, + 224600, + 225300, + 225399.99999904633, + 225499.99999952316, + 225500, + 225900, + 226099.99999952316, + 226200, + 226900, + 227200, + 227300, + 227700, + 228500, + 231200, + 232200, + 233000, + 233000, + 233900, + 234399.99999904633, + 234800, + 235700, + 236000, + 236500, + 236800, + 237200, + 238800, + 240500, + 241900, + 242000, + 242100, + 242600, + 242900, + 244300, + 245700, + 245800, + 246300, + 246800, + 247600, + 251200, + 251300, + 251600, + 251800, + 252400.00000047684, + 252700, + 253100, + 253900, + 257000, + 257399.99999952316, + 258800, + 259100, + 259200, + 260000, + 261300, + 261300, + 261800, + 263700, + 264700, + 266900, + 267800, + 268400, + 269100, + 270600, + 271600, + 274200, + 277500, + 278300, + 280100, + 281400.0000009537, + 284000, + 286700, + 286800, + 287600, + 287900, + 289500, + 291700, + 295800, + 297700, + 299200, + 301600, + 303000, + 304000, + 308100, + 309800, + 317000, + 321300, + 330600, + 376400, + 387400, + 395900, + 411100, + 419800, + 428900, + 432100, + 439700, + 443800, + 447900, + 457700, + 466600, + 495700, + 503400, + 520300, + 521700, + 524700, + 530900, + 538800, + 539600, + 545300, + 547000, + 548200, + 557100, + 561500, + 575000, + 581100.0000004768, + 583500, + 590000, + 590400, + 593900, + 598700, + 606400, + 607800, + 612900, + 614800, + 617900, + 620100, + 634400.0000009537, + 636200, + 639000, + 661300, + 665000, + 666699.9999995232, + 673300, + 673600, + 682200, + 691100, + 693900, + 704400, + 704800, + 733100 + ], + "min": 150300, + "max": 733100, + "p25": 153699.99999952316, + "p50": 155200, + "p75": 163200, + "p99": 443800, + "p999": 682200, + "avg": 166422.81242589757, + "ticks": 4217, + "heap": { + "_": 4154, + "total": 2510307032, + "min": 12128, + "max": 2447640, + "avg": 604310.7924891671 + } + }, + "args": {}, + "name": "handlebars composed-page" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta composed-page", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 11357.12890625, + 11382.177734375, + 11382.71484375, + 11384.326171875, + 11389.94140625, + 11393.603515625, + 11428.6865234375, + 11436.3525390625, + 11489.0625, + 11495.5322265625, + 11702.9541015625 + ], + "min": 11357.12890625, + "max": 11702.9541015625, + "p25": 11382.71484375, + "p50": 11393.603515625, + "p75": 11436.3525390625, + "p99": 11495.5322265625, + "p999": 11495.5322265625, + "avg": 11440.22549715909, + "ticks": 45056, + "heap": { + "_": 15, + "total": 3972.595703125, + "min": 255.365234375, + "max": 377.3671875, + "avg": 264.83971354166664 + } + }, + "args": {}, + "name": "eta composed-page" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars trivial-substitution", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 132600, + 132700, + 132800, + 133000, + 133000, + 133100, + 133100, + 133100, + 133100, + 133100, + 133200, + 133200, + 133200, + 133300, + 133300, + 133300, + 133300, + 133300, + 133300, + 133300, + 133300, + 133300, + 133400, + 133400, + 133400, + 133400, + 133400, + 133400, + 133400, + 133400, + 133400, + 133400, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133500, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133600, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133700, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133800, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 133900, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134000, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134100, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134200, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134300, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134400, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134500, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134600, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134700, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134800, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 134900, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135000, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135100, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135200, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135300, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135400, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135500, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135600, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135700, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135800, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 135900, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136000, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136100, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136200, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136300, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136400, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136500, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136600, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136700, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136800, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 136900, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137000, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137100, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137200, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137300, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137400, + 137500, + 137500, + 137500, + 137500, + 137500, + 137500, + 137500, + 137500, + 137500, + 137500, + 137500, + 137500, + 137500, + 137500, + 137500, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137600, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137700, + 137800, + 137800, + 137800, + 137800, + 137800, + 137800, + 137800, + 137800, + 137800, + 137800, + 137800, + 137800, + 137800, + 137800, + 137800, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 137900, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138000, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138100, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138200, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138300, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138400, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138500, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138600, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138700, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138800, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 138900, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139000, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139100, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139200, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139300, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139400, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139500, + 139600, + 139600, + 139600, + 139600, + 139600, + 139600, + 139600, + 139600, + 139600, + 139600, + 139600, + 139600, + 139600, + 139600, + 139600, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139700, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139800, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 139900, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140000, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140100, + 140200, + 140200, + 140200, + 140200, + 140200, + 140200, + 140200, + 140200, + 140200, + 140200, + 140200, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140300, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140400, + 140500, + 140500, + 140500, + 140500, + 140500, + 140500, + 140600, + 140600, + 140600, + 140600, + 140600, + 140600, + 140600, + 140600, + 140600, + 140600, + 140600, + 140600, + 140600, + 140600, + 140600, + 140700, + 140700, + 140700, + 140700, + 140700, + 140700, + 140700, + 140700, + 140700, + 140700, + 140700, + 140700, + 140700, + 140700, + 140800, + 140800, + 140800, + 140800, + 140800, + 140800, + 140800, + 140800, + 140800, + 140800, + 140800, + 140800, + 140800, + 140800, + 140900, + 140900, + 140900, + 140900, + 140900, + 140900, + 140900, + 140900, + 140900, + 140900, + 140900, + 140900, + 140900, + 140900, + 140900, + 141000, + 141000, + 141000, + 141000, + 141000, + 141000, + 141000, + 141000, + 141000, + 141000, + 141100, + 141100, + 141100, + 141100, + 141100, + 141100, + 141100, + 141100, + 141100, + 141100, + 141100, + 141100, + 141100, + 141100, + 141100, + 141200, + 141200, + 141200, + 141200, + 141300, + 141300, + 141300, + 141300, + 141300, + 141300, + 141300, + 141300, + 141300, + 141400, + 141400, + 141400, + 141400, + 141400, + 141400, + 141400, + 141400, + 141400, + 141500, + 141500, + 141500, + 141500, + 141500, + 141500, + 141500, + 141500, + 141500, + 141600, + 141600, + 141600, + 141600, + 141600, + 141600, + 141600, + 141600, + 141600, + 141600, + 141700, + 141700, + 141700, + 141700, + 141700, + 141700, + 141700, + 141700, + 141800, + 141800, + 141800, + 141800, + 141800, + 141800, + 141900, + 141900, + 141900, + 141900, + 141900, + 142000, + 142000, + 142000, + 142000, + 142000, + 142100, + 142100, + 142100, + 142100, + 142100, + 142100, + 142100, + 142100, + 142100, + 142200, + 142200, + 142200, + 142200, + 142200, + 142200, + 142200, + 142200, + 142300, + 142300, + 142300, + 142300, + 142300, + 142300, + 142300, + 142400, + 142400, + 142400, + 142400, + 142400, + 142400, + 142400, + 142500, + 142500, + 142500, + 142500, + 142500, + 142500, + 142500, + 142500, + 142600, + 142600, + 142600, + 142600, + 142600, + 142700, + 142700, + 142700, + 142700, + 142700, + 142700, + 142700, + 142700, + 142800, + 142800, + 142800, + 142800, + 142800, + 142800, + 142800, + 142800, + 142900, + 142900, + 142900, + 142900, + 142900, + 142900, + 142900, + 142900, + 143000, + 143000, + 143000, + 143000, + 143000, + 143000, + 143000, + 143000, + 143100, + 143100, + 143100, + 143100, + 143100, + 143100, + 143100, + 143200, + 143200, + 143200, + 143200, + 143200, + 143200, + 143200, + 143200, + 143200, + 143200, + 143200, + 143200, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143300, + 143400, + 143400, + 143400, + 143400, + 143400, + 143400, + 143400, + 143400, + 143400, + 143400, + 143400, + 143500, + 143500, + 143500, + 143500, + 143500, + 143600, + 143600, + 143600, + 143600, + 143600, + 143600, + 143600, + 143600, + 143600, + 143600, + 143600, + 143600, + 143600, + 143600, + 143600, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143700, + 143800, + 143800, + 143800, + 143800, + 143800, + 143800, + 143800, + 143800, + 143800, + 143800, + 143800, + 143800, + 143900, + 143900, + 143900, + 143900, + 143900, + 143900, + 143900, + 143900, + 143900, + 143900, + 143900, + 143900, + 143900, + 143900, + 143900, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144000, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144100, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144200, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144300, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144400, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144500, + 144600, + 144600, + 144600, + 144600, + 144600, + 144600, + 144600, + 144600, + 144600, + 144600, + 144700, + 144700, + 144700, + 144700, + 144700, + 144700, + 144700, + 144700, + 144700, + 144700, + 144700, + 144700, + 144700, + 144700, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144800, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 144900, + 145000, + 145000, + 145000, + 145000, + 145000, + 145000, + 145000, + 145000, + 145000, + 145000, + 145000, + 145000, + 145000, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145100, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145200, + 145300, + 145300, + 145300, + 145300, + 145300, + 145300, + 145300, + 145300, + 145300, + 145300, + 145300, + 145300, + 145300, + 145300, + 145400, + 145400, + 145400, + 145400, + 145400, + 145400, + 145400, + 145400, + 145400, + 145400, + 145400, + 145500, + 145500, + 145500, + 145500, + 145500, + 145500, + 145500, + 145500, + 145500, + 145500, + 145500, + 145500, + 145500, + 145500, + 145500, + 145600, + 145600, + 145600, + 145600, + 145600, + 145600, + 145600, + 145600, + 145600, + 145700, + 145700, + 145700, + 145700, + 145700, + 145700, + 145700, + 145700, + 145700, + 145700, + 145700, + 145700, + 145700, + 145800, + 145800, + 145800, + 145800, + 145800, + 145800, + 145800, + 145800, + 145800, + 145800, + 145800, + 145900, + 145900, + 145900, + 145900, + 145900, + 145900, + 145900, + 145900, + 145900, + 145900, + 145900, + 145900, + 146000, + 146000, + 146000, + 146000, + 146000, + 146000, + 146000, + 146000, + 146000, + 146000, + 146000, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146100, + 146200, + 146200, + 146200, + 146200, + 146200, + 146200, + 146300, + 146300, + 146300, + 146300, + 146300, + 146300, + 146300, + 146400, + 146400, + 146400, + 146400, + 146400, + 146400, + 146400, + 146400, + 146400, + 146400, + 146500, + 146500, + 146500, + 146500, + 146500, + 146500, + 146500, + 146500, + 146600, + 146600, + 146600, + 146600, + 146600, + 146600, + 146600, + 146700, + 146700, + 146700, + 146700, + 146700, + 146700, + 146700, + 146700, + 146700, + 146800, + 146800, + 146800, + 146800, + 146800, + 146800, + 146800, + 146900, + 146900, + 146900, + 146900, + 146900, + 146900, + 147000, + 147000, + 147000, + 147000, + 147000, + 147000, + 147000, + 147100, + 147100, + 147100, + 147100, + 147100, + 147100, + 147100, + 147100, + 147100, + 147100, + 147100, + 147100, + 147200, + 147200, + 147200, + 147200, + 147200, + 147200, + 147200, + 147200, + 147300, + 147300, + 147300, + 147300, + 147300, + 147300, + 147400, + 147400, + 147400, + 147400, + 147400, + 147400, + 147400, + 147400, + 147400, + 147400, + 147500, + 147500, + 147500, + 147500, + 147500, + 147500, + 147600, + 147600, + 147600, + 147600, + 147600, + 147600, + 147600, + 147700, + 147700, + 147700, + 147800, + 147800, + 147800, + 147800, + 147800, + 147900, + 147900, + 147900, + 147900, + 147900, + 147900, + 147900, + 147900, + 147900, + 147900, + 148000, + 148000, + 148000, + 148100, + 148100, + 148100, + 148100, + 148100, + 148200, + 148200, + 148200, + 148200, + 148200, + 148200, + 148200, + 148300, + 148300, + 148300, + 148300, + 148300, + 148300, + 148400, + 148400, + 148400, + 148400, + 148500, + 148500, + 148500, + 148500, + 148500, + 148600, + 148600, + 148600, + 148600, + 148600, + 148600, + 148700, + 148700, + 148700, + 148700, + 148700, + 148700, + 148700, + 148800, + 148800, + 148800, + 148800, + 148800, + 148800, + 148800, + 148800, + 148800, + 148900, + 148900, + 148900, + 148900, + 148900, + 148900, + 148900, + 149000, + 149000, + 149000, + 149000, + 149000, + 149000, + 149100, + 149100, + 149100, + 149100, + 149100, + 149100, + 149100, + 149200, + 149200, + 149200, + 149200, + 149200, + 149200, + 149200, + 149200, + 149300, + 149400, + 149400, + 149400, + 149400, + 149500, + 149500, + 149500, + 149600, + 149600, + 149600, + 149600, + 149700, + 149700, + 149700, + 149800, + 149800, + 149800, + 149800, + 149900, + 149900, + 149900, + 149900, + 149900, + 150000, + 150000, + 150000, + 150000, + 150000, + 150100, + 150100, + 150100, + 150100, + 150100, + 150100, + 150200, + 150200, + 150200, + 150200, + 150200, + 150200, + 150200, + 150200, + 150300, + 150300, + 150300, + 150400, + 150400, + 150500, + 150500, + 150500, + 150600, + 150600, + 150600, + 150600, + 150700, + 150700, + 150700, + 150900, + 151000, + 151000, + 151000, + 151100, + 151100, + 151200, + 151200, + 151200, + 151300, + 151300, + 151300, + 151300, + 151300, + 151300, + 151300, + 151400, + 151400, + 151500, + 151500, + 151500, + 151500, + 151500, + 151600, + 151700, + 151700, + 151700, + 151800, + 151800, + 151800, + 151900, + 151900, + 151900, + 151900, + 152000, + 152000, + 152000, + 152000, + 152100, + 152300, + 152300, + 152300, + 152400, + 152400, + 152500, + 152600, + 152600, + 152600, + 152700, + 152700, + 152900, + 152900, + 153000, + 153100, + 153100, + 153100, + 153200, + 153200, + 153200, + 153400, + 153400, + 153500, + 153600, + 153700, + 153700, + 153800, + 153800, + 153800, + 153900, + 154000, + 154000, + 154000, + 154100, + 154100, + 154200, + 154200, + 154300, + 154300, + 154400, + 154500, + 154500, + 154600, + 154600, + 154600, + 154600, + 154600, + 154700, + 154700, + 154700, + 154700, + 154900, + 154900, + 154900, + 155000, + 155000, + 155000, + 155200, + 155300, + 155300, + 155400, + 155500, + 155500, + 155700, + 155700, + 156000, + 156000, + 156200, + 156200, + 156200, + 156300, + 156300, + 156300, + 156400, + 156600, + 156600, + 156700, + 156700, + 156700, + 156800, + 156800, + 156900, + 156900, + 157100, + 157100, + 157200, + 157200, + 157300, + 157300, + 157300, + 157400, + 157600, + 157600, + 157600, + 157800, + 157800, + 158000, + 158000, + 158000, + 158100, + 158300, + 158300, + 158400, + 158500, + 158500, + 158900, + 158900, + 159200, + 159300, + 159400, + 159400, + 159500, + 159600, + 159600, + 159700, + 159800, + 159800, + 159800, + 159900, + 160100, + 160200, + 160200, + 160300, + 160300, + 160700, + 160700, + 160800, + 160900, + 161000, + 161300, + 161300, + 161300, + 161300, + 161400, + 161500, + 161600, + 161700, + 161800, + 162000, + 162100, + 162100, + 162200, + 162400, + 162400, + 162500, + 162700, + 163100, + 163100, + 164000, + 164000, + 164000, + 164000, + 164700, + 164700, + 164900, + 165000, + 165100, + 165300, + 165300, + 165500, + 165700, + 165800, + 165900, + 166100, + 166100, + 166100, + 166200, + 166200, + 166400, + 166400, + 166700, + 167200, + 167300, + 167500, + 167700, + 167800, + 168000, + 168000, + 168700, + 168700, + 169200, + 169800, + 169900, + 169900, + 170100, + 170900, + 171100, + 171600, + 171800, + 172300, + 172400, + 172600, + 172700, + 172700, + 172900, + 173000, + 173000, + 173000, + 173000, + 173300, + 173600, + 174000, + 174500, + 174500, + 174800, + 175300, + 175500, + 175700, + 175800, + 176000, + 176100, + 176300, + 176500, + 176500, + 176800, + 176800, + 177000, + 177000, + 177100, + 177300, + 177600, + 177700, + 178100, + 178400, + 178700, + 179200, + 179600, + 179600, + 181200, + 181900, + 182000, + 182100, + 183000, + 183000, + 183100, + 183500, + 184200, + 184500, + 185500, + 186200, + 187100, + 187500, + 187600, + 188400, + 188600, + 189000, + 189300, + 189600, + 189900, + 190100, + 190500, + 191900, + 192000, + 193500, + 193900, + 194000, + 195200, + 196400, + 196900, + 197000, + 197300, + 197500, + 197500, + 199500, + 200500, + 201400, + 201700, + 204400, + 205500, + 205700, + 206000, + 206400, + 208100, + 210300, + 211200, + 211400, + 212400, + 212800, + 213300, + 215300, + 216000, + 217100, + 217900, + 220000, + 220800, + 221300, + 225700, + 227800, + 234600, + 236800, + 241200, + 246200, + 250800, + 256600, + 280700, + 280700, + 287300, + 288900, + 290100, + 308500, + 308800, + 316400, + 334800, + 348000, + 362800, + 385100, + 435500, + 483200, + 484400, + 494000, + 494500, + 498700, + 499400, + 499600, + 499700, + 504500, + 507100, + 507500, + 509300, + 510800, + 511700, + 517100, + 517800, + 532800, + 536400, + 543700, + 544500, + 545500, + 556500, + 556600, + 558200, + 560900, + 561300, + 563500, + 564700, + 577100, + 603100, + 619900, + 652300, + 685500 + ], + "min": 132600, + "max": 685500, + "p25": 134900, + "p50": 136100, + "p75": 141700, + "p99": 236800, + "p999": 564700, + "avg": 143136.99551569507, + "ticks": 4906, + "heap": { + "_": 4826, + "total": 2335874400, + "min": 8160, + "max": 1215632, + "avg": 484018.7318690427 + } + }, + "args": {}, + "name": "handlebars trivial-substitution" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta trivial-substitution", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 6296.3134765625, + 6297.6318359375, + 6298.9501953125, + 6305.6396484375, + 6312.6220703125, + 6317.1142578125, + 6319.873046875, + 6321.77734375, + 6335.7421875, + 6340.0390625, + 6343.84765625, + 6345.5810546875, + 6352.099609375, + 6352.294921875, + 6355.2978515625, + 6359.1552734375, + 6362.451171875, + 6365.0634765625, + 6366.7236328125, + 6372.900390625, + 6374.6826171875, + 6378.6865234375, + 6400.439453125, + 6468.9697265625 + ], + "min": 6296.3134765625, + "max": 6468.9697265625, + "p25": 6317.1142578125, + "p50": 6345.5810546875, + "p75": 6365.0634765625, + "p99": 6400.439453125, + "p999": 6400.439453125, + "avg": 6347.662353515625, + "ticks": 98304, + "heap": { + "_": 5, + "total": 70296.201171875, + "min": 13979.904296875, + "max": 14376.31640625, + "avg": 14059.240234375 + } + }, + "args": {}, + "name": "eta trivial-substitution" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars large-loop", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 434800, + 435000, + 435100, + 435400, + 435400, + 435900, + 436300, + 436400, + 436500, + 437100, + 437100, + 437100, + 437100, + 437100, + 437400, + 437400, + 437400, + 437500, + 438200, + 438400, + 438400, + 438500, + 438700, + 438700, + 438700, + 438900, + 439000, + 439100, + 439100, + 439200, + 439200, + 439200, + 439300, + 439300, + 439300, + 439400, + 439500, + 439500, + 439500, + 439700, + 439800, + 439900, + 439900, + 440000, + 440100, + 440100, + 440100, + 440200, + 440200, + 440200, + 440300, + 440300, + 440400, + 440400, + 440400, + 440500, + 440500, + 440600, + 440700, + 440700, + 440700, + 440700, + 440800, + 440800, + 440900, + 441000, + 441000, + 441000, + 441100, + 441100, + 441100, + 441100, + 441200, + 441200, + 441300, + 441300, + 441400, + 441400, + 441400, + 441400, + 441400, + 441500, + 441500, + 441500, + 441600, + 441600, + 441600, + 441700, + 441700, + 441700, + 441800, + 441800, + 441800, + 441900, + 441900, + 442000, + 442100, + 442100, + 442100, + 442200, + 442300, + 442300, + 442300, + 442300, + 442300, + 442400, + 442400, + 442500, + 442500, + 442500, + 442500, + 442500, + 442600, + 442600, + 442600, + 442600, + 442700, + 442700, + 442700, + 442700, + 442800, + 443000, + 443000, + 443000, + 443000, + 443000, + 443100, + 443100, + 443100, + 443200, + 443300, + 443300, + 443300, + 443400, + 443400, + 443400, + 443500, + 443500, + 443500, + 443500, + 443500, + 443500, + 443500, + 443500, + 443600, + 443700, + 443700, + 443700, + 443700, + 443700, + 443700, + 443800, + 443800, + 443800, + 443900, + 443900, + 444000, + 444000, + 444000, + 444000, + 444000, + 444000, + 444100, + 444100, + 444100, + 444100, + 444100, + 444100, + 444200, + 444200, + 444200, + 444200, + 444200, + 444200, + 444300, + 444300, + 444400, + 444400, + 444400, + 444400, + 444500, + 444600, + 444600, + 444700, + 444700, + 444700, + 444700, + 444800, + 444800, + 444800, + 444800, + 444900, + 444900, + 444900, + 444900, + 445000, + 445000, + 445000, + 445000, + 445100, + 445100, + 445100, + 445100, + 445200, + 445200, + 445200, + 445300, + 445400, + 445400, + 445400, + 445400, + 445400, + 445400, + 445400, + 445500, + 445500, + 445600, + 445600, + 445600, + 445600, + 445600, + 445600, + 445800, + 445800, + 445800, + 445900, + 446200, + 446200, + 446300, + 446300, + 446300, + 446400, + 446400, + 446400, + 446400, + 446400, + 446500, + 446500, + 446600, + 446600, + 446600, + 446600, + 446700, + 446700, + 446800, + 446800, + 446800, + 446900, + 446900, + 446900, + 446900, + 446900, + 446900, + 447000, + 447000, + 447000, + 447000, + 447100, + 447100, + 447100, + 447100, + 447100, + 447100, + 447200, + 447200, + 447200, + 447200, + 447200, + 447300, + 447400, + 447400, + 447400, + 447400, + 447400, + 447400, + 447500, + 447500, + 447500, + 447500, + 447600, + 447600, + 447600, + 447600, + 447600, + 447700, + 447700, + 447800, + 447800, + 447800, + 447800, + 447900, + 447900, + 447900, + 447900, + 447900, + 448000, + 448000, + 448000, + 448000, + 448100, + 448100, + 448100, + 448100, + 448200, + 448200, + 448200, + 448200, + 448200, + 448200, + 448200, + 448300, + 448300, + 448300, + 448300, + 448300, + 448300, + 448300, + 448400, + 448400, + 448400, + 448400, + 448400, + 448400, + 448400, + 448400, + 448400, + 448400, + 448400, + 448400, + 448500, + 448500, + 448600, + 448600, + 448600, + 448600, + 448700, + 448800, + 448800, + 448800, + 448800, + 448800, + 448900, + 448900, + 448900, + 448900, + 448900, + 448900, + 449000, + 449000, + 449000, + 449000, + 449000, + 449000, + 449000, + 449100, + 449100, + 449100, + 449100, + 449100, + 449100, + 449200, + 449200, + 449200, + 449300, + 449300, + 449400, + 449400, + 449400, + 449400, + 449500, + 449500, + 449500, + 449500, + 449600, + 449600, + 449600, + 449600, + 449600, + 449600, + 449700, + 449700, + 449700, + 449700, + 449700, + 449700, + 449700, + 449700, + 449700, + 449700, + 449700, + 449700, + 449800, + 449800, + 449800, + 449900, + 449900, + 449900, + 449900, + 449900, + 449900, + 449900, + 450000, + 450000, + 450000, + 450000, + 450000, + 450100, + 450200, + 450200, + 450200, + 450200, + 450300, + 450300, + 450300, + 450300, + 450300, + 450400, + 450400, + 450400, + 450400, + 450500, + 450500, + 450500, + 450500, + 450500, + 450500, + 450500, + 450500, + 450600, + 450600, + 450600, + 450600, + 450700, + 450700, + 450700, + 450800, + 450800, + 450800, + 450900, + 450900, + 450900, + 450900, + 450900, + 450900, + 451000, + 451000, + 451000, + 451000, + 451000, + 451000, + 451100, + 451100, + 451100, + 451100, + 451100, + 451100, + 451100, + 451100, + 451100, + 451200, + 451300, + 451300, + 451400, + 451400, + 451400, + 451500, + 451500, + 451600, + 451600, + 451700, + 451700, + 451700, + 451700, + 451700, + 451700, + 451800, + 451800, + 451800, + 451900, + 451900, + 451900, + 452000, + 452000, + 452000, + 452000, + 452000, + 452000, + 452100, + 452100, + 452100, + 452100, + 452100, + 452100, + 452100, + 452200, + 452200, + 452200, + 452200, + 452200, + 452200, + 452200, + 452200, + 452200, + 452200, + 452300, + 452300, + 452300, + 452400, + 452400, + 452400, + 452400, + 452400, + 452400, + 452500, + 452500, + 452500, + 452500, + 452500, + 452600, + 452600, + 452600, + 452600, + 452700, + 452700, + 452700, + 452700, + 452700, + 452700, + 452800, + 452800, + 452800, + 452800, + 452800, + 452800, + 452900, + 452900, + 452900, + 452900, + 452900, + 452900, + 452900, + 453000, + 453000, + 453000, + 453100, + 453100, + 453100, + 453100, + 453100, + 453100, + 453100, + 453200, + 453200, + 453200, + 453200, + 453300, + 453300, + 453300, + 453400, + 453400, + 453400, + 453400, + 453500, + 453500, + 453600, + 453600, + 453700, + 453700, + 453800, + 453800, + 453800, + 453800, + 453800, + 453800, + 453800, + 453900, + 453900, + 453900, + 453900, + 453900, + 453900, + 454000, + 454100, + 454100, + 454100, + 454100, + 454300, + 454300, + 454300, + 454300, + 454400, + 454400, + 454500, + 454500, + 454500, + 454500, + 454500, + 454600, + 454600, + 454600, + 454700, + 454700, + 454700, + 454700, + 454700, + 454800, + 454800, + 454800, + 454800, + 454800, + 454800, + 454800, + 454800, + 454900, + 454900, + 454900, + 454900, + 454900, + 455000, + 455000, + 455000, + 455000, + 455000, + 455100, + 455200, + 455300, + 455300, + 455300, + 455300, + 455300, + 455400, + 455400, + 455400, + 455400, + 455400, + 455500, + 455500, + 455600, + 455700, + 455700, + 455700, + 455700, + 455700, + 455700, + 455700, + 455800, + 455800, + 455800, + 455800, + 455800, + 455900, + 455900, + 455900, + 456000, + 456000, + 456100, + 456100, + 456100, + 456100, + 456200, + 456200, + 456300, + 456300, + 456300, + 456300, + 456300, + 456300, + 456300, + 456300, + 456400, + 456500, + 456500, + 456500, + 456500, + 456600, + 456600, + 456600, + 456600, + 456700, + 456700, + 456700, + 456700, + 456700, + 456800, + 456800, + 456800, + 456800, + 456800, + 456800, + 456900, + 456900, + 456900, + 456900, + 456900, + 456900, + 457000, + 457000, + 457000, + 457000, + 457100, + 457100, + 457200, + 457200, + 457300, + 457300, + 457300, + 457400, + 457400, + 457400, + 457400, + 457400, + 457500, + 457500, + 457500, + 457500, + 457500, + 457600, + 457600, + 457600, + 457700, + 457700, + 457800, + 457800, + 457800, + 457900, + 458000, + 458000, + 458100, + 458200, + 458300, + 458300, + 458300, + 458300, + 458400, + 458400, + 458400, + 458400, + 458400, + 458500, + 458600, + 458600, + 458600, + 458600, + 458600, + 458700, + 458700, + 458800, + 458800, + 458900, + 458900, + 458900, + 459000, + 459100, + 459100, + 459100, + 459200, + 459200, + 459300, + 459300, + 459300, + 459300, + 459400, + 459500, + 459500, + 459500, + 459500, + 459600, + 459600, + 459600, + 459600, + 459600, + 459800, + 459800, + 459800, + 459800, + 459800, + 459900, + 459900, + 460000, + 460000, + 460000, + 460100, + 460100, + 460200, + 460200, + 460200, + 460200, + 460300, + 460500, + 460600, + 460700, + 460800, + 460800, + 460900, + 461000, + 461000, + 461200, + 461200, + 461200, + 461200, + 461300, + 461300, + 461300, + 461400, + 461400, + 461400, + 461400, + 461500, + 461500, + 461500, + 461600, + 461600, + 461700, + 461800, + 461900, + 461900, + 461900, + 462000, + 462000, + 462000, + 462100, + 462100, + 462200, + 462200, + 462200, + 462300, + 462400, + 462400, + 462500, + 462600, + 462800, + 462800, + 462800, + 462800, + 462800, + 462900, + 463100, + 463100, + 463100, + 463200, + 463200, + 463200, + 463200, + 463300, + 463300, + 463400, + 463400, + 463600, + 463600, + 463800, + 463900, + 463900, + 463900, + 464000, + 464100, + 464200, + 464200, + 464300, + 464400, + 464400, + 464500, + 464600, + 464700, + 464800, + 465100, + 465200, + 465200, + 465200, + 465200, + 465200, + 465300, + 465300, + 465500, + 465500, + 465500, + 465500, + 465600, + 465700, + 465800, + 465900, + 466000, + 466100, + 466100, + 466200, + 466200, + 466200, + 466300, + 466600, + 466600, + 466700, + 467100, + 467100, + 467200, + 467300, + 467300, + 467300, + 467300, + 467400, + 467400, + 467500, + 467500, + 467600, + 467700, + 467700, + 467700, + 468000, + 468000, + 468000, + 468400, + 468500, + 468500, + 468500, + 468600, + 468600, + 468600, + 468600, + 468600, + 468700, + 468700, + 468800, + 468800, + 468800, + 468800, + 468900, + 468900, + 469000, + 469000, + 469100, + 469100, + 469100, + 469200, + 469300, + 469400, + 469600, + 469800, + 470100, + 470200, + 470200, + 470300, + 470300, + 470300, + 470400, + 470500, + 470500, + 470500, + 470600, + 470600, + 470600, + 470700, + 471000, + 471000, + 471200, + 471200, + 471400, + 471400, + 471500, + 471500, + 471600, + 471600, + 471700, + 471800, + 472200, + 472400, + 472600, + 472600, + 472600, + 472700, + 472800, + 473000, + 473000, + 473000, + 473100, + 473200, + 473200, + 473300, + 473300, + 473300, + 473400, + 473500, + 473500, + 473500, + 473700, + 473700, + 473700, + 473800, + 473800, + 473900, + 473900, + 473900, + 474000, + 474100, + 474200, + 474300, + 474300, + 474400, + 474400, + 474400, + 474500, + 474600, + 474600, + 475000, + 475100, + 475100, + 475100, + 475100, + 475200, + 475400, + 475600, + 475800, + 476100, + 476200, + 476200, + 476200, + 476300, + 476300, + 476600, + 476600, + 476900, + 477000, + 477300, + 477400, + 477400, + 477600, + 477700, + 477700, + 477800, + 477900, + 477900, + 477900, + 477900, + 478100, + 478200, + 478400, + 478500, + 478700, + 478700, + 479100, + 479100, + 479300, + 479300, + 479300, + 479500, + 479500, + 479600, + 479800, + 479900, + 480100, + 480200, + 480300, + 480300, + 480600, + 480700, + 480800, + 480800, + 480800, + 480900, + 480900, + 480900, + 481000, + 481000, + 481000, + 481700, + 481800, + 482000, + 482300, + 482500, + 482600, + 482800, + 482900, + 483000, + 483100, + 483200, + 483300, + 483600, + 483600, + 483700, + 483800, + 483800, + 484200, + 484200, + 484300, + 484600, + 484900, + 485100, + 485300, + 485400, + 485500, + 485500, + 485500, + 485600, + 485700, + 486000, + 486000, + 486000, + 486100, + 486100, + 486200, + 486200, + 486400, + 486800, + 487100, + 487200, + 487300, + 487300, + 487300, + 487400, + 487500, + 487500, + 487900, + 488000, + 488300, + 488300, + 488400, + 488600, + 488800, + 488900, + 488900, + 488900, + 489100, + 489100, + 489100, + 490200, + 490200, + 490300, + 490500, + 490900, + 491000, + 491100, + 491600, + 491800, + 492100, + 492400, + 492500, + 493000, + 493100, + 493700, + 494000, + 494000, + 494000, + 494200, + 494600, + 494700, + 494700, + 494700, + 495100, + 495700, + 496200, + 496500, + 496800, + 497000, + 497000, + 497100, + 497200, + 497200, + 497200, + 497700, + 497900, + 498100, + 498400, + 498500, + 498800, + 499000, + 499000, + 499300, + 499600, + 499800, + 500300, + 500400, + 500500, + 500900, + 501000, + 501200, + 501200, + 501400, + 501500, + 501600, + 502000, + 502600, + 502700, + 502800, + 503400, + 503600, + 503600, + 503700, + 503900, + 504000, + 504200, + 505100, + 505200, + 505400, + 505600, + 505600, + 506000, + 506200, + 506300, + 506500, + 506500, + 506900, + 507000, + 507400, + 507800, + 508400, + 508900, + 509400, + 509600, + 509800, + 509900, + 510000, + 510100, + 510300, + 510600, + 510900, + 510900, + 511700, + 511900, + 511900, + 512000, + 512300, + 512300, + 512600, + 512700, + 513000, + 513300, + 513600, + 513700, + 514700, + 515000, + 515000, + 515100, + 515500, + 515800, + 516100, + 516800, + 516900, + 517200, + 517700, + 517900, + 518100, + 518200, + 518900, + 519300, + 519500, + 519700, + 519700, + 520300, + 520500, + 520600, + 520600, + 520600, + 520800, + 521100, + 521200, + 521600, + 521800, + 521800, + 521800, + 522300, + 523000, + 523500, + 524000, + 524100, + 524100, + 524500, + 524600, + 524700, + 525200, + 525600, + 525700, + 525800, + 526600, + 526800, + 526800, + 527000, + 527700, + 528300, + 529000, + 529000, + 529700, + 530100, + 530600, + 530900, + 531100, + 531200, + 531300, + 531500, + 531700, + 531900, + 532300, + 532900, + 533000, + 533300, + 533700, + 533800, + 534000, + 534500, + 534700, + 535500, + 535600, + 536200, + 536400, + 536700, + 536800, + 536900, + 537200, + 537600, + 538800, + 539000, + 539100, + 539400, + 539500, + 539700, + 540000, + 540500, + 540500, + 540500, + 540700, + 542100, + 542900, + 543100, + 543300, + 543400, + 543400, + 545700, + 546200, + 547000, + 547100, + 547600, + 547900, + 547900, + 548800, + 549200, + 549700, + 550100, + 550400, + 552400, + 558800, + 559900, + 560100, + 560100, + 561200, + 563400, + 563900, + 564400, + 565200, + 565400, + 566800, + 568800, + 573300, + 574300, + 574600, + 575200, + 581900, + 589700, + 599200, + 604900, + 642100, + 663900, + 711300, + 726600, + 750400, + 771000, + 1231700, + 1278300, + 1278400, + 1300800, + 1310700, + 1311100, + 1312300, + 1316300, + 1320700, + 1322100, + 1322800, + 1330100, + 1333400, + 1334300, + 1336400, + 1340800, + 1345300, + 1345600, + 1348900, + 1353000, + 1373000, + 1387800, + 1410600, + 1427800, + 1462300, + 1465500, + 1467800, + 1468900, + 1475100, + 1485000, + 1500600, + 1505800, + 1510800, + 1515900, + 1524000, + 1536700, + 1558600, + 1596500, + 1666200, + 1705300, + 1708000, + 1711600, + 1726200, + 1747300 + ], + "min": 434800, + "max": 1747300, + "p25": 449000, + "p50": 457200, + "p75": 480800, + "p99": 1475100, + "p999": 1711600, + "avg": 499106.83274021355, + "ticks": 1405, + "heap": { + "_": 1365, + "total": 3128333672, + "min": 998632, + "max": 3577128, + "avg": 2291819.53992674 + } + }, + "args": {}, + "name": "handlebars large-loop" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta large-loop", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 225600, + 226100, + 226200, + 226400, + 226800, + 226800, + 227000, + 227100, + 227200, + 227200, + 227300, + 227300, + 227300, + 227300, + 227500, + 227500, + 227600, + 227700, + 227800, + 227800, + 227800, + 227800, + 227800, + 227900, + 228000, + 228000, + 228000, + 228000, + 228100, + 228100, + 228100, + 228100, + 228200, + 228200, + 228200, + 228300, + 228300, + 228400, + 228400, + 228400, + 228400, + 228400, + 228400, + 228500, + 228500, + 228500, + 228500, + 228500, + 228500, + 228500, + 228500, + 228600, + 228600, + 228700, + 228700, + 228700, + 228800, + 228800, + 228800, + 228800, + 228800, + 228800, + 228800, + 228900, + 228900, + 229000, + 229000, + 229000, + 229000, + 229100, + 229100, + 229100, + 229100, + 229100, + 229100, + 229100, + 229200, + 229200, + 229200, + 229200, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229400, + 229400, + 229400, + 229400, + 229400, + 229400, + 229400, + 229500, + 229500, + 229500, + 229500, + 229500, + 229500, + 229600, + 229600, + 229600, + 229600, + 229600, + 229600, + 229600, + 229700, + 229700, + 229700, + 229700, + 229700, + 229700, + 229700, + 229700, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229900, + 229900, + 229900, + 229900, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230200, + 230200, + 230200, + 230200, + 230200, + 230200, + 230300, + 230300, + 230300, + 230300, + 230300, + 230300, + 230300, + 230300, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231800, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232000, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232400, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232600, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 232900, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233000, + 233100, + 233100, + 233100, + 233100, + 233100, + 233100, + 233100, + 233100, + 233100, + 233100, + 233100, + 233100, + 233100, + 233100, + 233100, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233200, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233300, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233500, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233800, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 233900, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234200, + 234300, + 234300, + 234300, + 234300, + 234300, + 234300, + 234300, + 234300, + 234300, + 234300, + 234300, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234400, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234500, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234600, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234700, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234800, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 234900, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235000, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235100, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235200, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235300, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235400, + 235500, + 235500, + 235500, + 235500, + 235500, + 235500, + 235500, + 235500, + 235500, + 235500, + 235500, + 235500, + 235500, + 235500, + 235500, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235600, + 235700, + 235700, + 235700, + 235700, + 235700, + 235700, + 235700, + 235700, + 235700, + 235700, + 235700, + 235700, + 235700, + 235700, + 235700, + 235800, + 235800, + 235800, + 235800, + 235800, + 235800, + 235800, + 235800, + 235800, + 235800, + 235800, + 235800, + 235800, + 235800, + 235800, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 235900, + 236000, + 236000, + 236000, + 236000, + 236000, + 236000, + 236000, + 236000, + 236000, + 236000, + 236100, + 236100, + 236100, + 236100, + 236100, + 236100, + 236100, + 236100, + 236100, + 236100, + 236100, + 236200, + 236200, + 236200, + 236200, + 236200, + 236200, + 236200, + 236200, + 236200, + 236200, + 236200, + 236200, + 236200, + 236300, + 236300, + 236300, + 236300, + 236300, + 236300, + 236300, + 236300, + 236300, + 236300, + 236300, + 236300, + 236300, + 236400, + 236400, + 236400, + 236400, + 236400, + 236400, + 236400, + 236400, + 236400, + 236400, + 236500, + 236500, + 236500, + 236500, + 236500, + 236500, + 236500, + 236500, + 236500, + 236500, + 236500, + 236500, + 236500, + 236600, + 236600, + 236600, + 236600, + 236600, + 236600, + 236600, + 236600, + 236600, + 236600, + 236600, + 236600, + 236600, + 236600, + 236700, + 236700, + 236700, + 236700, + 236700, + 236700, + 236700, + 236700, + 236800, + 236800, + 236800, + 236800, + 236800, + 236800, + 236800, + 236800, + 236800, + 236800, + 236800, + 236900, + 236900, + 236900, + 236900, + 236900, + 236900, + 236900, + 236900, + 236900, + 236900, + 236900, + 237000, + 237000, + 237000, + 237000, + 237000, + 237000, + 237000, + 237000, + 237000, + 237000, + 237100, + 237100, + 237100, + 237100, + 237100, + 237100, + 237100, + 237100, + 237100, + 237100, + 237200, + 237200, + 237200, + 237200, + 237200, + 237200, + 237200, + 237200, + 237200, + 237300, + 237300, + 237300, + 237300, + 237300, + 237300, + 237300, + 237300, + 237300, + 237300, + 237400, + 237400, + 237400, + 237400, + 237400, + 237400, + 237400, + 237400, + 237400, + 237400, + 237500, + 237500, + 237500, + 237500, + 237600, + 237600, + 237600, + 237600, + 237600, + 237600, + 237600, + 237600, + 237700, + 237700, + 237700, + 237700, + 237700, + 237700, + 237700, + 237700, + 237800, + 237800, + 237800, + 237800, + 237800, + 237800, + 237800, + 237800, + 237900, + 237900, + 237900, + 237900, + 237900, + 237900, + 238000, + 238000, + 238000, + 238000, + 238100, + 238100, + 238100, + 238100, + 238100, + 238100, + 238100, + 238200, + 238200, + 238200, + 238200, + 238200, + 238200, + 238200, + 238200, + 238200, + 238200, + 238200, + 238300, + 238300, + 238300, + 238300, + 238300, + 238300, + 238300, + 238300, + 238300, + 238300, + 238300, + 238300, + 238300, + 238300, + 238400, + 238400, + 238400, + 238400, + 238400, + 238400, + 238400, + 238400, + 238500, + 238500, + 238500, + 238500, + 238500, + 238500, + 238500, + 238600, + 238600, + 238600, + 238600, + 238600, + 238600, + 238600, + 238600, + 238600, + 238600, + 238700, + 238700, + 238700, + 238700, + 238700, + 238700, + 238700, + 238700, + 238700, + 238700, + 238700, + 238800, + 238800, + 238800, + 238800, + 238800, + 238800, + 238800, + 238900, + 238900, + 238900, + 238900, + 238900, + 238900, + 238900, + 239000, + 239000, + 239000, + 239000, + 239000, + 239000, + 239100, + 239100, + 239100, + 239100, + 239100, + 239100, + 239100, + 239100, + 239100, + 239200, + 239200, + 239200, + 239200, + 239200, + 239200, + 239200, + 239200, + 239200, + 239300, + 239300, + 239300, + 239300, + 239300, + 239400, + 239400, + 239400, + 239400, + 239400, + 239400, + 239400, + 239400, + 239400, + 239400, + 239400, + 239500, + 239500, + 239500, + 239500, + 239600, + 239600, + 239600, + 239600, + 239600, + 239600, + 239600, + 239600, + 239600, + 239600, + 239700, + 239700, + 239700, + 239700, + 239700, + 239700, + 239700, + 239800, + 239800, + 239800, + 239800, + 239800, + 239900, + 239900, + 239900, + 239900, + 239900, + 239900, + 239900, + 239900, + 239900, + 239900, + 239900, + 240000, + 240000, + 240000, + 240000, + 240000, + 240000, + 240000, + 240100, + 240100, + 240100, + 240100, + 240100, + 240100, + 240100, + 240100, + 240200, + 240200, + 240200, + 240200, + 240200, + 240200, + 240200, + 240200, + 240200, + 240300, + 240300, + 240300, + 240300, + 240300, + 240300, + 240300, + 240300, + 240300, + 240400, + 240400, + 240400, + 240500, + 240500, + 240500, + 240500, + 240500, + 240500, + 240500, + 240600, + 240600, + 240600, + 240600, + 240600, + 240600, + 240600, + 240700, + 240700, + 240700, + 240700, + 240700, + 240700, + 240700, + 240700, + 240700, + 240800, + 240800, + 240800, + 240800, + 240800, + 240800, + 240800, + 240800, + 240900, + 240900, + 240900, + 240900, + 240900, + 240900, + 240900, + 240900, + 241000, + 241000, + 241000, + 241000, + 241000, + 241000, + 241000, + 241000, + 241100, + 241100, + 241100, + 241100, + 241100, + 241100, + 241100, + 241100, + 241200, + 241200, + 241200, + 241200, + 241200, + 241200, + 241200, + 241200, + 241200, + 241200, + 241300, + 241300, + 241300, + 241300, + 241300, + 241300, + 241400, + 241400, + 241400, + 241400, + 241400, + 241400, + 241400, + 241400, + 241400, + 241400, + 241400, + 241400, + 241400, + 241500, + 241500, + 241600, + 241600, + 241600, + 241600, + 241600, + 241600, + 241600, + 241600, + 241600, + 241600, + 241600, + 241700, + 241700, + 241700, + 241700, + 241700, + 241700, + 241700, + 241700, + 241700, + 241700, + 241700, + 241700, + 241800, + 241800, + 241800, + 241800, + 241800, + 241800, + 241800, + 241800, + 241800, + 241800, + 241800, + 241800, + 241900, + 241900, + 241900, + 241900, + 241900, + 241900, + 241900, + 241900, + 242000, + 242000, + 242000, + 242000, + 242000, + 242000, + 242100, + 242100, + 242100, + 242100, + 242100, + 242100, + 242100, + 242100, + 242200, + 242200, + 242200, + 242200, + 242300, + 242300, + 242300, + 242300, + 242300, + 242300, + 242400, + 242400, + 242400, + 242400, + 242500, + 242500, + 242500, + 242500, + 242500, + 242500, + 242500, + 242500, + 242600, + 242600, + 242600, + 242600, + 242600, + 242700, + 242700, + 242700, + 242700, + 242700, + 242700, + 242800, + 242800, + 242800, + 242800, + 242800, + 242800, + 242800, + 242800, + 242900, + 242900, + 242900, + 242900, + 242900, + 242900, + 242900, + 242900, + 242900, + 242900, + 242900, + 242900, + 242900, + 242900, + 243000, + 243000, + 243000, + 243000, + 243000, + 243100, + 243100, + 243100, + 243100, + 243100, + 243100, + 243100, + 243100, + 243100, + 243100, + 243200, + 243200, + 243200, + 243200, + 243200, + 243200, + 243300, + 243300, + 243300, + 243300, + 243300, + 243300, + 243300, + 243300, + 243300, + 243400, + 243400, + 243400, + 243400, + 243500, + 243500, + 243500, + 243500, + 243500, + 243500, + 243500, + 243500, + 243500, + 243600, + 243600, + 243600, + 243600, + 243600, + 243600, + 243600, + 243600, + 243600, + 243700, + 243700, + 243700, + 243800, + 243800, + 243800, + 243800, + 243800, + 243800, + 243900, + 243900, + 243900, + 243900, + 243900, + 243900, + 243900, + 244000, + 244000, + 244000, + 244000, + 244000, + 244000, + 244100, + 244100, + 244100, + 244100, + 244100, + 244100, + 244100, + 244100, + 244200, + 244200, + 244200, + 244200, + 244200, + 244300, + 244300, + 244300, + 244300, + 244300, + 244300, + 244400, + 244400, + 244400, + 244400, + 244400, + 244400, + 244400, + 244500, + 244500, + 244500, + 244500, + 244600, + 244600, + 244700, + 244700, + 244700, + 244700, + 244700, + 244700, + 244700, + 244700, + 244800, + 244800, + 244800, + 244800, + 244900, + 244900, + 245000, + 245000, + 245100, + 245300, + 245300, + 245300, + 245400, + 245400, + 245400, + 245500, + 245500, + 245500, + 245500, + 245600, + 245600, + 245600, + 245600, + 245600, + 245600, + 245700, + 245700, + 245800, + 245800, + 245800, + 245800, + 245800, + 245900, + 245900, + 246000, + 246000, + 246000, + 246000, + 246000, + 246100, + 246100, + 246100, + 246100, + 246200, + 246300, + 246300, + 246300, + 246300, + 246300, + 246400, + 246600, + 246600, + 246600, + 246700, + 246700, + 246700, + 246700, + 246700, + 246800, + 246800, + 246800, + 246900, + 247000, + 247000, + 247100, + 247100, + 247200, + 247200, + 247300, + 247300, + 247400, + 247400, + 247400, + 247400, + 247500, + 247500, + 247500, + 247700, + 247700, + 247700, + 247700, + 247800, + 247800, + 247800, + 247900, + 248000, + 248000, + 248000, + 248200, + 248300, + 248400, + 248500, + 248500, + 248600, + 248900, + 249000, + 249000, + 249000, + 249100, + 249200, + 249200, + 249200, + 249300, + 249400, + 249400, + 249400, + 249500, + 249700, + 249700, + 249800, + 249800, + 249800, + 249900, + 250200, + 250200, + 250200, + 250300, + 250300, + 250300, + 250400, + 250500, + 250500, + 250500, + 250900, + 251000, + 251000, + 251200, + 251300, + 251500, + 251500, + 251500, + 251600, + 251900, + 252000, + 252000, + 252000, + 252100, + 252200, + 252200, + 252200, + 252300, + 252300, + 252600, + 252800, + 252800, + 252800, + 252900, + 252900, + 252900, + 253000, + 253000, + 253100, + 253100, + 253200, + 253300, + 253300, + 253300, + 253300, + 253400, + 253400, + 253500, + 253600, + 253600, + 253600, + 253600, + 253800, + 253800, + 254100, + 254300, + 254300, + 254400, + 254500, + 254500, + 254500, + 254600, + 254700, + 254700, + 254800, + 254800, + 254900, + 255000, + 255000, + 255000, + 255000, + 255100, + 255100, + 255100, + 255200, + 255300, + 255400, + 255400, + 255500, + 255500, + 255600, + 255700, + 255700, + 255900, + 256100, + 256200, + 256300, + 256300, + 256500, + 256600, + 256700, + 256700, + 256900, + 256900, + 256900, + 256900, + 257100, + 257200, + 257200, + 257300, + 257300, + 257400, + 257400, + 257600, + 257600, + 257700, + 257800, + 257800, + 257900, + 257900, + 257900, + 258000, + 258000, + 258100, + 258100, + 258200, + 258200, + 258200, + 258400, + 258400, + 258500, + 258600, + 258600, + 258700, + 258700, + 258900, + 258900, + 259000, + 259100, + 259300, + 259500, + 259500, + 259500, + 259600, + 259700, + 259800, + 259900, + 259900, + 260000, + 260100, + 260200, + 260200, + 260500, + 260500, + 260500, + 260700, + 260800, + 260900, + 260900, + 261000, + 261500, + 261500, + 261500, + 261800, + 261800, + 262000, + 262400, + 262500, + 262600, + 263100, + 263100, + 263200, + 263200, + 263200, + 263300, + 263400, + 263500, + 263500, + 263500, + 263600, + 263700, + 263800, + 263900, + 264000, + 264100, + 264100, + 264200, + 264300, + 264400, + 264600, + 264700, + 264800, + 265000, + 265100, + 265100, + 265400, + 265800, + 265800, + 265800, + 266000, + 266000, + 266400, + 266400, + 266600, + 266600, + 266800, + 266900, + 266900, + 267200, + 267400, + 267400, + 267600, + 267600, + 267700, + 267800, + 267900, + 267900, + 268100, + 268300, + 268400, + 268700, + 268800, + 268900, + 269000, + 269200, + 269300, + 269500, + 269600, + 269700, + 269900, + 270000, + 270100, + 270300, + 270400, + 270400, + 270400, + 270500, + 270500, + 270900, + 271000, + 271000, + 271300, + 271400, + 271500, + 271600, + 271600, + 271600, + 271800, + 271900, + 271900, + 272000, + 272200, + 272200, + 272500, + 272700, + 272700, + 272800, + 273100, + 273200, + 273300, + 273400, + 273600, + 273600, + 273600, + 273800, + 273900, + 274000, + 274000, + 274000, + 274100, + 274200, + 274300, + 274400, + 274500, + 274600, + 274800, + 274900, + 274900, + 275000, + 275000, + 275000, + 275200, + 275200, + 275300, + 275400, + 275500, + 275500, + 275600, + 275700, + 275800, + 275900, + 275900, + 276000, + 276100, + 276200, + 276200, + 276300, + 276300, + 276300, + 276300, + 276500, + 276600, + 276600, + 276700, + 276800, + 276900, + 277100, + 277200, + 277300, + 277300, + 277500, + 277500, + 277600, + 277700, + 277800, + 277800, + 277800, + 277900, + 277900, + 278100, + 278300, + 278400, + 278400, + 278500, + 278600, + 278600, + 278700, + 278700, + 278700, + 278900, + 278900, + 278900, + 279000, + 279200, + 279200, + 279400, + 279500, + 279500, + 280000, + 280000, + 281000, + 281200, + 281300, + 281600, + 281800, + 281800, + 282400, + 282600, + 282800, + 282800, + 282900, + 282900, + 283000, + 283000, + 283100, + 283200, + 283400, + 283500, + 283500, + 283600, + 283600, + 283800, + 283900, + 284700, + 284800, + 285400, + 285600, + 286400, + 286500, + 286700, + 287100, + 287100, + 287200, + 287700, + 287700, + 288100, + 288600, + 290400, + 290600, + 290900, + 291400, + 291400, + 291700, + 292400, + 293200, + 293700, + 294800, + 294800, + 295500, + 295600, + 295800, + 295900, + 296400, + 296700, + 296800, + 297000, + 297200, + 297700, + 297800, + 298200, + 298900, + 299200, + 299700, + 299800, + 300000, + 300400, + 300800, + 301200, + 301200, + 301700, + 302000, + 302800, + 303100, + 303300, + 303300, + 303400, + 303600, + 304900, + 305200, + 305400, + 305600, + 306400, + 306800, + 307500, + 307500, + 308000, + 308100, + 308300, + 308500, + 309900, + 310100, + 312700, + 313400, + 313700, + 314700, + 317900, + 320400, + 323600, + 328400, + 329400, + 336100, + 336900, + 338300, + 338700, + 340400, + 342800, + 348700, + 350700, + 354700, + 358900, + 369800, + 542700, + 1517500, + 1534800, + 1538700, + 1543100, + 1545800, + 1546200, + 1554700, + 1558300, + 1565700, + 1567300, + 1571900, + 1581900, + 1591000, + 1594000, + 1595500, + 1599500, + 1609900, + 1614300, + 1614400, + 1617900, + 1618800, + 1634000, + 1670100, + 1684900, + 1740100, + 1754300, + 1938000, + 1988100, + 1995600, + 2057400 + ], + "min": 225600, + "max": 2057400, + "p25": 232600, + "p50": 235600, + "p75": 243200, + "p99": 1534800, + "p999": 1938000, + "avg": 257520.77205882352, + "ticks": 2720, + "heap": { + "_": 2692, + "total": 2694852512, + "min": 484848, + "max": 1295464, + "avg": 1001059.6255572066 + } + }, + "args": {}, + "name": "eta large-loop" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars mixed-page", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 269500, + 269800, + 269800, + 269900, + 269900, + 269900, + 269900, + 269900, + 270000, + 270200, + 270200, + 270200, + 270200, + 270300, + 270300, + 270400, + 270400, + 270500, + 270500, + 270500, + 270500, + 270500, + 270600, + 270600, + 270600, + 270700, + 270700, + 270700, + 270700, + 270700, + 270700, + 270700, + 270700, + 270700, + 270800, + 270800, + 270800, + 270800, + 270800, + 270900, + 270900, + 270900, + 270900, + 270900, + 270900, + 270900, + 271000, + 271000, + 271000, + 271000, + 271000, + 271000, + 271000, + 271000, + 271000, + 271000, + 271000, + 271100, + 271100, + 271100, + 271100, + 271100, + 271100, + 271100, + 271100, + 271200, + 271200, + 271200, + 271200, + 271200, + 271200, + 271200, + 271200, + 271200, + 271200, + 271200, + 271200, + 271200, + 271200, + 271300, + 271300, + 271300, + 271300, + 271300, + 271300, + 271300, + 271300, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271400, + 271500, + 271500, + 271500, + 271500, + 271500, + 271500, + 271500, + 271500, + 271500, + 271500, + 271500, + 271500, + 271500, + 271600, + 271600, + 271600, + 271600, + 271600, + 271600, + 271600, + 271600, + 271600, + 271600, + 271600, + 271600, + 271600, + 271600, + 271700, + 271700, + 271700, + 271700, + 271700, + 271700, + 271700, + 271700, + 271700, + 271700, + 271700, + 271800, + 271800, + 271800, + 271800, + 271800, + 271800, + 271800, + 271800, + 271800, + 271800, + 271900, + 271900, + 271900, + 271900, + 271900, + 271900, + 271900, + 271900, + 271900, + 271900, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272100, + 272100, + 272100, + 272100, + 272100, + 272100, + 272100, + 272100, + 272100, + 272100, + 272100, + 272100, + 272100, + 272100, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272200, + 272300, + 272300, + 272300, + 272300, + 272300, + 272300, + 272300, + 272300, + 272300, + 272300, + 272300, + 272300, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272400, + 272500, + 272500, + 272500, + 272500, + 272500, + 272500, + 272500, + 272500, + 272500, + 272500, + 272500, + 272500, + 272600, + 272600, + 272600, + 272600, + 272600, + 272600, + 272600, + 272600, + 272600, + 272600, + 272600, + 272600, + 272600, + 272700, + 272700, + 272700, + 272700, + 272700, + 272700, + 272700, + 272700, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 272900, + 273000, + 273000, + 273000, + 273000, + 273000, + 273000, + 273000, + 273000, + 273000, + 273000, + 273000, + 273000, + 273100, + 273100, + 273100, + 273100, + 273100, + 273100, + 273100, + 273100, + 273100, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273200, + 273300, + 273300, + 273300, + 273300, + 273300, + 273300, + 273300, + 273300, + 273300, + 273300, + 273300, + 273300, + 273300, + 273300, + 273300, + 273400, + 273400, + 273400, + 273400, + 273400, + 273400, + 273400, + 273400, + 273400, + 273400, + 273400, + 273400, + 273500, + 273500, + 273500, + 273500, + 273500, + 273500, + 273500, + 273500, + 273500, + 273500, + 273500, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273600, + 273700, + 273700, + 273700, + 273700, + 273700, + 273700, + 273700, + 273700, + 273700, + 273700, + 273700, + 273700, + 273700, + 273800, + 273800, + 273800, + 273800, + 273800, + 273800, + 273800, + 273800, + 273800, + 273800, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274000, + 274099.99999809265, + 274100, + 274100, + 274100, + 274100, + 274100, + 274100, + 274100, + 274100, + 274100, + 274100, + 274100, + 274100, + 274100, + 274100.0000009537, + 274200, + 274200, + 274200, + 274200, + 274200, + 274200, + 274200, + 274200, + 274200, + 274200, + 274200.00000190735, + 274299.9999990463, + 274299.9999990463, + 274300, + 274300, + 274300, + 274300, + 274300, + 274300, + 274300, + 274300, + 274300, + 274300.0000009537, + 274400, + 274400, + 274400, + 274400, + 274400, + 274400, + 274400, + 274400, + 274400, + 274400.0000009537, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500.00000190735, + 274599.9999990463, + 274600, + 274600, + 274600, + 274600, + 274600, + 274600, + 274600.0000009537, + 274700, + 274700, + 274700, + 274700, + 274700, + 274700, + 274700, + 274700, + 274700, + 274700, + 274700, + 274799.9999990463, + 274799.9999990463, + 274800, + 274800, + 274800, + 274800.0000009537, + 274899.99999809265, + 274900, + 274900, + 274900, + 274900, + 274900, + 274900, + 274900, + 274900, + 274900, + 274900, + 274900, + 274900.0000009537, + 275000, + 275000, + 275000, + 275000, + 275000, + 275000, + 275000, + 275099.9999990463, + 275100, + 275100, + 275100, + 275100, + 275100, + 275100, + 275100.0000009537, + 275100.0000009537, + 275199.99999809265, + 275200, + 275200, + 275200, + 275200, + 275200, + 275200, + 275200, + 275200, + 275299.9999990463, + 275299.9999990463, + 275299.9999990463, + 275300, + 275300, + 275300, + 275300, + 275300.0000009537, + 275300.0000009537, + 275300.00000190735, + 275399.99999809265, + 275399.99999809265, + 275400, + 275400, + 275400, + 275400, + 275400.0000009537, + 275500, + 275500, + 275500, + 275500, + 275500, + 275500, + 275500, + 275500, + 275500.00000190735, + 275599.9999990463, + 275599.9999990463, + 275599.9999990463, + 275599.9999990463, + 275599.9999990463, + 275599.9999990463, + 275599.9999990463, + 275600, + 275600, + 275600, + 275600, + 275600.0000009537, + 275600.0000009537, + 275700, + 275700, + 275700, + 275700, + 275700, + 275700, + 275700, + 275700.0000009537, + 275799.9999990463, + 275799.9999990463, + 275800, + 275800, + 275800, + 275899.99999809265, + 275899.99999809265, + 275900, + 275900, + 275900, + 275900, + 275900, + 275900, + 275900, + 275900.0000009537, + 275900.0000009537, + 275900.0000009537, + 275900.0000009537, + 276000, + 276000, + 276000, + 276000, + 276000, + 276000, + 276000, + 276000, + 276000, + 276099.9999990463, + 276099.9999990463, + 276100, + 276100, + 276100, + 276100.0000009537, + 276100.0000009537, + 276100.0000009537, + 276199.99999809265, + 276200, + 276200, + 276200, + 276200, + 276200.0000009537, + 276200.0000009537, + 276200.0000009537, + 276299.9999990463, + 276299.9999990463, + 276299.9999990463, + 276300, + 276300, + 276300.00000190735, + 276399.9999990463, + 276400, + 276400, + 276400, + 276400.0000009537, + 276400.0000009537, + 276499.9999990463, + 276500, + 276500, + 276500, + 276500, + 276500, + 276500, + 276500, + 276500, + 276599.9999990463, + 276599.9999990463, + 276599.9999990463, + 276600, + 276600, + 276600, + 276600.0000009537, + 276600.0000009537, + 276600.0000009537, + 276700, + 276700, + 276700, + 276700, + 276700, + 276700, + 276700, + 276700.0000009537, + 276700.0000009537, + 276700.0000009537, + 276700.0000009537, + 276700.0000009537, + 276799.9999990463, + 276799.9999990463, + 276800, + 276800, + 276800, + 276800.00000190735, + 276899.99999809265, + 276899.9999990463, + 276900, + 276900, + 276900, + 276900, + 276900, + 276900.0000009537, + 276900.0000009537, + 276900.0000009537, + 277000, + 277000, + 277000, + 277099.9999990463, + 277099.9999990463, + 277100, + 277100, + 277100, + 277100.0000009537, + 277199.9999990463, + 277200, + 277200, + 277200, + 277200.0000009537, + 277200.0000009537, + 277299.9999990463, + 277299.9999990463, + 277299.9999990463, + 277299.9999990463, + 277299.9999990463, + 277299.9999990463, + 277300, + 277300, + 277300, + 277300, + 277400, + 277400, + 277400.0000009537, + 277400.0000009537, + 277499.99999809265, + 277499.99999809265, + 277500, + 277500, + 277500, + 277500, + 277500, + 277500, + 277500, + 277500, + 277500, + 277500, + 277500.0000009537, + 277599.9999990463, + 277599.9999990463, + 277599.9999990463, + 277600, + 277600, + 277600, + 277600.0000009537, + 277600.0000009537, + 277700, + 277700, + 277700.0000009537, + 277700.0000009537, + 277700.0000009537, + 277700.0000009537, + 277800, + 277800, + 277800, + 277800, + 277800.00000190735, + 277899.9999990463, + 277899.9999990463, + 277899.9999990463, + 277900, + 277900, + 277999.99999809265, + 278000, + 278000, + 278000, + 278000, + 278000.0000009537, + 278000.0000009537, + 278099.9999990463, + 278099.9999990463, + 278100, + 278100.00000190735, + 278100.00000190735, + 278199.9999990463, + 278200, + 278200, + 278200.0000009537, + 278300, + 278300, + 278300, + 278300, + 278400.00000190735, + 278499.99999809265, + 278500, + 278600, + 278600, + 278600, + 278600.00000190735, + 278700, + 278700.0000009537, + 278700.0000009537, + 278800, + 278800, + 278800, + 278800, + 278800, + 278899.9999990463, + 278900, + 278999.99999809265, + 279000, + 279000.0000009537, + 279000.0000009537, + 279100, + 279100.00000190735, + 279199.9999990463, + 279200, + 279200.0000009537, + 279400, + 279400, + 279400, + 279400.00000190735, + 279500, + 279500, + 279500, + 279500, + 279599.9999990463, + 279600, + 279699.9999990463, + 279700, + 279700, + 279700, + 279700.0000009537, + 279800, + 279800, + 279800, + 279800, + 279800, + 279800, + 279899.9999990463, + 279900, + 279900, + 279900.00000190735, + 279999.9999990463, + 280000, + 280000, + 280000, + 280000.0000009537, + 280099.9999990463, + 280099.9999990463, + 280100, + 280100, + 280100, + 280100, + 280100, + 280100, + 280100, + 280100, + 280199.9999990463, + 280199.9999990463, + 280200, + 280200.0000009537, + 280200.0000009537, + 280200.0000009537, + 280200.0000009537, + 280200.0000009537, + 280299.99999809265, + 280299.99999809265, + 280300, + 280300, + 280399.9999990463, + 280399.9999990463, + 280399.9999990463, + 280399.9999990463, + 280400, + 280400, + 280400.00000190735, + 280499.9999990463, + 280499.9999990463, + 280500, + 280500, + 280500, + 280500.0000009537, + 280500.0000009537, + 280599.99999809265, + 280600, + 280600, + 280600, + 280600, + 280600, + 280600, + 280600, + 280600, + 280600, + 280600, + 280600, + 280600, + 280600, + 280600, + 280600, + 280699.9999990463, + 280699.9999990463, + 280699.9999990463, + 280699.9999990463, + 280699.9999990463, + 280699.9999990463, + 280700, + 280700, + 280700, + 280700, + 280700.0000009537, + 280700.0000009537, + 280700.00000190735, + 280799.99999809265, + 280800, + 280800, + 280800, + 280800.0000009537, + 280899.9999990463, + 280900, + 280900, + 280900, + 280900, + 280900, + 280900, + 280900.00000190735, + 280999.9999990463, + 280999.9999990463, + 281000, + 281000, + 281000, + 281000, + 281000, + 281000.0000009537, + 281099.99999809265, + 281100, + 281100, + 281100, + 281100, + 281100, + 281100, + 281100, + 281100, + 281100, + 281100, + 281100.0000009537, + 281199.9999990463, + 281199.9999990463, + 281199.9999990463, + 281199.9999990463, + 281199.9999990463, + 281199.9999990463, + 281199.9999990463, + 281200, + 281200, + 281200, + 281200, + 281200, + 281200, + 281200, + 281200.00000190735, + 281200.00000190735, + 281299.9999990463, + 281300, + 281300, + 281300, + 281300, + 281300, + 281300.0000009537, + 281300.0000009537, + 281399.9999990463, + 281399.9999990463, + 281400, + 281400, + 281400, + 281400, + 281400, + 281400, + 281400, + 281400, + 281400.00000190735, + 281499.9999990463, + 281499.9999990463, + 281499.9999990463, + 281499.9999990463, + 281499.9999990463, + 281500, + 281500, + 281500, + 281500.0000009537, + 281500.0000009537, + 281500.0000009537, + 281599.99999809265, + 281600, + 281600, + 281600, + 281600, + 281600, + 281600, + 281600.0000009537, + 281600.0000009537, + 281699.9999990463, + 281699.9999990463, + 281699.9999990463, + 281700, + 281700, + 281700, + 281700.00000190735, + 281799.9999990463, + 281800, + 281800, + 281800, + 281800, + 281800, + 281800, + 281800, + 281800, + 281800, + 281800, + 281800.0000009537, + 281800.0000009537, + 281800.0000009537, + 281899.9999990463, + 281900, + 281900, + 281900, + 281900, + 281900, + 281900, + 281900, + 281900, + 281900, + 281900, + 281900, + 281900, + 281900, + 281900, + 281999.9999990463, + 282000, + 282000, + 282000, + 282000, + 282000, + 282000, + 282000.0000009537, + 282000.0000009537, + 282000.00000190735, + 282099.99999809265, + 282099.99999809265, + 282100, + 282100, + 282100, + 282100, + 282100, + 282100, + 282100, + 282100, + 282100, + 282100.0000009537, + 282100.0000009537, + 282100.0000009537, + 282100.0000009537, + 282199.9999990463, + 282199.9999990463, + 282199.9999990463, + 282199.9999990463, + 282200, + 282200, + 282200, + 282299.99999809265, + 282299.9999990463, + 282299.9999990463, + 282300, + 282300, + 282300, + 282300, + 282300, + 282300, + 282300, + 282300, + 282300, + 282300.0000009537, + 282300.0000009537, + 282300.0000009537, + 282300.0000009537, + 282300.0000009537, + 282300.0000009537, + 282400, + 282400, + 282400, + 282400, + 282400, + 282400, + 282500, + 282500, + 282500, + 282500, + 282500, + 282500, + 282500.00000190735, + 282500.00000190735, + 282599.99999809265, + 282599.99999809265, + 282600, + 282600, + 282600, + 282600, + 282600, + 282600, + 282600, + 282600.0000009537, + 282600.0000009537, + 282600.0000009537, + 282700, + 282700, + 282700, + 282700, + 282700, + 282700, + 282700, + 282700, + 282799.9999990463, + 282800, + 282800, + 282800, + 282800, + 282900, + 282900, + 282900, + 282900, + 282900, + 282900, + 282999.9999990463, + 282999.9999990463, + 282999.9999990463, + 283000, + 283000, + 283000, + 283000, + 283000, + 283000, + 283000, + 283000, + 283000, + 283000, + 283000.0000009537, + 283000.0000009537, + 283000.00000190735, + 283099.99999809265, + 283099.99999809265, + 283100, + 283100, + 283100, + 283100, + 283100, + 283100, + 283100, + 283100, + 283100, + 283100.0000009537, + 283100.0000009537, + 283200, + 283200, + 283200, + 283200, + 283299.9999990463, + 283300, + 283300, + 283300, + 283300.0000009537, + 283300.0000009537, + 283300.0000009537, + 283300.00000190735, + 283400, + 283400, + 283400, + 283400, + 283400, + 283500, + 283500, + 283500, + 283500, + 283500, + 283500, + 283500, + 283500.00000190735, + 283599.9999990463, + 283600, + 283600, + 283600, + 283700, + 283700, + 283700, + 283700, + 283700, + 283700, + 283700, + 283700, + 283700, + 283799.9999990463, + 283799.9999990463, + 283799.9999990463, + 283800, + 283800, + 283800.0000009537, + 283900, + 283900, + 283900, + 283900, + 283999.9999990463, + 283999.9999990463, + 284000, + 284000, + 284000, + 284000, + 284000, + 284000, + 284000, + 284099.9999990463, + 284100, + 284100, + 284100, + 284100, + 284100, + 284199.99999809265, + 284200, + 284200, + 284200, + 284200, + 284200, + 284299.9999990463, + 284300, + 284300, + 284300, + 284300.0000009537, + 284300.00000190735, + 284399.99999809265, + 284399.9999990463, + 284400, + 284400.0000009537, + 284499.9999990463, + 284499.9999990463, + 284500, + 284500, + 284500, + 284500, + 284599.9999990463, + 284599.9999990463, + 284599.9999990463, + 284600, + 284600, + 284600, + 284600, + 284600, + 284600, + 284600.0000009537, + 284699.99999809265, + 284700, + 284700, + 284700, + 284700, + 284700, + 284700, + 284700, + 284700.0000009537, + 284700.0000009537, + 284799.9999990463, + 284799.9999990463, + 284800, + 284800, + 284800, + 284800, + 284899.99999809265, + 284899.9999990463, + 284900, + 284900, + 284900, + 284900.0000009537, + 284900.0000009537, + 285000, + 285000, + 285000, + 285000, + 285000, + 285000, + 285000, + 285099.9999990463, + 285100, + 285100, + 285100, + 285100, + 285100, + 285100, + 285100.0000009537, + 285100.0000009537, + 285100.00000190735, + 285200, + 285200, + 285200.0000009537, + 285299.9999990463, + 285300, + 285300, + 285399.9999990463, + 285400, + 285400, + 285400.0000009537, + 285400.0000009537, + 285400.0000009537, + 285500, + 285500, + 285500, + 285500, + 285500, + 285500, + 285500, + 285500, + 285500, + 285599.9999990463, + 285599.9999990463, + 285600, + 285600, + 285600, + 285600.0000009537, + 285699.99999809265, + 285700, + 285700, + 285700, + 285700, + 285700, + 285800, + 285800, + 285800, + 285800.00000190735, + 285800.00000190735, + 285900, + 285900, + 285900, + 285900, + 285900.0000009537, + 285900.0000009537, + 285900.0000009537, + 285900.0000009537, + 286000, + 286000, + 286000.0000009537, + 286099.9999990463, + 286100, + 286100, + 286100.00000190735, + 286199.99999809265, + 286200, + 286200, + 286200, + 286200, + 286200.0000009537, + 286200.0000009537, + 286200.0000009537, + 286200.0000009537, + 286200.0000009537, + 286299.9999990463, + 286300, + 286399.9999990463, + 286400, + 286400.0000009537, + 286400.0000009537, + 286400.0000009537, + 286499.99999809265, + 286500, + 286500, + 286500, + 286500, + 286500, + 286600, + 286600, + 286600, + 286600, + 286600, + 286600.0000009537, + 286699.99999809265, + 286699.99999809265, + 286700, + 286700.0000009537, + 286800, + 286899.9999990463, + 286899.9999990463, + 286900, + 286900.0000009537, + 286900.0000009537, + 286900.0000009537, + 286999.99999809265, + 287000, + 287000, + 287000, + 287000, + 287000, + 287000, + 287000.0000009537, + 287099.9999990463, + 287099.9999990463, + 287100.00000190735, + 287200, + 287200.0000009537, + 287300, + 287300, + 287300, + 287300, + 287300, + 287300, + 287300, + 287399.9999990463, + 287400, + 287400.0000009537, + 287400.0000009537, + 287500, + 287500.0000009537, + 287500.0000009537, + 287500.0000009537, + 287600, + 287600, + 287600, + 287600, + 287600, + 287699.9999990463, + 287699.9999990463, + 287699.9999990463, + 287700, + 287700, + 287800, + 287800, + 287800.0000009537, + 287899.9999990463, + 287900, + 287900, + 287900.0000009537, + 287900.0000009537, + 287900.00000190735, + 288000, + 288000, + 288000.0000009537, + 288099.9999990463, + 288100, + 288100, + 288100, + 288100.00000190735, + 288199.9999990463, + 288200, + 288200.0000009537, + 288300, + 288300, + 288300, + 288399.9999990463, + 288400, + 288400.0000009537, + 288500, + 288600, + 288600, + 288600.00000190735, + 288699.9999990463, + 288700, + 288700.0000009537, + 288800, + 288800, + 288800, + 288800.0000009537, + 288900, + 289000, + 289000.0000009537, + 289100, + 289100, + 289199.9999990463, + 289199.9999990463, + 289200.0000009537, + 289200.0000009537, + 289300, + 289300, + 289399.9999990463, + 289400, + 289499.99999809265, + 289499.9999990463, + 289499.9999990463, + 289500.0000009537, + 289600, + 289699.9999990463, + 289700, + 289700.0000009537, + 289800.0000009537, + 289800.0000009537, + 289899.9999990463, + 289900, + 289900, + 289900, + 289900, + 289999.9999990463, + 290000, + 290000.0000009537, + 290100, + 290100, + 290100, + 290100.0000009537, + 290100.0000009537, + 290200, + 290200, + 290300, + 290300.0000009537, + 290300.0000009537, + 290300.0000009537, + 290300.0000009537, + 290400, + 290400, + 290400, + 290499.9999990463, + 290500.0000009537, + 290500.0000009537, + 290500.0000009537, + 290500.0000009537, + 290599.99999809265, + 290599.99999809265, + 290599.99999809265, + 290600, + 290600, + 290600.0000009537, + 290699.9999990463, + 290699.9999990463, + 290699.9999990463, + 290700, + 290800, + 290800.0000009537, + 290800.0000009537, + 290800.0000009537, + 290900, + 290999.9999990463, + 290999.9999990463, + 291000, + 291000, + 291000.0000009537, + 291100, + 291100, + 291100.0000009537, + 291100.0000009537, + 291100.0000009537, + 291200, + 291200, + 291200, + 291200.00000190735, + 291300, + 291300, + 291300.0000009537, + 291300.0000009537, + 291400, + 291400, + 291400, + 291400, + 291499.9999990463, + 291500.00000190735, + 291600.0000009537, + 291600.0000009537, + 291600.0000009537, + 291699.9999990463, + 291699.9999990463, + 291699.9999990463, + 291700, + 291700, + 291700, + 291700.00000190735, + 291799.9999990463, + 291800, + 291800.0000009537, + 291800.0000009537, + 291800.0000009537, + 291800.0000009537, + 291800.0000009537, + 291800.0000009537, + 291899.99999809265, + 291899.99999809265, + 291900, + 291900, + 291900, + 291900, + 291999.9999990463, + 291999.9999990463, + 292000.00000190735, + 292000.00000190735, + 292099.99999809265, + 292100.0000009537, + 292100.0000009537, + 292100.0000009537, + 292200, + 292299.9999990463, + 292299.9999990463, + 292300, + 292300, + 292399.99999809265, + 292400, + 292400.0000009537, + 292499.9999990463, + 292500, + 292500, + 292500.00000190735, + 292599.9999990463, + 292599.9999990463, + 292599.9999990463, + 292599.9999990463, + 292600, + 292600.0000009537, + 292600.0000009537, + 292600.0000009537, + 292699.9999990463, + 292700, + 292700, + 292700, + 292700, + 292700, + 292799.9999990463, + 292799.9999990463, + 292799.9999990463, + 292799.9999990463, + 292799.9999990463, + 292899.99999809265, + 292900.0000009537, + 292999.9999990463, + 293000, + 293000, + 293000.00000190735, + 293099.9999990463, + 293100.0000009537, + 293100.0000009537, + 293200, + 293200, + 293200, + 293200, + 293299.9999990463, + 293299.9999990463, + 293300, + 293300.0000009537, + 293300.0000009537, + 293300.00000190735, + 293400, + 293599.9999990463, + 293700, + 293700, + 293700.0000009537, + 293800.00000190735, + 293800.00000190735, + 293900, + 293900.0000009537, + 293900.0000009537, + 294000, + 294000, + 294100, + 294200, + 294200.0000009537, + 294200.0000009537, + 294399.9999990463, + 294399.9999990463, + 294399.9999990463, + 294400, + 294400.0000009537, + 294500, + 294500, + 294500, + 294500, + 294500, + 294600, + 294600, + 294699.99999809265, + 294700, + 294700.0000009537, + 295000, + 295000, + 295000, + 295099.9999990463, + 295200, + 295200, + 295200, + 295200.0000009537, + 295400.0000009537, + 295499.99999809265, + 295699.99999809265, + 295700, + 295700.0000009537, + 295700.0000009537, + 295800, + 295999.99999809265, + 296000, + 296200.0000009537, + 296300, + 296300, + 296399.9999990463, + 296500, + 296599.9999990463, + 296599.9999990463, + 296699.9999990463, + 296700, + 296700.0000009537, + 296799.99999809265, + 296800, + 296800.0000009537, + 296899.9999990463, + 296999.99999809265, + 297000.0000009537, + 297000.0000009537, + 297099.9999990463, + 297199.9999990463, + 297300, + 297300, + 297400, + 297500, + 297500.0000009537, + 297600, + 297600.00000190735, + 297699.9999990463, + 297800, + 297800, + 297800.0000009537, + 297899.9999990463, + 297900, + 298000, + 298100, + 298100, + 298300.0000009537, + 298400, + 298600, + 298700.00000190735, + 298799.99999809265, + 298800.0000009537, + 298899.9999990463, + 298900, + 298999.9999990463, + 298999.9999990463, + 299000, + 299000, + 299000.0000009537, + 299000.0000009537, + 299199.9999990463, + 299199.9999990463, + 299300, + 299400, + 299400.00000190735, + 299499.9999990463, + 299500.00000190735, + 299600, + 299699.9999990463, + 299700, + 299900, + 300000.0000009537, + 300000.0000009537, + 300100.0000009537, + 300400, + 300499.9999990463, + 300500, + 300600, + 300799.9999990463, + 300800, + 300800, + 300800.0000009537, + 300999.9999990463, + 301099.99999809265, + 301100.0000009537, + 301300.0000009537, + 301300.0000009537, + 301300.0000009537, + 301699.9999990463, + 301799.9999990463, + 301799.9999990463, + 301800.00000190735, + 301900, + 302000, + 302100, + 302200, + 302300, + 302400.0000009537, + 302499.9999990463, + 302500, + 302599.9999990463, + 302699.99999809265, + 302700, + 302700, + 302800, + 303000, + 303099.9999990463, + 303100.0000009537, + 303200, + 303200.0000009537, + 303300, + 303399.9999990463, + 303500, + 303500, + 303500, + 303599.9999990463, + 303600.00000190735, + 303600.00000190735, + 303600.00000190735, + 303700, + 303799.9999990463, + 303800, + 303899.9999990463, + 304000, + 304099.9999990463, + 304199.99999809265, + 304200.0000009537, + 304500.0000009537, + 304599.9999990463, + 304599.9999990463, + 304600, + 304600.00000190735, + 304800, + 304800, + 304800.00000190735, + 304900.0000009537, + 305000.0000009537, + 305000.0000009537, + 305499.99999809265, + 305599.9999990463, + 305600, + 305600, + 305800, + 305800, + 306500, + 306800, + 306899.9999990463, + 306899.9999990463, + 307199.9999990463, + 307200.0000009537, + 307299.99999809265, + 307399.9999990463, + 307400, + 307600, + 307600, + 307800, + 307900, + 308100, + 308299.9999990463, + 308299.9999990463, + 308400, + 308400, + 308499.9999990463, + 308600, + 308900, + 308900, + 308900, + 309000.00000190735, + 309100, + 309199.9999990463, + 309199.9999990463, + 309300.0000009537, + 309400, + 309400, + 309700, + 309799.9999990463, + 310100, + 310200, + 310300, + 310400, + 310700, + 310799.9999990463, + 311000.00000190735, + 311400, + 311400.0000009537, + 311499.9999990463, + 311600.0000009537, + 311700, + 311700.0000009537, + 312100, + 312200, + 312200, + 312399.99999809265, + 312500, + 312500, + 312700, + 312800, + 312800, + 312899.9999990463, + 312999.99999809265, + 313300, + 313300, + 313399.9999990463, + 313399.9999990463, + 313800, + 313800, + 313900.00000190735, + 314100, + 314200.0000009537, + 314300, + 314399.9999990463, + 314499.99999809265, + 314499.99999809265, + 314500, + 314599.9999990463, + 314600.00000190735, + 314700.0000009537, + 314800, + 314899.9999990463, + 314900.00000190735, + 315000, + 315000, + 315099.9999990463, + 315099.9999990463, + 315300, + 315300, + 315399.9999990463, + 315400, + 315499.99999809265, + 315500, + 315500.0000009537, + 315700.0000009537, + 315800.0000009537, + 315900, + 315900, + 315900, + 316200, + 316200, + 316300.0000009537, + 316600, + 316600, + 316900, + 317100, + 317199.9999990463, + 317199.9999990463, + 317200.00000190735, + 317300.0000009537, + 317300.0000009537, + 317400, + 317500.00000190735, + 317699.9999990463, + 317699.9999990463, + 317699.9999990463, + 317799.99999809265, + 317799.9999990463, + 317800, + 317900, + 317999.9999990463, + 318100, + 318200, + 318200, + 318200, + 318200, + 318200, + 318299.9999990463, + 318300.0000009537, + 318400, + 318500.0000009537, + 318900, + 318999.9999990463, + 318999.9999990463, + 319299.9999990463, + 319499.9999990463, + 319500, + 319599.99999809265, + 319599.99999809265, + 319700, + 319700, + 319799.9999990463, + 319800, + 319800.0000009537, + 319800.00000190735, + 319900.0000009537, + 319999.9999990463, + 320000, + 320000, + 320000.00000190735, + 320100.0000009537, + 320100.0000009537, + 320100.0000009537, + 320399.99999809265, + 320799.9999990463, + 320799.9999990463, + 320800.00000190735, + 320999.9999990463, + 321000, + 321299.9999990463, + 321300, + 321400, + 321400.0000009537, + 321400.0000009537, + 321400.0000009537, + 321500, + 321600.0000009537, + 321700.0000009537, + 321899.9999990463, + 322000, + 322000, + 322100.0000009537, + 322100.00000190735, + 322300, + 322300.00000190735, + 322400, + 322400.0000009537, + 322400.0000009537, + 322500.0000009537, + 322500.0000009537, + 322599.9999990463, + 322600, + 322699.9999990463, + 322799.9999990463, + 323000, + 323000.0000009537, + 323100, + 323200.0000009537, + 323200.0000009537, + 323400.0000009537, + 323400.0000009537, + 323599.9999990463, + 323600, + 323700, + 323700.0000009537, + 323899.9999990463, + 323899.9999990463, + 323900.0000009537, + 323900.00000190735, + 324000.0000009537, + 324099.9999990463, + 324199.9999990463, + 324199.9999990463, + 324200.0000009537, + 324300, + 324400.00000190735, + 324500.0000009537, + 324600, + 324699.9999990463, + 324800, + 325000.0000009537, + 325000.0000009537, + 325100, + 325100, + 325100, + 325299.99999809265, + 325300.0000009537, + 325400, + 325499.9999990463, + 325600.0000009537, + 325799.99999809265, + 325999.9999990463, + 326099.99999809265, + 326499.9999990463, + 326600, + 326700.00000190735, + 326800.0000009537, + 327000.0000009537, + 327400, + 327500, + 327600.0000009537, + 327700, + 327700, + 327900, + 327900, + 327900, + 328299.9999990463, + 328399.99999809265, + 328599.99999809265, + 328599.9999990463, + 328700, + 328800, + 328900, + 329099.9999990463, + 329200, + 329200, + 329200, + 329200, + 329300.0000009537, + 329400.0000009537, + 329800, + 330100, + 330100, + 330200, + 330200.0000009537, + 330300, + 330400.0000009537, + 330400.0000009537, + 330400.0000009537, + 330500, + 330500, + 330600.0000009537, + 330800, + 330800, + 330800, + 330899.9999990463, + 330900, + 330900, + 331000, + 331099.9999990463, + 331100.0000009537, + 331199.99999809265, + 331399.9999990463, + 331400.0000009537, + 331500.0000009537, + 331699.99999809265, + 331800, + 331800, + 331800, + 331900, + 332200.0000009537, + 332200.0000009537, + 332400.00000190735, + 332800, + 332800.0000009537, + 332899.9999990463, + 332999.99999809265, + 333100, + 333100, + 333100.00000190735, + 333199.9999990463, + 333300, + 333300, + 333400, + 333400.00000190735, + 333800.0000009537, + 334000, + 334199.9999990463, + 334200, + 334499.99999809265, + 334500.0000009537, + 335099.99999809265, + 335500, + 335699.9999990463, + 335700.00000190735, + 335799.9999990463, + 335999.9999990463, + 336200.00000190735, + 336300.0000009537, + 336500.0000009537, + 336700, + 336999.9999990463, + 337000, + 337099.99999809265, + 337099.9999990463, + 337700, + 337900, + 338200, + 338200, + 338299.9999990463, + 338399.9999990463, + 338500, + 338599.9999990463, + 338700, + 338799.9999990463, + 339000, + 339000, + 339000, + 339000, + 339200.0000009537, + 339400.0000009537, + 339400.0000009537, + 339800, + 339800, + 339800, + 340199.99999809265, + 340599.9999990463, + 340800, + 340800, + 341100, + 341699.9999990463, + 342000, + 342100, + 342200, + 342300, + 342499.9999990463, + 342600, + 342600, + 342899.9999990463, + 342900, + 342900, + 343000, + 343400, + 343500, + 343500.0000009537, + 343799.9999990463, + 344000.0000009537, + 344100, + 344300, + 344400, + 344499.9999990463, + 344599.99999809265, + 344800.0000009537, + 345100.0000009537, + 345200, + 345300, + 345400, + 345800, + 346000.00000190735, + 346100, + 346100, + 346500, + 347000, + 347200, + 347300, + 347399.9999990463, + 347600, + 347799.9999990463, + 349400, + 349600, + 350300, + 350400, + 350600.00000190735, + 351600, + 351800, + 352000.0000009537, + 352299.99999809265, + 352600.0000009537, + 352899.9999990463, + 352900, + 353100, + 353400, + 354100, + 354200, + 354799.9999990463, + 355400, + 355900, + 356499.9999990463, + 356800, + 357300.00000190735, + 358100, + 358600, + 358699.99999809265, + 359100, + 359600, + 360100, + 360999.9999990463, + 361100, + 361900, + 362300.0000009537, + 362400, + 362400, + 363600, + 363900, + 364700, + 366700, + 367200, + 367599.9999990463, + 367900, + 369300, + 370700, + 370900, + 370999.9999990463, + 370999.9999990463, + 371000, + 372100, + 374900.0000009537, + 376200, + 376400, + 376900, + 378000, + 378700, + 385500, + 386300, + 387000.0000009537, + 388100, + 389000.0000009537, + 389400, + 396000, + 396700, + 399000, + 401200, + 402400, + 404500, + 406000, + 407900, + 409200, + 410800, + 417400, + 418500.00000190735, + 420700, + 420800, + 422899.9999990463, + 425799.9999990463, + 427500, + 428200, + 429599.9999990463, + 431900, + 432800, + 433400, + 435200, + 436900, + 437200, + 437600, + 445900, + 455000, + 455400, + 461500, + 472900, + 475400, + 480900, + 518800, + 528100.0000009537, + 537800, + 541700, + 542500, + 544500, + 554100, + 559400, + 559800.0000009537, + 560100.0000009537, + 574400, + 574800, + 576300, + 578100, + 581100, + 584800, + 586499.9999990463, + 587500, + 592600, + 595300.0000009537, + 596100, + 606300, + 609100, + 611100, + 626599.9999990463, + 629000.0000009537, + 634400.0000009537, + 637600, + 638300.0000009537, + 640199.9999990463, + 645399.9999990463, + 649200, + 659099.9999990463, + 662699.9999990463, + 665300.0000009537, + 682700, + 689399.9999990463, + 712700, + 715200, + 739800, + 741799.9999990463, + 761800, + 779700.0000009537 + ], + "min": 269500, + "max": 779700.0000009537, + "p25": 275299.9999990463, + "p50": 283000.00000190735, + "p75": 299300, + "p99": 592600, + "p999": 739800, + "avg": 298610.4972375703, + "ticks": 2353, + "heap": { + "_": 2318, + "total": 2252840968, + "min": 936, + "max": 2239320, + "avg": 971889.977566868 + } + }, + "args": {}, + "name": "handlebars mixed-page" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta mixed-page", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 14663.2568359375, + 14667.3583984375, + 14684.6923828125, + 14693.310546875, + 14696.5576171875, + 14711.4501953125, + 14712.5732421875, + 14717.7734375, + 14736.4990234375, + 14759.1552734375, + 14789.3310546875, + 14898.681640625 + ], + "min": 14663.2568359375, + "max": 14898.681640625, + "p25": 14684.6923828125, + "p50": 14711.4501953125, + "p75": 14736.4990234375, + "p99": 14789.3310546875, + "p999": 14789.3310546875, + "avg": 14727.553304036459, + "ticks": 49152, + "heap": { + "_": 2, + "total": 29843.3125, + "min": 14905.19140625, + "max": 14938.12109375, + "avg": 14921.65625 + } + }, + "args": {}, + "name": "eta mixed-page" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars conditional-heavy", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 251400, + 251500, + 251600, + 251600, + 251700, + 251800, + 251800, + 251900, + 251900, + 251900, + 251900, + 252000, + 252000, + 252100, + 252100, + 252100, + 252200, + 252200, + 252300, + 252300, + 252300, + 252400, + 252400, + 252400, + 252400, + 252500, + 252500, + 252500, + 252500, + 252500, + 252500, + 252600, + 252600, + 252600, + 252600, + 252600, + 252700, + 252700, + 252700, + 252800, + 252800, + 252800, + 252800, + 252800, + 252800, + 252800, + 252800, + 252800, + 252800, + 252800, + 252900, + 252900, + 252900, + 253000, + 253000, + 253000, + 253000, + 253100, + 253100, + 253100, + 253200, + 253200, + 253200, + 253200, + 253200, + 253300, + 253300, + 253300, + 253300, + 253300, + 253300, + 253300, + 253300, + 253300, + 253300, + 253300, + 253400, + 253400, + 253400, + 253400, + 253400, + 253400, + 253400, + 253400, + 253500, + 253500, + 253500, + 253500, + 253500, + 253500, + 253500, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253600, + 253700, + 253700, + 253700, + 253700, + 253700, + 253700, + 253700, + 253700, + 253700, + 253700, + 253800, + 253800, + 253800, + 253800, + 253800, + 253800, + 253800, + 253800, + 253900, + 253900, + 253900, + 253900, + 253900, + 253900, + 253900, + 253900, + 253900, + 253900, + 254000, + 254000, + 254000, + 254000, + 254000, + 254000, + 254100, + 254100, + 254100, + 254100, + 254100, + 254100, + 254100, + 254100, + 254100, + 254100, + 254100, + 254200, + 254200, + 254200, + 254200, + 254200, + 254200, + 254200, + 254200, + 254200, + 254200, + 254200, + 254200, + 254200, + 254300, + 254300, + 254300, + 254300, + 254300, + 254300, + 254300, + 254300, + 254300, + 254300, + 254400, + 254400, + 254400, + 254400, + 254400, + 254400, + 254400, + 254400, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254500, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254600, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254700, + 254800, + 254800, + 254800, + 254800, + 254800, + 254800, + 254800, + 254800, + 254900, + 254900, + 254900, + 254900, + 254900, + 254900, + 254900, + 254900, + 254900, + 254900, + 254900, + 255000, + 255000, + 255000, + 255000, + 255000, + 255000, + 255000, + 255000, + 255000, + 255000, + 255000, + 255000, + 255000, + 255100, + 255100, + 255100, + 255100, + 255100, + 255100, + 255100, + 255100, + 255100, + 255100, + 255100, + 255100, + 255100, + 255100, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255200, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255300, + 255400, + 255400, + 255400, + 255400, + 255400, + 255400, + 255400, + 255400, + 255400, + 255400, + 255400, + 255400, + 255400, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255500, + 255600, + 255600, + 255600, + 255600, + 255600, + 255600, + 255600, + 255600, + 255600, + 255600, + 255600, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255700, + 255800, + 255800, + 255800, + 255800, + 255800, + 255800, + 255800, + 255800, + 255800, + 255800, + 255800, + 255800, + 255800, + 255900, + 255900, + 255900, + 255900, + 255900, + 255900, + 255900, + 255900, + 255900, + 255900, + 255900, + 255900, + 256000, + 256000, + 256000, + 256000, + 256000, + 256000, + 256000, + 256000, + 256000, + 256000, + 256000, + 256000, + 256000, + 256000, + 256000, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256100, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256300, + 256300, + 256300, + 256300, + 256300, + 256300, + 256300, + 256300, + 256300, + 256300, + 256300, + 256300, + 256400, + 256400, + 256400, + 256400, + 256400, + 256400, + 256400, + 256400, + 256400, + 256400, + 256400, + 256400, + 256500, + 256500, + 256500, + 256500, + 256500, + 256500, + 256500, + 256500, + 256500, + 256500, + 256500, + 256500, + 256500, + 256500, + 256600, + 256600, + 256600, + 256600, + 256600, + 256600, + 256600, + 256600, + 256600, + 256600, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256700, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256800, + 256900, + 256900, + 256900, + 256900, + 256900, + 256900, + 256900, + 256900, + 256900, + 256900, + 256900, + 256900, + 256900, + 257000, + 257000, + 257000, + 257100, + 257100, + 257100, + 257100, + 257100, + 257100, + 257100, + 257100, + 257100, + 257100, + 257100, + 257100, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257200, + 257300, + 257300, + 257300, + 257300, + 257300, + 257300, + 257300, + 257300, + 257300, + 257300, + 257300, + 257400, + 257400, + 257400, + 257400, + 257400, + 257400, + 257400, + 257400, + 257500, + 257500, + 257500, + 257500, + 257500, + 257500, + 257500, + 257500, + 257500, + 257500, + 257500, + 257500, + 257600, + 257600, + 257600, + 257600, + 257600, + 257600, + 257600, + 257600, + 257600, + 257600, + 257600, + 257600, + 257700, + 257700, + 257700, + 257700, + 257700, + 257700, + 257700, + 257700, + 257700, + 257700, + 257700, + 257700, + 257800, + 257800, + 257800, + 257800, + 257800, + 257800, + 257800, + 257800, + 257800, + 257800, + 257800, + 257900, + 257900, + 257900, + 257900, + 257900, + 257900, + 257900, + 257900, + 257900, + 257900, + 257900, + 257900, + 257900, + 258000, + 258000, + 258000, + 258000, + 258000, + 258000, + 258000, + 258000, + 258000, + 258000, + 258100, + 258100, + 258100, + 258100, + 258100, + 258100, + 258100, + 258100, + 258200, + 258200, + 258200, + 258200, + 258200, + 258200, + 258200, + 258200, + 258200, + 258200, + 258200, + 258200, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258300, + 258400, + 258400, + 258400, + 258400, + 258400, + 258400, + 258400, + 258400, + 258400, + 258400, + 258400, + 258400, + 258400, + 258400, + 258500, + 258500, + 258500, + 258500, + 258500, + 258500, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258600, + 258700, + 258700, + 258700, + 258700, + 258700, + 258800, + 258800, + 258800, + 258800, + 258800, + 258800, + 258800, + 258800, + 258800, + 258800, + 258900, + 258900, + 258900, + 258900, + 258900, + 258900, + 258900, + 258900, + 258900, + 258900, + 258900, + 258900, + 259000, + 259000, + 259000, + 259000, + 259000, + 259000, + 259000, + 259000, + 259000, + 259000, + 259000, + 259000, + 259100, + 259100, + 259100, + 259100, + 259100, + 259100, + 259100, + 259100, + 259100, + 259100, + 259100, + 259100, + 259100, + 259100, + 259100, + 259200, + 259200, + 259200, + 259200, + 259200, + 259200, + 259200, + 259200, + 259200, + 259300, + 259300, + 259300, + 259300, + 259300, + 259400, + 259400, + 259400, + 259400, + 259400, + 259500, + 259500, + 259500, + 259500, + 259500, + 259500, + 259500, + 259500, + 259500, + 259500, + 259500, + 259500, + 259500, + 259500, + 259600, + 259600, + 259600, + 259600, + 259600, + 259600, + 259600, + 259600, + 259600, + 259600, + 259600, + 259600, + 259600, + 259600, + 259700, + 259700, + 259700, + 259700, + 259700, + 259700, + 259700, + 259700, + 259700, + 259700, + 259800, + 259800, + 259800, + 259800, + 259800, + 259800, + 259800, + 259900, + 259900, + 259900, + 259900, + 259900, + 259900, + 260000, + 260000, + 260000, + 260000, + 260000, + 260000, + 260000, + 260000, + 260000, + 260000, + 260000, + 260000, + 260000, + 260000, + 260000, + 260100, + 260100, + 260100, + 260100, + 260100, + 260100, + 260100, + 260200, + 260200, + 260200, + 260200, + 260200, + 260200, + 260200, + 260200, + 260200, + 260200, + 260300, + 260300, + 260300, + 260300, + 260300, + 260300, + 260300, + 260400, + 260400, + 260400, + 260400, + 260400, + 260400, + 260400, + 260400, + 260500, + 260500, + 260600, + 260600, + 260600, + 260600, + 260600, + 260600, + 260600, + 260600, + 260600, + 260600, + 260700, + 260700, + 260700, + 260700, + 260800, + 260800, + 260800, + 260800, + 260800, + 260800, + 260800, + 260800, + 260900, + 260900, + 260900, + 260900, + 260900, + 260900, + 261000, + 261000, + 261000, + 261000, + 261000, + 261000, + 261000, + 261100, + 261100, + 261100, + 261100, + 261100, + 261100, + 261100, + 261100, + 261100, + 261100, + 261100, + 261200, + 261200, + 261200, + 261200, + 261200, + 261200, + 261200, + 261200, + 261300, + 261300, + 261300, + 261300, + 261300, + 261300, + 261300, + 261300, + 261300, + 261300, + 261300, + 261300, + 261400, + 261400, + 261400, + 261400, + 261400, + 261400, + 261400, + 261400, + 261500, + 261500, + 261500, + 261500, + 261500, + 261500, + 261600, + 261600, + 261600, + 261600, + 261600, + 261600, + 261600, + 261600, + 261600, + 261600, + 261700, + 261700, + 261700, + 261700, + 261700, + 261700, + 261700, + 261700, + 261800, + 261800, + 261800, + 261800, + 261800, + 261800, + 261800, + 261900, + 261900, + 261900, + 261900, + 261900, + 261900, + 261900, + 261900, + 262000, + 262000, + 262000, + 262000, + 262000, + 262000, + 262000, + 262000, + 262100, + 262100, + 262100, + 262100, + 262100, + 262100, + 262200, + 262200, + 262200, + 262200, + 262200, + 262200, + 262300, + 262300, + 262300, + 262300, + 262300, + 262300, + 262400, + 262400, + 262400, + 262400, + 262400, + 262400, + 262400, + 262400, + 262500, + 262500, + 262500, + 262500, + 262500, + 262500, + 262500, + 262500, + 262500, + 262500, + 262600, + 262600, + 262600, + 262600, + 262600, + 262600, + 262600, + 262600, + 262700, + 262700, + 262700, + 262700, + 262700, + 262700, + 262700, + 262800, + 262800, + 262800, + 262800, + 262800, + 262800, + 262800, + 262900, + 262900, + 262900, + 263000, + 263000, + 263000, + 263000, + 263000, + 263000, + 263000, + 263000, + 263000, + 263100, + 263100, + 263100, + 263200, + 263200, + 263200, + 263300, + 263300, + 263300, + 263300, + 263300, + 263400, + 263400, + 263400, + 263400, + 263400, + 263400, + 263400, + 263400, + 263500, + 263500, + 263500, + 263500, + 263500, + 263500, + 263500, + 263500, + 263500, + 263500, + 263600, + 263600, + 263600, + 263600, + 263700, + 263700, + 263700, + 263700, + 263700, + 263700, + 263700, + 263700, + 263700, + 263800, + 263800, + 263800, + 263800, + 263800, + 263900, + 263900, + 263900, + 264000, + 264000, + 264000, + 264000, + 264000, + 264000, + 264000, + 264000, + 264000, + 264000, + 264000, + 264100, + 264100, + 264100, + 264100, + 264100, + 264100, + 264200, + 264200, + 264200, + 264200, + 264200, + 264200, + 264200, + 264200, + 264300, + 264300, + 264300, + 264300, + 264300, + 264300, + 264300, + 264300, + 264400, + 264400, + 264400, + 264400, + 264400, + 264400, + 264500, + 264500, + 264500, + 264500, + 264500, + 264600, + 264600, + 264600, + 264600, + 264600, + 264600, + 264600, + 264700, + 264700, + 264700, + 264700, + 264700, + 264700, + 264700, + 264800, + 264800, + 264800, + 264800, + 264800, + 264800, + 264800, + 264900, + 264900, + 264900, + 264900, + 264900, + 264900, + 265000, + 265000, + 265000, + 265000, + 265000, + 265000, + 265000, + 265000, + 265000, + 265000, + 265000, + 265000, + 265100, + 265100, + 265100, + 265100, + 265100, + 265100, + 265100, + 265200, + 265200, + 265200, + 265200, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265300, + 265400, + 265400, + 265400, + 265400, + 265400, + 265400, + 265400, + 265500, + 265500, + 265500, + 265500, + 265500, + 265500, + 265500, + 265600, + 265600, + 265600, + 265700, + 265700, + 265700, + 265700, + 265700, + 265700, + 265700, + 265700, + 265800, + 265800, + 265800, + 265800, + 265800, + 265800, + 265800, + 265800, + 265800, + 265800, + 265800, + 265800, + 265800, + 265800, + 265900, + 265900, + 265900, + 265900, + 265900, + 265900, + 265900, + 266000, + 266000, + 266000, + 266000, + 266000, + 266000, + 266100, + 266100, + 266100, + 266100, + 266100, + 266100, + 266100, + 266100, + 266100, + 266100, + 266200, + 266200, + 266200, + 266200, + 266200, + 266200, + 266200, + 266200, + 266200, + 266200, + 266200, + 266200, + 266200, + 266200, + 266200, + 266300, + 266300, + 266300, + 266300, + 266300, + 266300, + 266300, + 266300, + 266300, + 266300, + 266300, + 266300, + 266300, + 266300, + 266400, + 266400, + 266400, + 266400, + 266500, + 266500, + 266500, + 266500, + 266500, + 266500, + 266500, + 266500, + 266500, + 266500, + 266500, + 266500, + 266600, + 266600, + 266600, + 266600, + 266600, + 266600, + 266600, + 266600, + 266600, + 266700, + 266700, + 266700, + 266700, + 266700, + 266700, + 266800, + 266800, + 266800, + 266800, + 266800, + 266800, + 266800, + 266900, + 266900, + 266900, + 266900, + 266900, + 266900, + 266900, + 267000, + 267000, + 267000, + 267000, + 267000, + 267000, + 267000, + 267000, + 267000, + 267000, + 267000, + 267100, + 267100, + 267100, + 267100, + 267100, + 267100, + 267100, + 267100, + 267200, + 267200, + 267200, + 267200, + 267200, + 267200, + 267300, + 267300, + 267300, + 267300, + 267300, + 267300, + 267300, + 267300, + 267300, + 267400, + 267400, + 267400, + 267400, + 267400, + 267400, + 267500, + 267500, + 267500, + 267500, + 267500, + 267500, + 267500, + 267500, + 267500, + 267500, + 267500, + 267600, + 267600, + 267600, + 267600, + 267600, + 267600, + 267700, + 267700, + 267700, + 267700, + 267700, + 267700, + 267700, + 267800, + 267800, + 267800, + 267800, + 267800, + 267900, + 267900, + 267900, + 267900, + 267900, + 267900, + 267900, + 267900, + 267900, + 268000, + 268000, + 268000, + 268000, + 268000, + 268000, + 268000, + 268000, + 268000, + 268000, + 268100, + 268100, + 268100, + 268100, + 268200, + 268200, + 268200, + 268200, + 268200, + 268300, + 268300, + 268300, + 268300, + 268300, + 268300, + 268300, + 268300, + 268300, + 268300, + 268400, + 268400, + 268400, + 268400, + 268400, + 268500, + 268500, + 268500, + 268500, + 268500, + 268500, + 268500, + 268600, + 268600, + 268600, + 268600, + 268600, + 268600, + 268600, + 268600, + 268600, + 268600, + 268600, + 268700, + 268700, + 268700, + 268800, + 268800, + 268800, + 268800, + 268800, + 268800, + 268800, + 268800, + 268900, + 268900, + 268900, + 268900, + 269000, + 269000, + 269000, + 269000, + 269000, + 269000, + 269000, + 269100, + 269100, + 269100, + 269100, + 269200, + 269200, + 269200, + 269200, + 269200, + 269300, + 269300, + 269300, + 269300, + 269300, + 269400, + 269400, + 269400, + 269400, + 269400, + 269400, + 269400, + 269500, + 269500, + 269500, + 269500, + 269500, + 269600, + 269600, + 269600, + 269700, + 269700, + 269700, + 269800, + 269800, + 269800, + 269800, + 269900, + 269900, + 269900, + 269900, + 269900, + 270000, + 270000, + 270000, + 270000, + 270000, + 270000, + 270000, + 270000, + 270100, + 270100, + 270100, + 270100, + 270100, + 270100, + 270300, + 270300, + 270300, + 270300, + 270300, + 270300, + 270300, + 270300, + 270400, + 270400, + 270400, + 270400, + 270500, + 270500, + 270500, + 270500, + 270500, + 270500, + 270600, + 270700, + 270700, + 270700, + 270700, + 270700, + 270800, + 270800, + 270800, + 270900, + 270900, + 271000, + 271000, + 271000, + 271000, + 271100, + 271100, + 271200, + 271200, + 271200, + 271200, + 271200, + 271200, + 271300, + 271300, + 271300, + 271300, + 271300, + 271300, + 271400, + 271400, + 271400, + 271400, + 271500, + 271500, + 271500, + 271600, + 271600, + 271600, + 271600, + 271700, + 271700, + 271700, + 271800, + 271800, + 271800, + 271800, + 271900, + 271900, + 271900, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272000, + 272100, + 272100, + 272100, + 272100, + 272200, + 272200, + 272200, + 272200, + 272200, + 272300, + 272300, + 272300, + 272300, + 272400, + 272400, + 272400, + 272500, + 272500, + 272500, + 272500, + 272600, + 272600, + 272600, + 272600, + 272700, + 272700, + 272800, + 272800, + 272800, + 272800, + 272800, + 272800, + 272900, + 272900, + 272900, + 272900, + 272900, + 273000, + 273000, + 273000, + 273000, + 273000, + 273000, + 273000, + 273100, + 273100, + 273200, + 273200, + 273200, + 273300, + 273300, + 273300, + 273300, + 273300, + 273400, + 273400, + 273400, + 273500, + 273500, + 273500, + 273600, + 273600, + 273600, + 273600, + 273700, + 273700, + 273700, + 273700, + 273700, + 273800, + 273800, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 273900, + 274000, + 274000, + 274100, + 274100, + 274200, + 274200, + 274200, + 274200, + 274200, + 274300, + 274300, + 274300, + 274300, + 274400, + 274400, + 274400, + 274400, + 274400, + 274400, + 274500, + 274500, + 274500, + 274500, + 274500, + 274500, + 274700, + 274700, + 274800, + 274800, + 274800, + 274800, + 274800, + 274800, + 274900, + 274900, + 274900, + 275000, + 275000, + 275100, + 275100, + 275100, + 275200, + 275300, + 275300, + 275300, + 275300, + 275300, + 275300, + 275300, + 275400, + 275400, + 275400, + 275400, + 275400, + 275500, + 275500, + 275500, + 275500, + 275500, + 275600, + 275600, + 275600, + 275700, + 275800, + 275900, + 275900, + 275900, + 276000, + 276000, + 276000, + 276100, + 276200, + 276200, + 276200, + 276200, + 276200, + 276200, + 276300, + 276300, + 276400, + 276600, + 276600, + 276600, + 276600, + 276700, + 276700, + 276700, + 276800, + 276800, + 276800, + 276800, + 276800, + 276800, + 276900, + 276900, + 276900, + 276900, + 276900, + 276900, + 276900, + 276900, + 277000, + 277000, + 277000, + 277100, + 277100, + 277100, + 277100, + 277100, + 277200, + 277200, + 277200, + 277300, + 277300, + 277300, + 277300, + 277400, + 277400, + 277400, + 277500, + 277600, + 277600, + 277600, + 277600, + 277700, + 277800, + 277900, + 278000, + 278000, + 278100, + 278100, + 278100, + 278200, + 278200, + 278200, + 278300, + 278300, + 278300, + 278400, + 278400, + 278500, + 278500, + 278500, + 278600, + 278600, + 278700, + 278800, + 278800, + 278900, + 278900, + 278900, + 278900, + 279000, + 279000, + 279000, + 279100, + 279100, + 279100, + 279100, + 279100, + 279100, + 279100, + 279200, + 279200, + 279300, + 279300, + 279300, + 279400, + 279400, + 279400, + 279500, + 279500, + 279500, + 279500, + 279500, + 279600, + 279600, + 279600, + 279600, + 279600, + 279700, + 279700, + 279800, + 279800, + 279800, + 279800, + 279800, + 279900, + 279900, + 280100, + 280200, + 280200, + 280200, + 280200, + 280200, + 280400, + 280400, + 280400, + 280500, + 280500, + 280600, + 280600, + 280700, + 280700, + 280800, + 280800, + 280800, + 280900, + 280900, + 280900, + 280900, + 281000, + 281000, + 281000, + 281000, + 281100, + 281100, + 281100, + 281100, + 281100, + 281200, + 281200, + 281200, + 281300, + 281300, + 281300, + 281400, + 281500, + 281500, + 281500, + 281600, + 281600, + 281600, + 281700, + 281700, + 281700, + 281700, + 281800, + 281800, + 281800, + 281800, + 281900, + 281900, + 282000, + 282200, + 282300, + 282300, + 282300, + 282300, + 282300, + 282400, + 282400, + 282400, + 282400, + 282400, + 282400, + 282500, + 282700, + 282700, + 282800, + 282900, + 283000, + 283000, + 283000, + 283100, + 283100, + 283100, + 283100, + 283100, + 283200, + 283200, + 283200, + 283300, + 283300, + 283300, + 283400, + 283400, + 283400, + 283400, + 283500, + 283500, + 283600, + 283700, + 283700, + 283800, + 283900, + 283900, + 284000, + 284000, + 284000, + 284300, + 284300, + 284300, + 284300, + 284400, + 284500, + 284600, + 284600, + 284700, + 284700, + 284800, + 284800, + 284900, + 284900, + 285000, + 285000, + 285000, + 285200, + 285200, + 285500, + 285500, + 285700, + 285800, + 285800, + 285900, + 286000, + 286000, + 286100, + 286200, + 286200, + 286300, + 286300, + 286400, + 286400, + 286500, + 286700, + 286900, + 286900, + 286900, + 287200, + 287200, + 287200, + 287200, + 287300, + 287400, + 287500, + 287500, + 287500, + 287600, + 287600, + 287600, + 287700, + 287700, + 287800, + 287800, + 287800, + 287900, + 287900, + 287900, + 287900, + 287900, + 287900, + 288000, + 288100, + 288200, + 288300, + 288400, + 288400, + 288400, + 288500, + 288500, + 288500, + 288500, + 288600, + 288700, + 288800, + 289000, + 289000, + 289000, + 289200, + 289200, + 289300, + 289300, + 289300, + 289400, + 289400, + 289500, + 289700, + 289800, + 290000, + 290000, + 290100, + 290100, + 290100, + 290200, + 290200, + 290200, + 290400, + 290500, + 290500, + 290500, + 290600, + 290700, + 290900, + 290900, + 290900, + 291000, + 291100, + 291100, + 291100, + 291200, + 291400, + 291400, + 291600, + 291700, + 291800, + 291900, + 292000, + 292100, + 292200, + 292200, + 292300, + 292400, + 292400, + 292500, + 292600, + 292600, + 292600, + 292700, + 292700, + 292800, + 292900, + 293000, + 293200, + 293200, + 293500, + 293500, + 293500, + 293600, + 293600, + 293700, + 293900, + 293900, + 294200, + 294300, + 294300, + 294400, + 294500, + 294600, + 294800, + 294900, + 295100, + 295100, + 295100, + 295300, + 295500, + 295600, + 295600, + 296100, + 296100, + 296100, + 296300, + 296400, + 296400, + 296500, + 296500, + 296600, + 296700, + 296800, + 296800, + 296800, + 297000, + 297300, + 297600, + 297900, + 298000, + 298100, + 298200, + 298200, + 298200, + 298300, + 298800, + 298900, + 298900, + 299400, + 299600, + 299600, + 299600, + 299800, + 300300, + 300500, + 300700, + 300800, + 300800, + 300800, + 301700, + 301900, + 301900, + 302000, + 302300, + 302500, + 302600, + 303200, + 303900, + 303900, + 304400, + 304800, + 305200, + 305200, + 305400, + 305500, + 305700, + 305800, + 305800, + 305800, + 305900, + 306100, + 306300, + 306400, + 306500, + 306600, + 307300, + 307600, + 307700, + 307800, + 308200, + 308600, + 308800, + 309000, + 309000, + 309200, + 309300, + 309300, + 309300, + 309300, + 309400, + 309700, + 309700, + 309800, + 310100, + 310600, + 310900, + 311000, + 311300, + 311500, + 311500, + 311800, + 312100, + 312200, + 312500, + 312800, + 312800, + 313000, + 313400, + 313400, + 314100, + 314600, + 314700, + 314900, + 315200, + 315200, + 316400, + 317200, + 317900, + 318300, + 318300, + 318300, + 318500, + 319100, + 319300, + 319400, + 319700, + 320000, + 320500, + 320500, + 320700, + 321500, + 321600, + 322000, + 322200, + 322300, + 322600, + 322700, + 322800, + 323100, + 323300, + 323300, + 323700, + 324400, + 325000, + 325300, + 325400, + 325700, + 326300, + 326400, + 326800, + 327000, + 327200, + 327300, + 327300, + 327600, + 327800, + 327900, + 327900, + 328100, + 328300, + 329000, + 329600, + 330100, + 330100, + 330900, + 331100, + 333200, + 333500, + 333700, + 333900, + 334600, + 334700, + 335100, + 335400, + 335500, + 335600, + 336300, + 337000, + 337000, + 337100, + 337200, + 338100, + 338600, + 340100, + 340500, + 340600, + 342000, + 342700, + 342800, + 343200, + 343500, + 343700, + 344300, + 344900, + 345200, + 345600, + 347800, + 348100, + 348100, + 348300, + 348600, + 349800, + 350300, + 350300, + 350700, + 350700, + 351400, + 351700, + 353900, + 355500, + 355600, + 355900, + 356500, + 356500, + 358000, + 359800, + 360300, + 361100, + 362300, + 364600, + 364900, + 365600, + 368500, + 371000, + 371200, + 371900, + 372300, + 379300, + 380700, + 381300, + 382000, + 385800, + 386700, + 389800, + 393100, + 396200, + 398100, + 404600, + 410000, + 421700, + 425300, + 428000, + 456200, + 459800, + 460000, + 463600, + 473300, + 487700, + 535700, + 538700, + 539400, + 539500, + 539600, + 542300, + 546400, + 555000, + 557900, + 558000, + 571200, + 575800, + 582000, + 583400, + 583500, + 585000, + 586300, + 586600, + 588500, + 591300, + 593000, + 593900, + 594800, + 595100, + 595600, + 597800, + 598000, + 598000, + 598800, + 599700, + 601600, + 602200, + 603000, + 609000, + 611500, + 616000, + 617100, + 638700, + 638800, + 639700, + 640100, + 641100, + 643500, + 646800, + 660000, + 663600, + 667300, + 674700, + 681400, + 697800, + 700200, + 713000, + 716000, + 725400, + 733800, + 740600, + 754800 + ], + "min": 251400, + "max": 754800, + "p25": 257700, + "p50": 265200, + "p75": 277300, + "p99": 601600, + "p999": 725400, + "avg": 279530.68046159967, + "ticks": 2513, + "heap": { + "_": 2467, + "total": 3064886152, + "min": 7944, + "max": 2939240, + "avg": 1242353.5273611674 + } + }, + "args": {}, + "name": "handlebars conditional-heavy" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta conditional-heavy", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 17118.0908203125, + 17153.1005859375, + 17183.4228515625, + 17195.8740234375, + 17200.48828125, + 17200.6591796875, + 17203.02734375, + 17209.4482421875, + 17212.20703125, + 17226.0986328125, + 17253.1494140625, + 17297.8759765625 + ], + "min": 17118.0908203125, + "max": 17297.8759765625, + "p25": 17183.4228515625, + "p50": 17200.6591796875, + "p75": 17212.20703125, + "p99": 17253.1494140625, + "p999": 17253.1494140625, + "avg": 17204.453531901043, + "ticks": 49152, + "heap": { + "_": 8, + "total": 43640.68359375, + "min": 5443.275390625, + "max": 5470.4921875, + "avg": 5455.08544921875 + } + }, + "args": {}, + "name": "eta conditional-heavy" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars fragment-heavy", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 85700, + 85700, + 85800, + 85800, + 85800, + 85900, + 85900, + 85900, + 85900, + 85900, + 85900, + 85900, + 85900, + 85900, + 85900, + 85900, + 86000, + 86000, + 86000, + 86000, + 86000, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86100, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86200, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86300, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86400, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86500, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86600, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86700, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86800, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 86900, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87000, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87100, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87200, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87300, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87400, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87500, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87600, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87700, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87800, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 87900, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88000, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88100, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88200, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88300, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88400, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88500, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88600, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88700, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88800, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 88900, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89000, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89100, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89200, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89300, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89400, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89500, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89600, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89700, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89800, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 89900, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90000, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90100, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90200, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90300, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90400, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90500, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90600, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90700, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90800, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 90900, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91000, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91100, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91200, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91300, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91400, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91500, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91600, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91700, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91800, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 91900, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92000, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96500, + 96500, + 96500, + 96500, + 96500, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99100, + 99100, + 99100, + 99100, + 99100, + 99100, + 99100, + 99100, + 99100, + 99100, + 99100, + 99100, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99500, + 99500, + 99500, + 99500, + 99500, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99800, + 99800, + 99800, + 99800, + 99800, + 99800, + 99800, + 99800, + 99800, + 99900, + 99900, + 99900, + 99900, + 99900, + 99900, + 99900, + 100000, + 100000, + 100000, + 100000, + 100000, + 100000, + 100000, + 100000, + 100100, + 100100, + 100100, + 100100, + 100100, + 100100, + 100100, + 100100, + 100200, + 100200, + 100200, + 100200, + 100200, + 100200, + 100200, + 100200, + 100200, + 100300, + 100300, + 100300, + 100300, + 100300, + 100400, + 100400, + 100400, + 100400, + 100400, + 100400, + 100400, + 100400, + 100400, + 100400, + 100500, + 100500, + 100500, + 100500, + 100500, + 100500, + 100600, + 100600, + 100600, + 100600, + 100700, + 100700, + 100700, + 100700, + 100700, + 100700, + 100700, + 100800, + 100800, + 100800, + 100800, + 100800, + 100800, + 100900, + 100900, + 100900, + 100900, + 101000, + 101000, + 101000, + 101000, + 101000, + 101000, + 101000, + 101100, + 101100, + 101100, + 101100, + 101200, + 101200, + 101200, + 101200, + 101200, + 101200, + 101200, + 101200, + 101300, + 101300, + 101300, + 101300, + 101300, + 101300, + 101300, + 101400, + 101400, + 101400, + 101500, + 101500, + 101500, + 101500, + 101500, + 101500, + 101500, + 101500, + 101500, + 101600, + 101600, + 101600, + 101600, + 101600, + 101600, + 101600, + 101600, + 101600, + 101600, + 101700, + 101700, + 101700, + 101800, + 101800, + 101800, + 101800, + 101800, + 101800, + 101800, + 101800, + 101900, + 101900, + 101900, + 102000, + 102000, + 102000, + 102000, + 102000, + 102000, + 102000, + 102000, + 102000, + 102100, + 102100, + 102100, + 102100, + 102100, + 102200, + 102200, + 102200, + 102200, + 102200, + 102200, + 102200, + 102200, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102400, + 102400, + 102500, + 102500, + 102500, + 102600, + 102600, + 102600, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102800, + 102800, + 102800, + 102800, + 102800, + 102900, + 102900, + 102900, + 102900, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103100, + 103100, + 103100, + 103100, + 103100, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103400, + 103400, + 103400, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104100, + 104100, + 104100, + 104100, + 104100, + 104200, + 104200, + 104200, + 104200, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104500, + 104500, + 104500, + 104500, + 104500, + 104600, + 104600, + 104600, + 104600, + 104700, + 104700, + 104700, + 104700, + 104700, + 104700, + 104800, + 104800, + 104800, + 104800, + 104900, + 104900, + 104900, + 105000, + 105000, + 105100, + 105100, + 105100, + 105100, + 105100, + 105200, + 105200, + 105300, + 105300, + 105300, + 105400, + 105400, + 105400, + 105400, + 105400, + 105400, + 105500, + 105500, + 105500, + 105500, + 105600, + 105600, + 105600, + 105600, + 105600, + 105600, + 105600, + 105600, + 105700, + 105700, + 105700, + 105800, + 105800, + 105800, + 105800, + 105800, + 105800, + 105900, + 105900, + 105900, + 105900, + 105900, + 106000, + 106100, + 106100, + 106100, + 106100, + 106100, + 106100, + 106100, + 106100, + 106200, + 106200, + 106200, + 106200, + 106300, + 106300, + 106300, + 106400, + 106500, + 106500, + 106500, + 106500, + 106600, + 106600, + 106600, + 106700, + 106700, + 106700, + 106700, + 106800, + 106800, + 106800, + 106900, + 106900, + 106900, + 106900, + 106900, + 106900, + 107000, + 107000, + 107100, + 107100, + 107200, + 107300, + 107300, + 107300, + 107400, + 107500, + 107500, + 107600, + 107600, + 107600, + 107600, + 107600, + 107600, + 107700, + 107700, + 107700, + 107800, + 107800, + 107900, + 107900, + 108000, + 108100, + 108100, + 108100, + 108100, + 108100, + 108300, + 108300, + 108300, + 108300, + 108300, + 108400, + 108400, + 108400, + 108400, + 108500, + 108500, + 108600, + 108600, + 108700, + 108700, + 108800, + 108900, + 109100, + 109200, + 109300, + 109300, + 109400, + 109400, + 109500, + 109500, + 109500, + 109700, + 109800, + 109800, + 109900, + 110000, + 110000, + 110100, + 110200, + 110200, + 110300, + 110400, + 110400, + 110400, + 110500, + 110500, + 110600, + 110800, + 110800, + 111000, + 111000, + 111000, + 111000, + 111200, + 111200, + 111200, + 111200, + 111200, + 111500, + 111600, + 111600, + 111700, + 111700, + 111800, + 111800, + 111900, + 111900, + 112000, + 112200, + 112400, + 112400, + 112900, + 113000, + 113000, + 113000, + 113300, + 113500, + 113700, + 113700, + 113800, + 113800, + 113900, + 113900, + 114000, + 114000, + 114000, + 114100, + 114200, + 114300, + 114400, + 114400, + 114600, + 114700, + 114800, + 114800, + 115000, + 115100, + 115100, + 115400, + 115600, + 115600, + 115600, + 115700, + 115700, + 115800, + 115900, + 115900, + 115900, + 116000, + 116100, + 116200, + 116200, + 116300, + 116700, + 116700, + 116700, + 116800, + 116800, + 116900, + 116900, + 117000, + 117300, + 117300, + 117500, + 117500, + 117500, + 117600, + 117600, + 117600, + 117900, + 117900, + 118000, + 118100, + 118200, + 118400, + 118600, + 118600, + 118600, + 118800, + 119000, + 119100, + 119100, + 119100, + 119200, + 119300, + 119300, + 119400, + 119500, + 119700, + 119700, + 119700, + 119700, + 119800, + 120000, + 120000, + 120100, + 120100, + 120100, + 120100, + 120100, + 120200, + 120500, + 120600, + 120600, + 120600, + 120700, + 120800, + 121000, + 121000, + 121100, + 121300, + 121400, + 121400, + 121400, + 121500, + 121800, + 122100, + 122100, + 122300, + 122300, + 122500, + 122600, + 122600, + 122800, + 122900, + 122900, + 123000, + 123100, + 123100, + 123100, + 123100, + 123200, + 123400, + 123600, + 123800, + 123800, + 123900, + 124000, + 124000, + 124000, + 124500, + 124500, + 124600, + 124700, + 124800, + 124900, + 125100, + 125300, + 125400, + 125700, + 125800, + 126000, + 126100, + 126100, + 126200, + 126200, + 126400, + 126500, + 126700, + 126700, + 127100, + 127100, + 127300, + 127400, + 127500, + 127700, + 127900, + 127900, + 127900, + 128000, + 128400, + 128400, + 128600, + 128900, + 129100, + 129300, + 129300, + 129800, + 129800, + 129800, + 130100, + 130200, + 130400, + 130500, + 130700, + 131200, + 131300, + 132200, + 132200, + 132200, + 132600, + 132700, + 132800, + 133000, + 133600, + 134100, + 134100, + 134500, + 134700, + 134800, + 134900, + 134900, + 135000, + 135200, + 135300, + 135700, + 136500, + 136700, + 136800, + 137200, + 137400, + 137600, + 137700, + 137900, + 138100, + 138100, + 138300, + 138300, + 138400, + 138800, + 138900, + 138900, + 139200, + 139500, + 139800, + 139900, + 139900, + 140000, + 140100, + 140500, + 140700, + 140700, + 141000, + 141500, + 141800, + 141900, + 142100, + 142400, + 142400, + 142500, + 142600, + 142900, + 143500, + 143600, + 143600, + 144500, + 145000, + 145100, + 145100, + 145300, + 146600, + 147000, + 147100, + 147400, + 151000, + 151200, + 152000, + 152600, + 153400, + 153400, + 153600, + 153800, + 154400, + 154700, + 155400, + 155600, + 155900, + 157100, + 158200, + 158600, + 158600, + 158900, + 159800, + 160300, + 160700, + 160800, + 162100, + 162200, + 162500, + 162600, + 163400, + 163800, + 163900, + 164500, + 164700, + 164800, + 169600, + 174800, + 178800, + 179000, + 184400, + 195400, + 201900, + 203400, + 206100, + 206200, + 209400, + 213000, + 219100, + 221700, + 223900, + 248800, + 253300, + 256400, + 262900, + 264000, + 264700, + 272100, + 286900, + 291800, + 302000, + 309000, + 362600, + 551500, + 600900, + 621800, + 641000, + 663400, + 678800, + 681400, + 685400, + 687400, + 688400, + 690700, + 698300, + 701200, + 705700, + 707300, + 708300, + 708400, + 708600, + 709600, + 711300, + 712300, + 724700, + 732600, + 736100, + 752500, + 760500, + 762300, + 764100, + 767400, + 776300, + 785700, + 802100, + 831500, + 832700, + 839800 + ], + "min": 85700, + "max": 839800, + "p25": 87700, + "p50": 89200, + "p75": 93100, + "p99": 160300, + "p999": 762300, + "avg": 96003.98357289527, + "ticks": 7305, + "heap": { + "_": 7175, + "total": 2350736808, + "min": 1344, + "max": 1065216, + "avg": 327628.82341463416 + } + }, + "args": {}, + "name": "handlebars fragment-heavy" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta fragment-heavy", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 11975.78125, + 11978.9794921875, + 11984.27734375, + 11984.423828125, + 11988.6962890625, + 11989.4775390625, + 11993.4326171875, + 12014.6240234375, + 12023.388671875, + 12034.5947265625, + 12054.443359375 + ], + "min": 11975.78125, + "max": 12054.443359375, + "p25": 11984.27734375, + "p50": 11989.4775390625, + "p75": 12014.6240234375, + "p99": 12034.5947265625, + "p999": 12034.5947265625, + "avg": 12002.01083096591, + "ticks": 45056, + "heap": { + "_": 12, + "total": 42223.376953125, + "min": 3384.353515625, + "max": 4938.056640625, + "avg": 3518.61474609375 + } + }, + "args": {}, + "name": "eta fragment-heavy" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars fortunes-encoded", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 51300, + 51300, + 51300, + 51300, + 51400, + 51400, + 51400, + 51400, + 51500, + 51500, + 51500, + 51500, + 51500, + 51500, + 51500, + 51500, + 51600, + 51600, + 51600, + 51600, + 51600, + 51600, + 51600, + 51600, + 51600, + 51600, + 51600, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51700, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51800, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 51900, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52000, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52100, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52200, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52300, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52400, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52500, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52600, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52700, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52800, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 52900, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53000, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53100, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53200, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53300, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53400, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53500, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53600, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53700, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53800, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 53900, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54000, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54100, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54200, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54300, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54400, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54500, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54600, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54700, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54800, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 54900, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55000, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55100, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55200, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55300, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55400, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55500, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55600, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55700, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55800, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 55900, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56000, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56100, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56200, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56300, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56400, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56500, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56600, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56700, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56800, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 56900, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57000, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57100, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57200, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57300, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57400, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57500, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57600, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57700, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57800, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 57900, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58000, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58100, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58200, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58300, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58400, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58500, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58600, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58700, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58800, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 58900, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59000, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59100, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59200, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59300, + 59400, + 59400, + 59400, + 59400, + 59400, + 59400, + 59400, + 59400, + 59400, + 59400, + 59400, + 59400, + 59400, + 59400, + 59400, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59500, + 59600, + 59600, + 59600, + 59600, + 59600, + 59600, + 59600, + 59600, + 59600, + 59600, + 59600, + 59600, + 59600, + 59600, + 59600, + 59700, + 59700, + 59700, + 59700, + 59700, + 59700, + 59700, + 59700, + 59700, + 59700, + 59700, + 59800, + 59800, + 59800, + 59800, + 59800, + 59800, + 59800, + 59800, + 59800, + 59800, + 59800, + 59800, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 59900, + 60000, + 60000, + 60000, + 60000, + 60000, + 60000, + 60000, + 60000, + 60000, + 60000, + 60000, + 60100, + 60100, + 60100, + 60100, + 60100, + 60100, + 60100, + 60100, + 60100, + 60100, + 60100, + 60100, + 60200, + 60200, + 60200, + 60200, + 60200, + 60200, + 60200, + 60200, + 60200, + 60300, + 60300, + 60300, + 60300, + 60300, + 60300, + 60300, + 60300, + 60300, + 60300, + 60300, + 60400, + 60400, + 60400, + 60400, + 60400, + 60400, + 60500, + 60500, + 60500, + 60500, + 60500, + 60500, + 60500, + 60500, + 60500, + 60500, + 60600, + 60600, + 60600, + 60600, + 60600, + 60600, + 60600, + 60600, + 60600, + 60600, + 60600, + 60600, + 60700, + 60700, + 60700, + 60700, + 60700, + 60700, + 60700, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60800, + 60900, + 60900, + 60900, + 60900, + 60900, + 60900, + 60900, + 61000, + 61000, + 61000, + 61000, + 61000, + 61000, + 61000, + 61100, + 61100, + 61100, + 61100, + 61200, + 61200, + 61200, + 61200, + 61200, + 61200, + 61200, + 61200, + 61200, + 61300, + 61300, + 61300, + 61300, + 61300, + 61300, + 61300, + 61300, + 61300, + 61300, + 61400, + 61400, + 61400, + 61400, + 61400, + 61400, + 61400, + 61400, + 61400, + 61400, + 61400, + 61500, + 61500, + 61500, + 61500, + 61500, + 61500, + 61500, + 61500, + 61500, + 61600, + 61600, + 61600, + 61600, + 61600, + 61600, + 61600, + 61600, + 61600, + 61600, + 61700, + 61700, + 61700, + 61700, + 61700, + 61700, + 61700, + 61700, + 61700, + 61700, + 61700, + 61700, + 61800, + 61800, + 61800, + 61800, + 61800, + 61800, + 61800, + 61800, + 61800, + 61900, + 61900, + 61900, + 61900, + 61900, + 61900, + 61900, + 61900, + 62000, + 62000, + 62000, + 62000, + 62000, + 62000, + 62000, + 62100, + 62100, + 62100, + 62100, + 62100, + 62100, + 62100, + 62100, + 62100, + 62100, + 62200, + 62200, + 62200, + 62200, + 62200, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62300, + 62400, + 62400, + 62400, + 62400, + 62400, + 62400, + 62400, + 62400, + 62400, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62500, + 62600, + 62600, + 62600, + 62600, + 62600, + 62600, + 62600, + 62600, + 62600, + 62600, + 62600, + 62600, + 62600, + 62600, + 62600, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62700, + 62800, + 62800, + 62800, + 62800, + 62800, + 62800, + 62800, + 62800, + 62800, + 62800, + 62800, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 62900, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63000, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63100, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63200, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63300, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63400, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63500, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63600, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63700, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63800, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 63900, + 64000, + 64000, + 64000, + 64000, + 64000, + 64000, + 64000, + 64000, + 64000, + 64000, + 64000, + 64000, + 64000, + 64000, + 64000, + 64100, + 64100, + 64100, + 64100, + 64100, + 64100, + 64100, + 64100, + 64100, + 64100, + 64100, + 64100, + 64100, + 64100, + 64100, + 64200, + 64200, + 64200, + 64200, + 64200, + 64200, + 64200, + 64200, + 64200, + 64200, + 64200, + 64200, + 64200, + 64200, + 64200, + 64300, + 64300, + 64300, + 64300, + 64300, + 64300, + 64300, + 64300, + 64300, + 64300, + 64300, + 64400, + 64400, + 64400, + 64400, + 64400, + 64400, + 64400, + 64400, + 64400, + 64500, + 64500, + 64500, + 64500, + 64500, + 64500, + 64500, + 64500, + 64500, + 64500, + 64500, + 64500, + 64500, + 64500, + 64500, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64600, + 64700, + 64700, + 64700, + 64700, + 64700, + 64700, + 64700, + 64700, + 64700, + 64700, + 64700, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64800, + 64900, + 64900, + 64900, + 64900, + 64900, + 64900, + 64900, + 64900, + 64900, + 64900, + 64900, + 64900, + 65000, + 65000, + 65000, + 65000, + 65000, + 65000, + 65000, + 65000, + 65000, + 65000, + 65100, + 65100, + 65100, + 65100, + 65100, + 65100, + 65100, + 65100, + 65200, + 65200, + 65200, + 65200, + 65200, + 65200, + 65200, + 65200, + 65200, + 65200, + 65300, + 65300, + 65300, + 65300, + 65400, + 65400, + 65400, + 65400, + 65400, + 65400, + 65400, + 65400, + 65500, + 65500, + 65500, + 65500, + 65500, + 65500, + 65500, + 65500, + 65500, + 65600, + 65600, + 65600, + 65600, + 65700, + 65700, + 65700, + 65700, + 65800, + 65800, + 65800, + 65800, + 65800, + 65800, + 65800, + 65800, + 65800, + 65900, + 65900, + 65900, + 65900, + 65900, + 65900, + 65900, + 65900, + 66000, + 66000, + 66000, + 66000, + 66000, + 66000, + 66000, + 66000, + 66000, + 66000, + 66000, + 66000, + 66100, + 66100, + 66100, + 66100, + 66100, + 66100, + 66100, + 66100, + 66100, + 66100, + 66100, + 66200, + 66200, + 66200, + 66200, + 66200, + 66200, + 66300, + 66300, + 66300, + 66300, + 66300, + 66300, + 66300, + 66400, + 66400, + 66400, + 66400, + 66400, + 66400, + 66400, + 66400, + 66400, + 66400, + 66400, + 66500, + 66500, + 66500, + 66500, + 66500, + 66500, + 66500, + 66600, + 66600, + 66600, + 66600, + 66600, + 66700, + 66700, + 66700, + 66700, + 66700, + 66700, + 66700, + 66700, + 66700, + 66800, + 66800, + 66800, + 66800, + 66800, + 66800, + 66800, + 66800, + 66800, + 66800, + 66900, + 66900, + 66900, + 67000, + 67000, + 67100, + 67100, + 67100, + 67100, + 67100, + 67200, + 67200, + 67200, + 67200, + 67200, + 67200, + 67200, + 67200, + 67300, + 67300, + 67300, + 67400, + 67400, + 67400, + 67400, + 67400, + 67400, + 67500, + 67500, + 67500, + 67500, + 67500, + 67600, + 67600, + 67600, + 67600, + 67600, + 67600, + 67700, + 67700, + 67700, + 67700, + 67700, + 67700, + 67700, + 67800, + 67800, + 67800, + 67800, + 67800, + 67800, + 67900, + 67900, + 67900, + 67900, + 67900, + 67900, + 67900, + 67900, + 67900, + 68000, + 68000, + 68000, + 68100, + 68100, + 68100, + 68100, + 68100, + 68200, + 68200, + 68200, + 68200, + 68200, + 68200, + 68300, + 68300, + 68300, + 68300, + 68300, + 68400, + 68400, + 68400, + 68400, + 68400, + 68400, + 68400, + 68400, + 68500, + 68600, + 68600, + 68600, + 68600, + 68600, + 68700, + 68700, + 68700, + 68700, + 68800, + 68800, + 68800, + 68800, + 68900, + 68900, + 68900, + 68900, + 69000, + 69000, + 69000, + 69100, + 69100, + 69100, + 69100, + 69200, + 69200, + 69200, + 69200, + 69200, + 69300, + 69300, + 69300, + 69400, + 69400, + 69400, + 69400, + 69500, + 69500, + 69500, + 69500, + 69500, + 69500, + 69500, + 69500, + 69500, + 69500, + 69500, + 69600, + 69600, + 69600, + 69600, + 69600, + 69600, + 69700, + 69700, + 69700, + 69700, + 69800, + 69800, + 69800, + 69800, + 69800, + 69900, + 69900, + 69900, + 69900, + 70000, + 70000, + 70000, + 70000, + 70000, + 70000, + 70000, + 70100, + 70200, + 70200, + 70200, + 70200, + 70300, + 70400, + 70400, + 70400, + 70400, + 70400, + 70400, + 70400, + 70500, + 70500, + 70600, + 70600, + 70600, + 70700, + 70700, + 70700, + 70700, + 70800, + 70800, + 70800, + 70800, + 70900, + 70900, + 71000, + 71100, + 71100, + 71100, + 71200, + 71200, + 71200, + 71400, + 71500, + 71500, + 71500, + 71600, + 71600, + 71600, + 71700, + 71700, + 71700, + 71700, + 71900, + 71900, + 71900, + 72000, + 72000, + 72000, + 72100, + 72100, + 72100, + 72100, + 72200, + 72200, + 72200, + 72300, + 72300, + 72300, + 72400, + 72500, + 72500, + 72500, + 72500, + 72700, + 72800, + 72800, + 72800, + 72900, + 72900, + 72900, + 73100, + 73100, + 73200, + 73200, + 73300, + 73300, + 73300, + 73300, + 73300, + 73400, + 73400, + 73400, + 73400, + 73500, + 73600, + 73600, + 73600, + 73700, + 73800, + 73800, + 73900, + 73900, + 74000, + 74000, + 74000, + 74100, + 74100, + 74100, + 74100, + 74200, + 74200, + 74300, + 74300, + 74300, + 74400, + 74400, + 74500, + 74500, + 74500, + 74800, + 74800, + 75300, + 75400, + 75500, + 75700, + 75800, + 76000, + 76000, + 76100, + 76200, + 76400, + 76400, + 76400, + 76700, + 76800, + 76900, + 76900, + 77100, + 77200, + 77200, + 77300, + 77400, + 77400, + 77400, + 77500, + 77500, + 77500, + 77700, + 77800, + 77900, + 78000, + 78100, + 78100, + 78100, + 78200, + 78300, + 78300, + 78400, + 78400, + 78400, + 78600, + 78700, + 78700, + 78800, + 78900, + 78900, + 78900, + 79100, + 79200, + 79200, + 79200, + 79300, + 79400, + 79400, + 79400, + 79500, + 79500, + 79600, + 79600, + 79600, + 79600, + 79600, + 79700, + 79700, + 79900, + 79900, + 80100, + 80100, + 80100, + 80300, + 80400, + 80400, + 80400, + 80400, + 80500, + 80500, + 80600, + 80600, + 80600, + 80700, + 80700, + 80800, + 80800, + 80800, + 80800, + 80800, + 80800, + 80900, + 80900, + 80900, + 81000, + 81000, + 81000, + 81100, + 81200, + 81400, + 81500, + 81600, + 81600, + 81600, + 81700, + 81700, + 81900, + 82000, + 82000, + 82000, + 82100, + 82100, + 82200, + 82200, + 82200, + 82400, + 82500, + 82500, + 82500, + 82800, + 82800, + 83000, + 83000, + 83000, + 83200, + 83200, + 83400, + 83400, + 83500, + 83500, + 83600, + 83600, + 83600, + 83700, + 84000, + 84100, + 84100, + 84100, + 84300, + 84300, + 84300, + 84400, + 84500, + 84500, + 84500, + 84600, + 84700, + 84800, + 84800, + 84800, + 85000, + 85200, + 85300, + 85400, + 85700, + 85700, + 85800, + 85800, + 85800, + 86000, + 86000, + 86200, + 86300, + 86300, + 86400, + 86600, + 87000, + 87000, + 87100, + 87500, + 87500, + 87600, + 87900, + 88000, + 88100, + 88300, + 88500, + 88900, + 89200, + 89600, + 89600, + 89900, + 90400, + 90500, + 90500, + 91300, + 91600, + 91700, + 92100, + 92200, + 92700, + 92700, + 92900, + 92900, + 93000, + 93100, + 93100, + 93300, + 93400, + 93600, + 93700, + 93800, + 93800, + 94000, + 94000, + 94200, + 94200, + 94400, + 94700, + 94900, + 95000, + 95000, + 95000, + 95300, + 95300, + 95500, + 95800, + 95900, + 96200, + 96200, + 96200, + 96400, + 96400, + 96600, + 97000, + 97100, + 97200, + 97300, + 97500, + 97800, + 98100, + 98900, + 99000, + 99100, + 99300, + 99500, + 99600, + 99800, + 99900, + 100000, + 100100, + 100200, + 100400, + 100600, + 100700, + 100800, + 100900, + 101400, + 101400, + 101900, + 102000, + 102100, + 103000, + 103200, + 104600, + 104800, + 105000, + 105200, + 105500, + 105600, + 105800, + 106000, + 107100, + 107400, + 107400, + 107500, + 107600, + 107800, + 107900, + 107900, + 107900, + 108000, + 108400, + 108800, + 109000, + 109000, + 109300, + 109500, + 109500, + 110000, + 110000, + 110600, + 110700, + 110800, + 110800, + 110900, + 111100, + 111200, + 111300, + 111400, + 111400, + 111900, + 112000, + 112500, + 112700, + 113100, + 114000, + 114100, + 115400, + 115900, + 116300, + 116500, + 116500, + 116600, + 117400, + 118000, + 118300, + 118300, + 118500, + 118500, + 118500, + 119000, + 119000, + 119300, + 120100, + 121000, + 121900, + 123500, + 123700, + 124500, + 125200, + 125300, + 125600, + 125700, + 125800, + 126300, + 126400, + 126800, + 127900, + 129400, + 129600, + 130000, + 130800, + 130800, + 131100, + 131300, + 131800, + 132600, + 134400, + 135800, + 137300, + 138200, + 138400, + 138600, + 140000, + 140000, + 141000, + 142900, + 145100, + 145600, + 147300, + 150100, + 150300, + 151300, + 154000, + 155500, + 164900, + 176100, + 199900, + 206600, + 224900, + 341400, + 612900, + 682200, + 685500, + 691400, + 706600, + 713100, + 716900, + 721000, + 729000, + 735200, + 744700, + 745100, + 747000, + 752700, + 762400, + 768900, + 770800, + 775400, + 776500, + 786100, + 789900, + 792000, + 793300, + 808300, + 808500, + 811900, + 831400, + 854900, + 865900, + 904300, + 923900, + 957900, + 989100, + 1034900 + ], + "min": 51300, + "max": 1034900, + "p25": 53000, + "p50": 53800, + "p75": 56200, + "p99": 109000, + "p999": 792000, + "avg": 58540.448498033635, + "ticks": 11951, + "heap": { + "_": 11757, + "total": 2298280112, + "min": 1104, + "max": 725040, + "avg": 195481.85013183634 + } + }, + "args": {}, + "name": "handlebars fortunes-encoded" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta fortunes-encoded", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 5956.982421875, + 5957.6904296875, + 5958.349609375, + 5961.4013671875, + 5962.060546875, + 5962.7197265625, + 5967.8955078125, + 5971.1669921875, + 5971.7041015625, + 5972.16796875, + 5972.998046875, + 5974.267578125, + 5974.267578125, + 5975.048828125, + 5982.51953125, + 5985.8642578125, + 5989.1845703125, + 5989.74609375, + 5991.552734375, + 5998.828125, + 5999.0234375, + 6004.98046875, + 6008.7890625, + 6009.3017578125, + 6056.494140625 + ], + "min": 5956.982421875, + "max": 6056.494140625, + "p25": 5967.8955078125, + "p50": 5974.267578125, + "p75": 5991.552734375, + "p99": 6009.3017578125, + "p999": 6009.3017578125, + "avg": 5982.2001953125, + "ticks": 102400, + "heap": { + "_": 4, + "total": 57267.619140625, + "min": 14297.63671875, + "max": 14373.87890625, + "avg": 14316.90478515625 + } + }, + "args": {}, + "name": "eta fortunes-encoded" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars encoded-loop", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 4776200, + 4777300, + 4780300, + 4782300, + 4785300, + 4787400, + 4787600, + 4788400, + 4790500, + 4790900, + 4793800, + 4794100, + 4794300, + 4798900, + 4799900, + 4800200, + 4801000, + 4803700, + 4804400, + 4805400, + 4807100, + 4807900, + 4808500, + 4809800, + 4813400, + 4815700, + 4816400, + 4817100, + 4817700, + 4818100, + 4818800, + 4822900, + 4826600, + 4827300, + 4827500, + 4828000, + 4831100, + 4832200, + 4832200, + 4834500, + 4839900, + 4840400, + 4841100, + 4841900, + 4842700, + 4843100, + 4845800, + 4845900, + 4846300, + 4846900, + 4849300, + 4849900, + 4850000, + 4852100, + 4854700, + 4859200, + 4860000, + 4860400, + 4861000, + 4862200, + 4866400, + 4866700, + 4866900, + 4868200, + 4869300, + 4871400, + 4871600, + 4871900, + 4872500, + 4874800, + 4876200, + 4878300, + 4880400, + 4880600, + 4881000, + 4882000, + 4883700, + 4883900, + 4885800, + 4886400, + 4886600, + 4887200, + 4888700, + 4888800, + 4893600, + 4894200, + 4902900, + 4903700, + 4910600, + 4920100, + 4923800, + 4925900, + 4925900, + 4931000, + 4933700, + 4934400, + 4934900, + 4934900, + 4938200, + 4939600, + 4944000, + 4950500, + 4966200, + 4971000, + 4983100, + 5000900, + 5001200, + 5004000, + 5018000, + 5031400, + 5037700, + 5078800, + 5087900, + 5108900, + 5149700, + 5151600, + 5160000, + 5177400, + 5178200, + 5240300, + 5296800, + 5297400, + 5299800, + 5339200, + 5433100, + 6212500, + 6336600, + 6356600, + 6468400, + 6497900, + 6596400, + 6625500, + 6728500, + 6941100, + 6962300, + 7015600 + ], + "min": 4776200, + "max": 7015600, + "p25": 4827300, + "p50": 4871900, + "p75": 4950500, + "p99": 6941100, + "p999": 6962300, + "avg": 5042005.147058823, + "ticks": 136, + "heap": { + "_": 128, + "total": 954888072, + "min": 5958312, + "max": 8962248, + "avg": 7460063.0625 + } + }, + "args": {}, + "name": "handlebars encoded-loop" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta encoded-loop", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 4220700, + 4221000, + 4222100, + 4222100, + 4224600, + 4227200, + 4230900, + 4231000, + 4232400, + 4233400, + 4233800, + 4235100, + 4236500, + 4237100, + 4238200, + 4238200, + 4239300, + 4239700, + 4242900, + 4246100, + 4246700, + 4246900, + 4247500, + 4247900, + 4249000, + 4249100, + 4249300, + 4249400, + 4250000, + 4250100, + 4250500, + 4251000, + 4251400, + 4252100, + 4255500, + 4255800, + 4256500, + 4256800, + 4257900, + 4258900, + 4260200, + 4261500, + 4263500, + 4268400, + 4271100, + 4271500, + 4274000, + 4274800, + 4283400, + 4287200, + 4288500, + 4289500, + 4293000, + 4294600, + 4296400, + 4297000, + 4297700, + 4297900, + 4300200, + 4300600, + 4301200, + 4304200, + 4304800, + 4305400, + 4308400, + 4309500, + 4310600, + 4312400, + 4313700, + 4314200, + 4314600, + 4315700, + 4316700, + 4316900, + 4317300, + 4318300, + 4322800, + 4322900, + 4323600, + 4323700, + 4324700, + 4325600, + 4326000, + 4328200, + 4331300, + 4333600, + 4336000, + 4337500, + 4338900, + 4339200, + 4343900, + 4345800, + 4350400, + 4358000, + 4364100, + 4364200, + 4364800, + 4368700, + 4369700, + 4370300, + 4370600, + 4371100, + 4372000, + 4375100, + 4383000, + 4386700, + 4387300, + 4393300, + 4394600, + 4395400, + 4396200, + 4399400, + 4399400, + 4401600, + 4402000, + 4402100, + 4412800, + 4416400, + 4421400, + 4423900, + 4435600, + 4440500, + 4440500, + 4443500, + 4447400, + 4452800, + 4458300, + 4466800, + 4473000, + 4484400, + 4490300, + 4490600, + 4508300, + 4519000, + 4535300, + 4543700, + 4547100, + 4550700, + 4561600, + 4564000, + 4594400, + 4596900, + 4617000, + 4640900, + 5397600, + 5404300, + 5423000, + 5423400, + 5432700, + 5436300, + 5438200, + 5445000, + 5450600, + 5452000, + 5458900, + 5468500 + ], + "min": 4220700, + "max": 5468500, + "p25": 4257900, + "p50": 4322900, + "p75": 4412800, + "p99": 5452000, + "p999": 5458900, + "avg": 4423017.948717949, + "ticks": 156, + "heap": { + "_": 146, + "total": 1117545312, + "min": 7654136, + "max": 7669136, + "avg": 7654419.94520548 + } + }, + "args": {}, + "name": "eta encoded-loop" + } + ], + "style": { + "highlight": false, + "compact": false + } + } +] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/js/cold-compile.txt b/docs/benchmarks/2026-08-08/js/cold-compile.txt new file mode 100644 index 00000000..f520340a --- /dev/null +++ b/docs/benchmarks/2026-08-08/js/cold-compile.txt @@ -0,0 +1,73 @@ +clk: ~5.42 GHz +cpu: AMD Ryzen 9 9950X 16-Core Processor  +runtime: node 24.19.0 (x64-win32) + +benchmark avg (min … max) p75 / p99 (min … top 1%) +---------------------------------------------- ------------------------------- +• cold-compile [per-ecosystem] +---------------------------------------------- ------------------------------- +handlebars composed-page 166.42 µs/iter 163.20 µs █   + (150.30 µs … 733.10 µs) 443.80 µs █▃  + ( 11.84 kb …  2.33 mb) 590.15 kb ██▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +eta composed-page  11.44 µs/iter  11.44 µs  █    + (11.36 µs … 11.70 µs)  11.50 µs  ██    + (255.37 b … 377.37 b) 264.84 b █▁▁▁██▁▁▁▁██▁▁▁▁▁▁▁██ + +handlebars trivial-substitution 143.14 µs/iter 141.70 µs ▄█   + (132.60 µs … 685.50 µs) 236.80 µs ██   + ( 7.97 kb …  1.16 mb) 472.67 kb ███▅▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +eta trivial-substitution  6.35 µs/iter  6.37 µs   █  + (6.30 µs … 6.47 µs)  6.40 µs █ █ ██ █ █ █  + ( 13.65 kb …  14.04 kb)  13.73 kb ██████▁▁██▁██████▁▁▁█ + +handlebars large-loop 499.11 µs/iter 480.80 µs █   + (434.80 µs … 1.75 ms)  1.48 ms █▅  + (975.23 kb …  3.41 mb)  2.19 mb ██▅▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +eta large-loop 257.52 µs/iter 243.20 µs █  + (225.60 µs … 2.06 ms)  1.53 ms █  + (473.48 kb …  1.24 mb) 977.60 kb █▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +handlebars mixed-page 298.61 µs/iter 299.30 µs ▅█   + (269.50 µs … 779.70 µs) 592.60 µs ██   + (936.00 b …  2.14 mb) 949.11 kb ██▆▆▄▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +eta mixed-page  14.73 µs/iter  14.74 µs  █ █    + (14.66 µs … 14.90 µs)  14.79 µs ▅▅ ▅ █ █▅  ▅ ▅ ▅ + ( 14.56 kb …  14.59 kb)  14.57 kb ██▁█▁█▁▁██▁▁█▁▁█▁▁▁▁█ + +handlebars conditional-heavy 279.53 µs/iter 277.30 µs ▆█   + (251.40 µs … 754.80 µs) 601.60 µs ██   + ( 7.76 kb …  2.80 mb)  1.18 mb ███▃▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +eta conditional-heavy  17.20 µs/iter  17.21 µs  █   + (17.12 µs … 17.30 µs)  17.25 µs  █ █  + ( 5.32 kb …  5.34 kb)  5.33 kb █▁▁▁▁█▁▁▁▁█▁███▁█▁▁▁█ + +handlebars fragment-heavy  96.00 µs/iter  93.10 µs  █    + (85.70 µs … 839.80 µs) 160.30 µs ▅█▃   + ( 1.31 kb …  1.02 mb) 319.95 kb ███▅▃▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +eta fragment-heavy  12.00 µs/iter  12.01 µs  █    + (11.98 µs … 12.05 µs)  12.03 µs ▅▅ █▅▅▅   ▅ ▅ ▅ + ( 3.31 kb …  4.82 kb)  3.44 kb ██▁████▁▁▁▁▁▁█▁▁█▁▁▁█ + +handlebars fortunes-encoded  58.54 µs/iter  56.20 µs  █    + (51.30 µs … 1.03 ms) 109.00 µs  █    + ( 1.08 kb … 708.05 kb) 190.90 kb ██▇▃▃▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +eta fortunes-encoded  5.98 µs/iter  5.99 µs  █ ██    + (5.96 µs … 6.06 µs)  6.01 µs █ █ ██   █ █ █ + ( 13.96 kb …  14.04 kb)  13.98 kb ███▁████▁▁████▁▁█▁█▁█ + +handlebars encoded-loop  5.04 ms/iter  4.95 ms  █   + (4.78 ms … 7.02 ms)  6.94 ms ▆█   + ( 5.68 mb …  8.55 mb)  7.11 mb ██▅▃▂▂▁▁▁▁▁▁▁▁▁▁▂▂▁▁▁ + +eta encoded-loop  4.42 ms/iter  4.41 ms ▇██   + (4.22 ms … 5.47 ms)  5.45 ms ███▅  + ( 7.30 mb …  7.31 mb)  7.30 mb █████▅▄▂▁▁▁▁▁▁▁▁▁▁▁▂▆ +artifacts: cold-compile.txt + cold-compile.json written under benchmarks/js/artifacts/ (single run, two views). +DEOPT-CHECK: clean diff --git a/docs/benchmarks/2026-08-08/js/controlled.json b/docs/benchmarks/2026-08-08/js/controlled.json new file mode 100644 index 00000000..5a818d07 --- /dev/null +++ b/docs/benchmarks/2026-08-08/js/controlled.json @@ -0,0 +1,15788 @@ +[ + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 5352.3193359375, + 5353.8818359375, + 5357.5439453125, + 5365.0634765625, + 5367.333984375, + 5370.0439453125, + 5370.60546875, + 5371.826171875, + 5372.021484375116, + 5375.5615234375, + 5375.659179687384, + 5380.273437499884, + 5380.908203125, + 5382.7392578125, + 5384.765624999884, + 5391.8701171875, + 5392.260742187616, + 5393.994140625, + 5397.314453125, + 5411.9384765625, + 5415.966796875, + 5417.7001953125, + 5434.228515625, + 5439.892578125, + 5460.180664062616, + 5470.1416015625, + 5526.391601562384, + 5760.64453125 + ], + "min": 5269.99680091592, + "max": 5505.7904924665345, + "p25": 5370.60546875, + "p50": 5414.282226562492, + "p75": 5415.966796875, + "p99": 5526.391601562384, + "p999": 5526.391601562384, + "avg": 5414.282226562492, + "ticks": 114688, + "heap": { + "_": 32, + "total": 8407.380859375, + "min": 248.025390625, + "max": 417.5625, + "avg": 262.5339012328518 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 5409.752546037942, + 5445.438929966539, + 5462.380545479894, + 5472.048514229919, + 5397.572544642845, + 5417.053222656271, + 5367.012241908486, + 5427.624511718737, + 5406.177629743291, + 5505.7904924665345, + 5414.505440848223, + 5327.442248114212, + 5441.568429129465, + 5314.124797952594, + 5417.403738839298, + 5427.28881835938, + 5391.845703124984, + 5453.462437221003, + 5373.7217494419765, + 5426.344517299111, + 5297.899548760796, + 5431.388636997768, + 5414.059012276761, + 5331.351865571117, + 5443.320138113835, + 5402.245221819197, + 5419.560895647325, + 5392.583356584825, + 5403.792898995527, + 5399.826485770106, + 5381.917027064736, + 5426.962716238843, + 5400.362723214298, + 5425.998360770098, + 5269.99680091592, + 5317.419012661642, + 5436.031668526798, + 5425.072370256692 + ], + "rsdPercent": 0.9139001322471888 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 4127.7099609375, + 4128.41796875, + 4133.49609375, + 4136.42578125, + 4137.20703125, + 4139.990234375, + 4141.1865234375, + 4142.3583984375, + 4143.3837890625, + 4143.65234375, + 4144.3115234375, + 4146.044921875, + 4150.7080078125, + 4154.7607421875, + 4164.599609375, + 4167.3828125, + 4167.4072265625, + 4168.994140625, + 4181.982421875, + 4184.326171875, + 4198.193359375, + 4206.0302734375, + 4254.0771484375, + 4263.9404296875, + 4266.7724609375, + 4287.4755859375, + 4301.46484375, + 4303.2470703125, + 4311.23046875, + 4334.375, + 4342.9443359375, + 4346.435546875, + 4353.7109375, + 4372.998046875, + 4426.708984375, + 4469.5556640625, + 4473.193359375 + ], + "min": 4180.8882863898025, + "max": 4309.872097439236, + "p25": 4143.65234375, + "p50": 4235.400060705237, + "p75": 4303.2470703125, + "p99": 4469.5556640625, + "p999": 4469.5556640625, + "avg": 4235.400060705237, + "ticks": 151552, + "heap": { + "_": 41, + "total": 10547.81640625, + "min": 249.240234375, + "max": 320.236328125, + "avg": 257.07650236401076 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 4230.181059966216, + 4233.728357263513, + 4226.181112753378, + 4241.832506334459, + 4309.872097439236, + 4223.710673564189, + 4217.155167863176, + 4232.670634501689, + 4277.711280616554, + 4239.380542652027, + 4212.305347339527, + 4205.913481841216, + 4249.202254011824, + 4235.6372730152025, + 4243.098738386824, + 4234.662690033784, + 4230.679238809122, + 4231.645903716216, + 4181.45751953125, + 4256.201171875, + 4198.9330394847975, + 4248.605759079392, + 4250.762774493243, + 4201.944547086148, + 4246.474477407095, + 4248.4619140625, + 4257.768950591216, + 4303.232150607639, + 4264.691986908784, + 4262.005780194257, + 4237.9189980996625, + 4236.1288534628375, + 4235.16284839527, + 4222.546716638513, + 4223.106920396959, + 4180.8882863898025, + 4300.857883029514, + 4226.9913956925675 + ], + "rsdPercent": 0.6734244854678516 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 3, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 731.005859375, + 731.0302734375, + 731.34765625, + 731.3720703125, + 731.54296875, + 731.54296875, + 731.6162109375, + 731.73828125, + 732.3974609375, + 732.51953125, + 732.5439453125, + 732.6416015625, + 732.71484375, + 733.0810546875, + 733.2763671875, + 733.30078125, + 733.349609375, + 733.642578125, + 733.7158203125, + 733.7890625, + 733.9111328125, + 733.935546875, + 733.984375, + 734.130859375, + 734.1796875, + 734.1796875, + 734.5458984375, + 734.86328125, + 734.8876953125, + 735.0830078125, + 735.15625, + 735.400390625, + 735.4248046875, + 735.498046875, + 735.546875, + 735.6201171875, + 736.0595703125, + 736.3037109375, + 736.4013671875, + 736.4013671875, + 736.42578125, + 736.5234375, + 736.6943359375, + 737.3291015625, + 737.40234375, + 737.451171875, + 737.4755859375, + 737.5732421875, + 738.134765625, + 738.1591796875, + 738.1591796875, + 738.18359375, + 738.232421875, + 738.3544921875, + 738.916015625, + 739.013671875, + 739.111328125, + 739.111328125, + 739.4287109375, + 739.55078125, + 739.697265625, + 739.7705078125, + 739.892578125, + 739.990234375, + 739.990234375, + 740.087890625, + 740.087890625, + 740.2099609375, + 740.4541015625, + 740.7958984375, + 740.7958984375, + 740.8447265625, + 740.966796875, + 740.966796875, + 741.2353515625, + 741.4794921875, + 741.69921875, + 741.748046875, + 741.7724609375, + 741.8701171875, + 741.943359375, + 741.9921875, + 742.0654296875, + 742.236328125, + 742.28515625, + 742.3095703125, + 742.6025390625, + 742.67578125, + 742.724609375, + 743.359375, + 743.45703125, + 743.5791015625, + 743.701171875, + 743.896484375, + 743.9208984375, + 743.9697265625, + 744.4091796875, + 744.43359375, + 744.43359375, + 744.6533203125, + 744.82421875, + 744.921875, + 744.9951171875, + 745.0439453125, + 745.0439453125, + 745.263671875, + 745.263671875, + 745.6298828125, + 745.6787109375, + 745.703125, + 745.751953125, + 745.947265625, + 746.0693359375, + 746.142578125, + 746.3134765625, + 746.3134765625, + 746.337890625, + 746.5576171875, + 746.9970703125, + 747.4609375, + 747.509765625, + 747.6318359375, + 747.8271484375, + 748.14453125, + 748.14453125, + 748.2177734375, + 748.3154296875, + 748.6328125, + 748.7060546875, + 748.73046875, + 748.8037109375, + 748.8525390625, + 748.9013671875, + 749.21875, + 749.267578125, + 749.4140625, + 749.4140625, + 749.8779296875, + 749.8779296875, + 750.048828125, + 750.244140625, + 750.4150390625, + 750.732421875, + 750.9033203125, + 750.927734375, + 751.0009765625, + 751.220703125, + 751.2451171875, + 751.513671875, + 751.9775390625, + 752.0263671875, + 752.05078125, + 752.5634765625, + 752.8076171875, + 752.9296875, + 753.1005859375, + 753.2958984375, + 753.9306640625, + 754.150390625, + 754.296875, + 754.4677734375, + 754.6875, + 754.98046875, + 755.0048828125, + 755.2734375, + 755.6396484375, + 755.76171875, + 756.15234375, + 756.3232421875, + 756.494140625, + 756.6162109375, + 756.73828125, + 756.73828125, + 756.8603515625, + 757.6171875, + 757.666015625, + 757.958984375, + 758.1298828125, + 758.2763671875, + 758.3251953125, + 758.447265625, + 758.935546875, + 759.375, + 759.619140625, + 759.7900390625, + 759.9609375, + 760.05859375, + 760.205078125, + 760.400390625, + 760.7666015625, + 760.83984375, + 761.0107421875, + 761.376953125, + 761.42578125, + 761.669921875, + 761.865234375, + 762.5, + 762.5244140625, + 762.79296875, + 763.0615234375, + 763.8916015625, + 764.0380859375, + 764.404296875, + 764.697265625, + 764.892578125, + 765.33203125, + 765.6494140625, + 765.771484375, + 765.771484375, + 765.9912109375, + 766.1376953125, + 766.162109375, + 766.8212890625, + 767.96875, + 767.96875, + 768.06640625, + 771.09375, + 772.94921875, + 776.9775390625, + 777.294921875, + 781.396484375, + 783.10546875, + 786.767578125, + 793.115234375, + 793.6279296875, + 861.8896484375 + ], + "min": 719.3296270855402, + "max": 767.5793401795814, + "p25": 739.111328125, + "p50": 742.5373813562226, + "p75": 756.3232421875, + "p99": 786.767578125, + "p999": 793.6279296875, + "avg": 742.5373813562226, + "ticks": 925696, + "heap": { + "_": 171, + "total": 725365.703125, + "min": 3522.1328125, + "max": 4913.646484375, + "avg": 4240.575832290038 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 748.7662256291483, + 757.6466151646206, + 750.4132026064713, + 743.5689290364584, + 741.6828356291119, + 744.4712856359649, + 736.9173530910326, + 732.4862776131465, + 735.8106530230979, + 737.4851392663044, + 746.9058671186674, + 757.073974609375, + 736.0945991847826, + 733.8427522997836, + 747.3276818901431, + 748.1712038821586, + 739.4722084811681, + 749.8160303166483, + 719.3296270855402, + 767.5793401795814, + 728.03090631706, + 741.4043309907205, + 730.1365293305496, + 761.6077371776906, + 746.1838776844713, + 744.709108586897, + 734.1403713474026, + 743.3919270833334, + 733.3771940949675, + 738.1904933763587, + 760.5227893778027, + 730.2021947400324, + 750.3500069137168, + 755.30515398298, + 760.3944786995515, + 739.6062192958515, + 738.2139521059783, + 735.6467603600544 + ], + "rsdPercent": 1.426386146028167 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 3, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 139.9169921875, + 140.0634765625, + 140.1611328125, + 140.1611328125, + 140.234375, + 140.234375, + 140.2587890625, + 140.2587890625, + 140.33203125, + 140.3564453125, + 140.3564453125, + 140.380859375, + 140.4296875, + 140.478515625, + 140.5517578125, + 140.5517578125, + 140.576171875, + 140.576171875, + 140.625, + 140.673828125, + 140.673828125, + 140.673828125, + 140.673828125, + 140.6982421875, + 140.6982421875, + 140.6982421875, + 140.6982421875, + 140.72265625, + 140.7470703125, + 140.7470703125, + 140.7470703125, + 140.7470703125, + 140.771484375, + 140.771484375, + 140.771484375, + 140.7958984375, + 140.7958984375, + 140.8447265625, + 140.8447265625, + 140.8447265625, + 140.869140625, + 140.869140625, + 140.8935546875, + 140.91796875, + 140.91796875, + 140.9423828125, + 140.966796875, + 140.9912109375, + 140.9912109375, + 140.9912109375, + 141.015625, + 141.0400390625, + 141.0400390625, + 141.064453125, + 141.064453125, + 141.064453125, + 141.064453125, + 141.0888671875, + 141.0888671875, + 141.0888671875, + 141.0888671875, + 141.11328125, + 141.1376953125, + 141.1376953125, + 141.1376953125, + 141.1376953125, + 141.1376953125, + 141.162109375, + 141.162109375, + 141.162109375, + 141.162109375, + 141.1865234375, + 141.1865234375, + 141.1865234375, + 141.2109375, + 141.2109375, + 141.2109375, + 141.2353515625, + 141.2353515625, + 141.2353515625, + 141.2353515625, + 141.2353515625, + 141.2353515625, + 141.259765625, + 141.259765625, + 141.259765625, + 141.2841796875, + 141.30859375, + 141.30859375, + 141.30859375, + 141.3330078125, + 141.3330078125, + 141.3330078125, + 141.3330078125, + 141.357421875, + 141.3818359375, + 141.3818359375, + 141.3818359375, + 141.40625, + 141.40625, + 141.4306640625, + 141.4306640625, + 141.4306640625, + 141.455078125, + 141.455078125, + 141.455078125, + 141.4794921875, + 141.4794921875, + 141.4794921875, + 141.4794921875, + 141.50390625, + 141.5283203125, + 141.5283203125, + 141.5283203125, + 141.5283203125, + 141.552734375, + 141.552734375, + 141.552734375, + 141.5771484375, + 141.5771484375, + 141.5771484375, + 141.5771484375, + 141.5771484375, + 141.5771484375, + 141.5771484375, + 141.6015625, + 141.6015625, + 141.6015625, + 141.6259765625, + 141.650390625, + 141.650390625, + 141.650390625, + 141.650390625, + 141.650390625, + 141.650390625, + 141.650390625, + 141.650390625, + 141.650390625, + 141.6748046875, + 141.6748046875, + 141.69921875, + 141.69921875, + 141.7236328125, + 141.7236328125, + 141.7236328125, + 141.7236328125, + 141.7236328125, + 141.7236328125, + 141.748046875, + 141.748046875, + 141.748046875, + 141.748046875, + 141.7724609375, + 141.7724609375, + 141.7724609375, + 141.796875, + 141.796875, + 141.796875, + 141.796875, + 141.8212890625, + 141.8212890625, + 141.8212890625, + 141.8212890625, + 141.8212890625, + 141.845703125, + 141.845703125, + 141.845703125, + 141.8701171875, + 141.8701171875, + 141.8701171875, + 141.8701171875, + 141.89453125, + 141.89453125, + 141.89453125, + 141.89453125, + 141.89453125, + 141.9189453125, + 141.9189453125, + 141.9189453125, + 141.943359375, + 141.943359375, + 141.943359375, + 141.943359375, + 141.943359375, + 141.943359375, + 141.9677734375, + 141.9677734375, + 141.9677734375, + 141.9677734375, + 141.9921875, + 141.9921875, + 141.9921875, + 141.9921875, + 142.0166015625, + 142.0166015625, + 142.041015625, + 142.041015625, + 142.0654296875, + 142.0654296875, + 142.0654296875, + 142.0654296875, + 142.0654296875, + 142.0654296875, + 142.0654296875, + 142.08984375, + 142.08984375, + 142.08984375, + 142.1142578125, + 142.138671875, + 142.138671875, + 142.138671875, + 142.138671875, + 142.1630859375, + 142.1630859375, + 142.1630859375, + 142.1630859375, + 142.1630859375, + 142.1630859375, + 142.1875, + 142.1875, + 142.1875, + 142.2119140625, + 142.2119140625, + 142.2119140625, + 142.2119140625, + 142.2119140625, + 142.236328125, + 142.236328125, + 142.236328125, + 142.2607421875, + 142.2607421875, + 142.2607421875, + 142.2607421875, + 142.2607421875, + 142.2607421875, + 142.28515625, + 142.28515625, + 142.28515625, + 142.28515625, + 142.3095703125, + 142.3095703125, + 142.3095703125, + 142.333984375, + 142.333984375, + 142.333984375, + 142.333984375, + 142.333984375, + 142.3583984375, + 142.3583984375, + 142.3583984375, + 142.3583984375, + 142.3828125, + 142.3828125, + 142.3828125, + 142.3828125, + 142.3828125, + 142.4072265625, + 142.4072265625, + 142.4072265625, + 142.431640625, + 142.431640625, + 142.431640625, + 142.431640625, + 142.4560546875, + 142.4560546875, + 142.4560546875, + 142.4560546875, + 142.4560546875, + 142.4560546875, + 142.4560546875, + 142.48046875, + 142.48046875, + 142.48046875, + 142.48046875, + 142.48046875, + 142.48046875, + 142.5048828125, + 142.5048828125, + 142.5048828125, + 142.529296875, + 142.529296875, + 142.5537109375, + 142.5537109375, + 142.5537109375, + 142.5537109375, + 142.5537109375, + 142.578125, + 142.578125, + 142.578125, + 142.6025390625, + 142.6025390625, + 142.6025390625, + 142.6025390625, + 142.6025390625, + 142.6025390625, + 142.626953125, + 142.626953125, + 142.6513671875, + 142.6513671875, + 142.67578125, + 142.67578125, + 142.67578125, + 142.67578125, + 142.7001953125, + 142.7001953125, + 142.7001953125, + 142.7001953125, + 142.7001953125, + 142.7001953125, + 142.724609375, + 142.724609375, + 142.724609375, + 142.724609375, + 142.7490234375, + 142.7490234375, + 142.7490234375, + 142.7490234375, + 142.7734375, + 142.7734375, + 142.7978515625, + 142.7978515625, + 142.7978515625, + 142.7978515625, + 142.7978515625, + 142.7978515625, + 142.7978515625, + 142.7978515625, + 142.7978515625, + 142.7978515625, + 142.822265625, + 142.8466796875, + 142.87109375, + 142.87109375, + 142.87109375, + 142.87109375, + 142.87109375, + 142.8955078125, + 142.8955078125, + 142.8955078125, + 142.8955078125, + 142.8955078125, + 142.8955078125, + 142.8955078125, + 142.919921875, + 142.919921875, + 142.919921875, + 142.919921875, + 142.919921875, + 142.9443359375, + 142.9443359375, + 142.9443359375, + 142.96875, + 142.96875, + 142.96875, + 142.96875, + 142.96875, + 142.96875, + 142.96875, + 142.96875, + 142.96875, + 142.96875, + 142.96875, + 142.96875, + 142.96875, + 142.9931640625, + 142.9931640625, + 142.9931640625, + 142.9931640625, + 142.9931640625, + 142.9931640625, + 143.017578125, + 143.017578125, + 143.017578125, + 143.017578125, + 143.017578125, + 143.017578125, + 143.017578125, + 143.017578125, + 143.0419921875, + 143.0419921875, + 143.0419921875, + 143.0419921875, + 143.0419921875, + 143.06640625, + 143.06640625, + 143.06640625, + 143.06640625, + 143.0908203125, + 143.0908203125, + 143.0908203125, + 143.0908203125, + 143.0908203125, + 143.115234375, + 143.115234375, + 143.115234375, + 143.115234375, + 143.115234375, + 143.115234375, + 143.115234375, + 143.115234375, + 143.115234375, + 143.1396484375, + 143.1396484375, + 143.1396484375, + 143.1396484375, + 143.1640625, + 143.1640625, + 143.1640625, + 143.1640625, + 143.1640625, + 143.1640625, + 143.1884765625, + 143.1884765625, + 143.1884765625, + 143.1884765625, + 143.1884765625, + 143.1884765625, + 143.212890625, + 143.212890625, + 143.212890625, + 143.212890625, + 143.212890625, + 143.2373046875, + 143.2373046875, + 143.2373046875, + 143.2373046875, + 143.2373046875, + 143.2373046875, + 143.2373046875, + 143.2373046875, + 143.2373046875, + 143.26171875, + 143.26171875, + 143.2861328125, + 143.2861328125, + 143.2861328125, + 143.2861328125, + 143.2861328125, + 143.2861328125, + 143.2861328125, + 143.2861328125, + 143.2861328125, + 143.310546875, + 143.310546875, + 143.310546875, + 143.310546875, + 143.310546875, + 143.310546875, + 143.310546875, + 143.310546875, + 143.3349609375, + 143.3349609375, + 143.3349609375, + 143.3349609375, + 143.3349609375, + 143.3349609375, + 143.3349609375, + 143.3349609375, + 143.359375, + 143.359375, + 143.359375, + 143.359375, + 143.359375, + 143.359375, + 143.359375, + 143.3837890625, + 143.3837890625, + 143.3837890625, + 143.3837890625, + 143.3837890625, + 143.3837890625, + 143.3837890625, + 143.3837890625, + 143.3837890625, + 143.3837890625, + 143.3837890625, + 143.408203125, + 143.408203125, + 143.408203125, + 143.408203125, + 143.4326171875, + 143.4326171875, + 143.4326171875, + 143.4326171875, + 143.4326171875, + 143.45703125, + 143.45703125, + 143.45703125, + 143.45703125, + 143.4814453125, + 143.4814453125, + 143.4814453125, + 143.4814453125, + 143.4814453125, + 143.4814453125, + 143.4814453125, + 143.4814453125, + 143.505859375, + 143.505859375, + 143.505859375, + 143.505859375, + 143.505859375, + 143.505859375, + 143.5302734375, + 143.5302734375, + 143.5302734375, + 143.5546875, + 143.5546875, + 143.5546875, + 143.5546875, + 143.5546875, + 143.5546875, + 143.5791015625, + 143.5791015625, + 143.5791015625, + 143.5791015625, + 143.5791015625, + 143.5791015625, + 143.5791015625, + 143.5791015625, + 143.603515625, + 143.603515625, + 143.603515625, + 143.603515625, + 143.603515625, + 143.603515625, + 143.603515625, + 143.6279296875, + 143.6279296875, + 143.6279296875, + 143.6279296875, + 143.6279296875, + 143.6279296875, + 143.6279296875, + 143.65234375, + 143.65234375, + 143.65234375, + 143.65234375, + 143.65234375, + 143.65234375, + 143.65234375, + 143.65234375, + 143.65234375, + 143.6767578125, + 143.6767578125, + 143.6767578125, + 143.6767578125, + 143.701171875, + 143.701171875, + 143.701171875, + 143.701171875, + 143.7255859375, + 143.7255859375, + 143.75, + 143.75, + 143.75, + 143.75, + 143.75, + 143.75, + 143.75, + 143.7744140625, + 143.7744140625, + 143.7744140625, + 143.7744140625, + 143.7744140625, + 143.7744140625, + 143.798828125, + 143.798828125, + 143.798828125, + 143.798828125, + 143.798828125, + 143.8232421875, + 143.8232421875, + 143.8232421875, + 143.8232421875, + 143.8232421875, + 143.8232421875, + 143.8232421875, + 143.84765625, + 143.84765625, + 143.84765625, + 143.84765625, + 143.84765625, + 143.84765625, + 143.84765625, + 143.8720703125, + 143.8720703125, + 143.8720703125, + 143.8720703125, + 143.8720703125, + 143.8720703125, + 143.896484375, + 143.896484375, + 143.896484375, + 143.896484375, + 143.896484375, + 143.896484375, + 143.896484375, + 143.896484375, + 143.896484375, + 143.9208984375, + 143.9208984375, + 143.9208984375, + 143.9208984375, + 143.9208984375, + 143.9208984375, + 143.9208984375, + 143.9453125, + 143.9453125, + 143.9453125, + 143.9453125, + 143.9697265625, + 143.9697265625, + 143.9697265625, + 143.9697265625, + 143.9697265625, + 143.9697265625, + 143.9697265625, + 143.9697265625, + 143.994140625, + 143.994140625, + 143.994140625, + 143.994140625, + 143.994140625, + 144.0185546875, + 144.0185546875, + 144.0185546875, + 144.0185546875, + 144.0185546875, + 144.0185546875, + 144.0185546875, + 144.04296875, + 144.04296875, + 144.04296875, + 144.04296875, + 144.04296875, + 144.04296875, + 144.04296875, + 144.04296875, + 144.0673828125, + 144.0673828125, + 144.0673828125, + 144.0673828125, + 144.0673828125, + 144.0673828125, + 144.0673828125, + 144.091796875, + 144.091796875, + 144.091796875, + 144.091796875, + 144.091796875, + 144.091796875, + 144.091796875, + 144.091796875, + 144.091796875, + 144.091796875, + 144.1162109375, + 144.1162109375, + 144.1162109375, + 144.1162109375, + 144.1162109375, + 144.1162109375, + 144.1162109375, + 144.1162109375, + 144.140625, + 144.140625, + 144.140625, + 144.140625, + 144.140625, + 144.140625, + 144.140625, + 144.140625, + 144.140625, + 144.1650390625, + 144.1650390625, + 144.1650390625, + 144.1650390625, + 144.1650390625, + 144.1650390625, + 144.1650390625, + 144.1650390625, + 144.1650390625, + 144.1650390625, + 144.1650390625, + 144.1650390625, + 144.189453125, + 144.189453125, + 144.189453125, + 144.189453125, + 144.189453125, + 144.2138671875, + 144.2138671875, + 144.2138671875, + 144.2138671875, + 144.2138671875, + 144.23828125, + 144.23828125, + 144.23828125, + 144.23828125, + 144.23828125, + 144.23828125, + 144.2626953125, + 144.2626953125, + 144.2626953125, + 144.2626953125, + 144.2626953125, + 144.2626953125, + 144.287109375, + 144.287109375, + 144.287109375, + 144.287109375, + 144.3115234375, + 144.3115234375, + 144.3115234375, + 144.3115234375, + 144.3115234375, + 144.3115234375, + 144.3115234375, + 144.3115234375, + 144.3115234375, + 144.3115234375, + 144.3115234375, + 144.3359375, + 144.3359375, + 144.3359375, + 144.3359375, + 144.3603515625, + 144.3603515625, + 144.3603515625, + 144.3603515625, + 144.3603515625, + 144.3603515625, + 144.3603515625, + 144.384765625, + 144.384765625, + 144.384765625, + 144.384765625, + 144.4091796875, + 144.4091796875, + 144.4091796875, + 144.4091796875, + 144.4091796875, + 144.4091796875, + 144.4091796875, + 144.4091796875, + 144.4091796875, + 144.4091796875, + 144.4091796875, + 144.4091796875, + 144.43359375, + 144.43359375, + 144.43359375, + 144.43359375, + 144.43359375, + 144.43359375, + 144.4580078125, + 144.4580078125, + 144.4580078125, + 144.4580078125, + 144.4580078125, + 144.482421875, + 144.482421875, + 144.482421875, + 144.482421875, + 144.482421875, + 144.482421875, + 144.5068359375, + 144.5068359375, + 144.5068359375, + 144.5068359375, + 144.5068359375, + 144.5068359375, + 144.5068359375, + 144.5068359375, + 144.53125, + 144.53125, + 144.53125, + 144.5556640625, + 144.5556640625, + 144.5556640625, + 144.5556640625, + 144.5556640625, + 144.580078125, + 144.580078125, + 144.580078125, + 144.580078125, + 144.580078125, + 144.580078125, + 144.6044921875, + 144.6044921875, + 144.6044921875, + 144.6044921875, + 144.6044921875, + 144.6044921875, + 144.6044921875, + 144.6044921875, + 144.6044921875, + 144.62890625, + 144.62890625, + 144.62890625, + 144.62890625, + 144.62890625, + 144.62890625, + 144.6533203125, + 144.6533203125, + 144.6533203125, + 144.6533203125, + 144.6533203125, + 144.6533203125, + 144.677734375, + 144.677734375, + 144.677734375, + 144.677734375, + 144.7021484375, + 144.7021484375, + 144.7021484375, + 144.7021484375, + 144.7021484375, + 144.7021484375, + 144.7021484375, + 144.7021484375, + 144.7509765625, + 144.7509765625, + 144.7509765625, + 144.7509765625, + 144.7509765625, + 144.7509765625, + 144.7509765625, + 144.775390625, + 144.775390625, + 144.775390625, + 144.775390625, + 144.7998046875, + 144.7998046875, + 144.7998046875, + 144.7998046875, + 144.82421875, + 144.82421875, + 144.82421875, + 144.82421875, + 144.82421875, + 144.82421875, + 144.8486328125, + 144.8486328125, + 144.8486328125, + 144.8486328125, + 144.8486328125, + 144.873046875, + 144.873046875, + 144.873046875, + 144.873046875, + 144.873046875, + 144.8974609375, + 144.8974609375, + 144.8974609375, + 144.8974609375, + 144.8974609375, + 144.921875, + 144.921875, + 144.921875, + 144.921875, + 144.921875, + 144.921875, + 144.9462890625, + 144.9462890625, + 144.9462890625, + 144.9462890625, + 144.9462890625, + 144.970703125, + 144.9951171875, + 144.9951171875, + 144.9951171875, + 144.9951171875, + 144.9951171875, + 144.9951171875, + 144.9951171875, + 144.9951171875, + 145.01953125, + 145.01953125, + 145.01953125, + 145.01953125, + 145.01953125, + 145.0439453125, + 145.0439453125, + 145.0439453125, + 145.0439453125, + 145.0439453125, + 145.0439453125, + 145.068359375, + 145.068359375, + 145.068359375, + 145.068359375, + 145.0927734375, + 145.0927734375, + 145.0927734375, + 145.1171875, + 145.1171875, + 145.1171875, + 145.1171875, + 145.1171875, + 145.1171875, + 145.1171875, + 145.1416015625, + 145.1416015625, + 145.1416015625, + 145.1416015625, + 145.1416015625, + 145.166015625, + 145.166015625, + 145.166015625, + 145.166015625, + 145.166015625, + 145.166015625, + 145.166015625, + 145.166015625, + 145.166015625, + 145.1904296875, + 145.21484375, + 145.2392578125, + 145.263671875, + 145.263671875, + 145.263671875, + 145.263671875, + 145.263671875, + 145.2880859375, + 145.2880859375, + 145.2880859375, + 145.2880859375, + 145.2880859375, + 145.2880859375, + 145.3125, + 145.3125, + 145.3125, + 145.3369140625, + 145.3369140625, + 145.361328125, + 145.361328125, + 145.361328125, + 145.361328125, + 145.3857421875, + 145.41015625, + 145.41015625, + 145.4345703125, + 145.4345703125, + 145.4345703125, + 145.4345703125, + 145.458984375, + 145.458984375, + 145.4833984375, + 145.5078125, + 145.5322265625, + 145.556640625, + 145.556640625, + 145.5810546875, + 145.6298828125, + 145.654296875, + 145.654296875, + 145.6787109375, + 145.6787109375, + 145.6787109375, + 145.703125, + 145.7275390625, + 145.751953125, + 145.7763671875, + 145.80078125, + 145.849609375, + 145.849609375, + 145.99609375, + 145.99609375, + 145.99609375, + 146.0205078125, + 146.0205078125, + 146.142578125, + 146.2158203125, + 146.2158203125, + 146.2646484375, + 146.4111328125, + 146.484375, + 146.5576171875, + 146.630859375, + 146.630859375, + 146.7529296875, + 146.77734375, + 146.923828125, + 147.3388671875, + 147.4365234375, + 147.5341796875, + 147.6806640625, + 147.8271484375, + 147.9736328125, + 148.0224609375, + 148.1201171875, + 148.2666015625, + 148.3154296875, + 148.4130859375, + 148.4375, + 148.53515625, + 148.53515625, + 148.583984375, + 148.7060546875, + 148.779296875, + 148.8037109375, + 148.9990234375, + 148.9990234375, + 149.0234375, + 149.0966796875, + 149.12109375, + 149.3896484375, + 149.462890625, + 149.5361328125, + 149.6337890625, + 149.8046875, + 149.8046875, + 149.8779296875, + 150.29296875, + 150.9765625, + 151.513671875, + 151.7822265625, + 151.9287109375, + 152.0263671875, + 152.197265625, + 152.294921875, + 152.294921875, + 152.8564453125, + 152.8564453125, + 153.2958984375, + 153.955078125, + 154.8095703125, + 156.005859375, + 156.103515625, + 156.4697265625, + 156.8115234375, + 156.8115234375, + 156.8603515625, + 156.884765625, + 156.93359375, + 156.93359375, + 157.1533203125, + 157.275390625, + 157.51953125, + 157.51953125, + 157.51953125, + 157.51953125, + 157.568359375, + 157.71484375, + 157.7392578125, + 157.763671875, + 157.8125, + 157.8369140625, + 157.91015625, + 158.0078125, + 158.056640625, + 158.10546875, + 158.203125, + 158.30078125, + 158.349609375, + 158.4716796875, + 158.49609375, + 158.49609375, + 158.5693359375, + 158.642578125, + 158.6669921875, + 158.740234375, + 158.8623046875, + 158.935546875, + 158.9599609375, + 159.0087890625, + 159.033203125, + 159.1064453125, + 159.1796875, + 159.2041015625, + 159.228515625, + 159.326171875, + 159.47265625, + 159.47265625, + 159.5458984375, + 159.5947265625, + 159.5947265625, + 159.619140625, + 159.66796875, + 159.7412109375, + 159.765625, + 159.86328125, + 159.912109375, + 159.912109375, + 159.912109375, + 159.912109375, + 159.9853515625, + 160.0341796875, + 160.05859375, + 160.05859375, + 160.107421875, + 160.1318359375, + 160.15625, + 160.15625, + 160.2294921875, + 160.2294921875, + 160.2783203125, + 160.302734375, + 160.400390625, + 160.546875, + 160.5712890625, + 160.6201171875, + 160.6689453125, + 160.7421875, + 160.888671875, + 160.888671875, + 160.9130859375, + 160.9375, + 161.0595703125, + 161.1083984375, + 161.1572265625, + 161.181640625, + 161.181640625, + 161.2548828125, + 161.279296875, + 161.376953125, + 161.376953125, + 161.4013671875, + 161.4501953125, + 161.71875, + 161.8896484375, + 162.353515625, + 162.5244140625, + 163.1103515625, + 163.1103515625, + 163.5009765625, + 163.7451171875, + 164.0625, + 164.35546875, + 165.0634765625, + 165.91796875, + 167.041015625, + 168.6767578125, + 168.7744140625, + 169.2138671875, + 171.2646484375, + 174.5849609375, + 174.7802734375, + 175.1708984375, + 175.5615234375, + 175.6103515625, + 176.1962890625, + 176.85546875, + 244.3359375, + 244.8486328125, + 245.6298828125, + 245.654296875, + 246.58203125, + 246.97265625, + 247.021484375, + 247.8271484375, + 248.095703125, + 249.0966796875, + 249.70703125, + 252.9541015625, + 253.41796875, + 253.7109375, + 261.8896484375, + 271.484375, + 282.8125, + 284.130859375, + 284.6923828125, + 287.1826171875 + ], + "min": 130.72762838224085, + "max": 147.32812835588487, + "p25": 142.6025390625, + "p50": 135.42049569272103, + "p75": 144.9951171875, + "p99": 247.8271484375, + "p999": 284.130859375, + "avg": 135.42049569272103, + "ticks": 4767744, + "heap": { + "_": 1091, + "total": 1190625.73046875, + "min": 790.55078125, + "max": 1668.16015625, + "avg": 1091.1589579952545 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 147.32812835588487, + 135.06813620468873, + 132.74587152912153, + 136.291057544217, + 135.0708968996063, + 139.09998241712287, + 130.72762838224085, + 135.86874597612916, + 133.91595463749024, + 136.39938609412292, + 134.45501536784874, + 133.32857455287714, + 137.41905016776843, + 136.31442362629173, + 133.21543636485043, + 139.4045350609756, + 131.90236253004807, + 138.36349721297418, + 131.30725901488324, + 136.20702426901312, + 133.87960989339382, + 142.43557445234634, + 132.74432202979875, + 133.886337578064, + 138.0034564965781, + 139.29170659651706, + 136.6826249688745, + 133.15103661199535, + 137.5489455944266, + 135.21229837219045, + 135.692934446697, + 134.28569844484142, + 140.00825095663265, + 133.22729245580808, + 134.5245481004902, + 134.29411049456735, + 138.46590228384787, + 135.6286930132516 + ], + "rsdPercent": 2.3679577387627813 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 5, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 362100, + 362300, + 362300, + 362800, + 362800, + 362800, + 363100, + 363700, + 363800, + 363800, + 363900, + 363900, + 364000, + 364000, + 364200, + 364200, + 364300, + 364400, + 364600, + 365000, + 365100, + 365100, + 365400, + 365500, + 365500, + 365500, + 365600, + 365600, + 365800, + 365800, + 365900, + 365900, + 365900, + 366200, + 366200, + 366200, + 366300, + 366400, + 366400, + 366500, + 366600, + 366700, + 366700, + 366800, + 366800, + 366800, + 367000, + 367000, + 367000, + 367000, + 367100, + 367200, + 367200, + 367200, + 367300, + 367300, + 367300, + 367300, + 367400, + 367400, + 367400, + 367400, + 367400, + 367400, + 367500, + 367500, + 367700, + 367700, + 367700, + 367800, + 367900, + 367900, + 368000, + 368100, + 368200, + 368200, + 368200, + 368200, + 368300, + 368300, + 368300, + 368400, + 368400, + 368400, + 368400, + 368400, + 368400, + 368500, + 368500, + 368500, + 368500, + 368500, + 368600, + 368600, + 368600, + 368700, + 368700, + 368700, + 368800, + 368800, + 368800, + 368800, + 368800, + 368900, + 368900, + 368900, + 368900, + 369000, + 369000, + 369000, + 369100, + 369100, + 369100, + 369100, + 369100, + 369100, + 369200, + 369200, + 369200, + 369200, + 369200, + 369200, + 369200, + 369200, + 369300, + 369300, + 369300, + 369300, + 369300, + 369400, + 369400, + 369400, + 369400, + 369400, + 369400, + 369400, + 369400, + 369400, + 369400, + 369500, + 369500, + 369500, + 369500, + 369500, + 369500, + 369600, + 369600, + 369600, + 369600, + 369600, + 369600, + 369600, + 369600, + 369700, + 369700, + 369700, + 369700, + 369700, + 369700, + 369700, + 369800, + 369800, + 369900, + 369900, + 369900, + 369900, + 369900, + 369900, + 369900, + 369900, + 369900, + 370000, + 370000, + 370000, + 370000, + 370000, + 370100, + 370100, + 370100, + 370100, + 370100, + 370100, + 370100, + 370100, + 370100, + 370200, + 370200, + 370200, + 370200, + 370200, + 370200, + 370200, + 370200, + 370200, + 370200, + 370300, + 370300, + 370300, + 370300, + 370300, + 370300, + 370300, + 370300, + 370300, + 370400, + 370400, + 370400, + 370400, + 370400, + 370400, + 370400, + 370400, + 370400, + 370400, + 370400, + 370400, + 370400, + 370400, + 370500, + 370500, + 370500, + 370500, + 370500, + 370500, + 370600, + 370600, + 370600, + 370600, + 370600, + 370600, + 370600, + 370700, + 370700, + 370700, + 370700, + 370700, + 370700, + 370700, + 370700, + 370700, + 370700, + 370700, + 370800, + 370800, + 370900, + 370900, + 370900, + 370900, + 370900, + 370900, + 371000, + 371000, + 371000, + 371000, + 371000, + 371000, + 371000, + 371000, + 371000, + 371100, + 371100, + 371100, + 371100, + 371100, + 371100, + 371100, + 371100, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371200, + 371300, + 371300, + 371300, + 371300, + 371300, + 371300, + 371300, + 371300, + 371300, + 371400, + 371400, + 371400, + 371400, + 371400, + 371400, + 371400, + 371500, + 371500, + 371500, + 371500, + 371500, + 371500, + 371500, + 371500, + 371500, + 371500, + 371600, + 371600, + 371600, + 371600, + 371600, + 371600, + 371600, + 371600, + 371700, + 371700, + 371700, + 371700, + 371700, + 371700, + 371700, + 371700, + 371700, + 371700, + 371700, + 371700, + 371700, + 371700, + 371800, + 371800, + 371800, + 371800, + 371800, + 371800, + 371800, + 371900, + 371900, + 371900, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372000, + 372100, + 372100, + 372100, + 372100, + 372100, + 372100, + 372100, + 372100, + 372100, + 372200, + 372200, + 372200, + 372200, + 372200, + 372200, + 372200, + 372200, + 372200, + 372200, + 372200, + 372200, + 372300, + 372300, + 372300, + 372300, + 372300, + 372300, + 372300, + 372300, + 372300, + 372300, + 372300, + 372300, + 372300, + 372400, + 372400, + 372400, + 372400, + 372400, + 372400, + 372400, + 372400, + 372400, + 372500, + 372500, + 372500, + 372500, + 372500, + 372600, + 372600, + 372600, + 372700, + 372700, + 372700, + 372700, + 372700, + 372700, + 372700, + 372700, + 372700, + 372700, + 372800, + 372800, + 372800, + 372800, + 372800, + 372800, + 372800, + 372800, + 372800, + 372800, + 372900, + 372900, + 372900, + 372900, + 372900, + 372900, + 372900, + 372900, + 372900, + 372900, + 373000, + 373000, + 373000, + 373000, + 373000, + 373000, + 373000, + 373100, + 373100, + 373100, + 373100, + 373100, + 373100, + 373100, + 373200, + 373200, + 373200, + 373200, + 373200, + 373200, + 373200, + 373200, + 373200, + 373200, + 373200, + 373200, + 373300, + 373300, + 373300, + 373300, + 373300, + 373300, + 373300, + 373400, + 373400, + 373400, + 373400, + 373400, + 373400, + 373400, + 373400, + 373500, + 373500, + 373500, + 373500, + 373500, + 373500, + 373500, + 373500, + 373500, + 373500, + 373500, + 373500, + 373500, + 373600, + 373600, + 373600, + 373600, + 373600, + 373600, + 373600, + 373600, + 373600, + 373600, + 373600, + 373600, + 373600, + 373600, + 373700, + 373700, + 373700, + 373700, + 373700, + 373700, + 373800, + 373800, + 373800, + 373800, + 373800, + 373800, + 373800, + 373800, + 373800, + 373800, + 373900, + 373900, + 373900, + 373900, + 373900, + 373900, + 373900, + 373900, + 373900, + 373900, + 373900, + 373900, + 374000, + 374000, + 374000, + 374000, + 374000, + 374000, + 374000, + 374100, + 374100, + 374100, + 374100, + 374100, + 374200, + 374200, + 374200, + 374200, + 374200, + 374200, + 374200, + 374300, + 374300, + 374300, + 374300, + 374300, + 374300, + 374300, + 374300, + 374300, + 374400, + 374400, + 374400, + 374400, + 374400, + 374400, + 374500, + 374500, + 374500, + 374500, + 374600, + 374600, + 374600, + 374600, + 374600, + 374600, + 374600, + 374600, + 374600, + 374600, + 374600, + 374600, + 374700, + 374700, + 374800, + 374800, + 374800, + 374800, + 374800, + 374800, + 374800, + 374800, + 374800, + 374800, + 374800, + 374900, + 374900, + 374900, + 374900, + 374900, + 374900, + 374900, + 374900, + 375000, + 375000, + 375000, + 375000, + 375000, + 375000, + 375000, + 375000, + 375000, + 375000, + 375000, + 375100, + 375100, + 375100, + 375100, + 375100, + 375100, + 375100, + 375100, + 375100, + 375100, + 375100, + 375100, + 375100, + 375100, + 375200, + 375200, + 375200, + 375200, + 375200, + 375300, + 375300, + 375300, + 375300, + 375300, + 375300, + 375300, + 375300, + 375300, + 375300, + 375400, + 375400, + 375500, + 375500, + 375500, + 375500, + 375500, + 375500, + 375500, + 375500, + 375500, + 375500, + 375600, + 375600, + 375600, + 375600, + 375600, + 375600, + 375600, + 375600, + 375600, + 375600, + 375700, + 375700, + 375700, + 375700, + 375700, + 375700, + 375800, + 375800, + 375800, + 375800, + 375800, + 375900, + 375900, + 375900, + 375900, + 376000, + 376000, + 376000, + 376000, + 376000, + 376000, + 376000, + 376000, + 376000, + 376000, + 376100, + 376100, + 376100, + 376100, + 376100, + 376100, + 376200, + 376200, + 376300, + 376300, + 376400, + 376400, + 376400, + 376400, + 376400, + 376500, + 376500, + 376500, + 376500, + 376500, + 376500, + 376500, + 376500, + 376600, + 376600, + 376600, + 376700, + 376700, + 376700, + 376700, + 376800, + 376800, + 376800, + 376800, + 376900, + 376900, + 376900, + 376900, + 376900, + 376900, + 377000, + 377000, + 377000, + 377000, + 377000, + 377000, + 377000, + 377100, + 377100, + 377100, + 377100, + 377100, + 377100, + 377100, + 377200, + 377200, + 377300, + 377300, + 377300, + 377400, + 377400, + 377400, + 377400, + 377500, + 377500, + 377500, + 377600, + 377600, + 377600, + 377600, + 377700, + 377700, + 377700, + 377700, + 377700, + 377700, + 377800, + 377800, + 377800, + 377800, + 377800, + 377900, + 377900, + 377900, + 377900, + 377900, + 378000, + 378000, + 378000, + 378000, + 378000, + 378100, + 378100, + 378100, + 378100, + 378100, + 378100, + 378100, + 378200, + 378200, + 378200, + 378300, + 378300, + 378300, + 378300, + 378300, + 378300, + 378300, + 378400, + 378400, + 378400, + 378400, + 378400, + 378500, + 378500, + 378500, + 378500, + 378500, + 378500, + 378500, + 378700, + 378700, + 378700, + 378800, + 378900, + 378900, + 378900, + 378900, + 378900, + 379000, + 379000, + 379000, + 379000, + 379100, + 379100, + 379100, + 379100, + 379100, + 379100, + 379100, + 379100, + 379100, + 379200, + 379200, + 379200, + 379200, + 379200, + 379200, + 379200, + 379200, + 379200, + 379300, + 379300, + 379300, + 379300, + 379300, + 379300, + 379400, + 379400, + 379400, + 379400, + 379400, + 379500, + 379500, + 379500, + 379500, + 379500, + 379500, + 379600, + 379600, + 379600, + 379600, + 379600, + 379600, + 379600, + 379600, + 379600, + 379700, + 379700, + 379700, + 379700, + 379700, + 379700, + 379700, + 379700, + 379700, + 379800, + 379800, + 379800, + 379800, + 379800, + 379800, + 379800, + 379800, + 379900, + 379900, + 379900, + 380000, + 380000, + 380000, + 380000, + 380000, + 380100, + 380100, + 380100, + 380100, + 380200, + 380200, + 380200, + 380300, + 380300, + 380300, + 380300, + 380300, + 380300, + 380300, + 380300, + 380400, + 380400, + 380400, + 380400, + 380500, + 380500, + 380500, + 380500, + 380500, + 380500, + 380500, + 380500, + 380600, + 380600, + 380600, + 380600, + 380600, + 380600, + 380600, + 380600, + 380700, + 380700, + 380700, + 380700, + 380700, + 380700, + 380700, + 380700, + 380700, + 380700, + 380800, + 380800, + 380800, + 380800, + 380800, + 380800, + 380800, + 380900, + 380900, + 380900, + 380900, + 380900, + 380900, + 381000, + 381000, + 381000, + 381000, + 381000, + 381000, + 381000, + 381000, + 381100, + 381100, + 381100, + 381100, + 381100, + 381100, + 381200, + 381200, + 381300, + 381300, + 381300, + 381300, + 381300, + 381300, + 381400, + 381400, + 381400, + 381400, + 381400, + 381400, + 381400, + 381400, + 381400, + 381400, + 381500, + 381500, + 381500, + 381500, + 381500, + 381500, + 381500, + 381500, + 381500, + 381600, + 381600, + 381700, + 381800, + 381800, + 381800, + 381800, + 381800, + 381800, + 381800, + 381800, + 381900, + 381900, + 381900, + 381900, + 381900, + 381900, + 381900, + 381900, + 381900, + 382000, + 382000, + 382000, + 382000, + 382000, + 382000, + 382000, + 382100, + 382100, + 382100, + 382100, + 382100, + 382100, + 382100, + 382200, + 382200, + 382200, + 382300, + 382300, + 382300, + 382300, + 382400, + 382400, + 382400, + 382400, + 382500, + 382500, + 382500, + 382500, + 382500, + 382500, + 382500, + 382500, + 382600, + 382600, + 382600, + 382600, + 382600, + 382600, + 382600, + 382600, + 382600, + 382600, + 382600, + 382600, + 382700, + 382700, + 382700, + 382700, + 382800, + 382800, + 382800, + 382800, + 382800, + 382900, + 382900, + 382900, + 382900, + 383000, + 383000, + 383000, + 383000, + 383000, + 383000, + 383000, + 383100, + 383100, + 383100, + 383100, + 383100, + 383100, + 383100, + 383100, + 383100, + 383200, + 383200, + 383200, + 383300, + 383300, + 383300, + 383300, + 383300, + 383400, + 383400, + 383400, + 383400, + 383400, + 383400, + 383400, + 383500, + 383500, + 383500, + 383500, + 383600, + 383600, + 383600, + 383600, + 383700, + 383700, + 383700, + 383700, + 383700, + 383800, + 383800, + 383800, + 383800, + 383800, + 383800, + 383800, + 383900, + 383900, + 383900, + 383900, + 383900, + 383900, + 383900, + 384000, + 384000, + 384000, + 384100, + 384100, + 384200, + 384200, + 384200, + 384200, + 384200, + 384300, + 384300, + 384400, + 384400, + 384400, + 384400, + 384400, + 384500, + 384500, + 384500, + 384500, + 384500, + 384500, + 384600, + 384600, + 384600, + 384600, + 384600, + 384700, + 384700, + 384800, + 384800, + 384900, + 384900, + 384900, + 384900, + 385100, + 385100, + 385100, + 385100, + 385200, + 385200, + 385200, + 385200, + 385300, + 385300, + 385300, + 385400, + 385400, + 385400, + 385400, + 385400, + 385400, + 385400, + 385500, + 385500, + 385500, + 385500, + 385500, + 385600, + 385600, + 385600, + 385600, + 385700, + 385700, + 385700, + 385700, + 385800, + 385800, + 385800, + 385800, + 385800, + 385800, + 385800, + 385900, + 385900, + 385900, + 385900, + 385900, + 386000, + 386000, + 386000, + 386000, + 386100, + 386100, + 386100, + 386100, + 386100, + 386100, + 386200, + 386200, + 386200, + 386200, + 386300, + 386300, + 386300, + 386300, + 386400, + 386400, + 386400, + 386500, + 386600, + 386700, + 386700, + 386700, + 386700, + 386700, + 386800, + 386800, + 386800, + 386900, + 386900, + 387000, + 387000, + 387000, + 387000, + 387100, + 387100, + 387100, + 387200, + 387300, + 387300, + 387300, + 387400, + 387500, + 387500, + 387500, + 387700, + 387700, + 387700, + 387800, + 387900, + 387900, + 387900, + 387900, + 387900, + 388000, + 388000, + 388000, + 388100, + 388100, + 388100, + 388200, + 388200, + 388200, + 388200, + 388200, + 388300, + 388300, + 388300, + 388300, + 388300, + 388400, + 388400, + 388500, + 388500, + 388500, + 388500, + 388500, + 388700, + 388700, + 388800, + 388800, + 388900, + 388900, + 388900, + 388900, + 389200, + 389200, + 389300, + 389300, + 389300, + 389400, + 389400, + 389400, + 389500, + 389500, + 389600, + 389800, + 389800, + 389900, + 389900, + 389900, + 390000, + 390000, + 390100, + 390100, + 390100, + 390200, + 390300, + 390400, + 390600, + 390700, + 390700, + 390700, + 390800, + 390800, + 391000, + 391000, + 391300, + 391300, + 391600, + 391600, + 391700, + 391900, + 392100, + 392200, + 392200, + 392300, + 392300, + 392400, + 392500, + 392800, + 393100, + 393400, + 393800, + 393800, + 393800, + 393900, + 394000, + 394100, + 394300, + 394300, + 394300, + 394600, + 394600, + 395000, + 395200, + 395200, + 395400, + 395500, + 395600, + 395700, + 395900, + 395900, + 396600, + 396700, + 396700, + 396700, + 397100, + 397400, + 397500, + 397600, + 398100, + 398200, + 398200, + 398300, + 398700, + 399000, + 399300, + 399600, + 399700, + 399700, + 401200, + 401400, + 401400, + 401500, + 401600, + 401600, + 401900, + 401900, + 402100, + 402300, + 402400, + 402500, + 403000, + 403100, + 403100, + 403500, + 403800, + 404100, + 404100, + 404300, + 404700, + 405000, + 405700, + 405800, + 405900, + 406000, + 406100, + 406100, + 406300, + 406500, + 406500, + 406600, + 406800, + 406900, + 406900, + 406900, + 407000, + 407100, + 407300, + 407400, + 408000, + 408000, + 408400, + 408400, + 408700, + 409000, + 409100, + 409200, + 409300, + 409500, + 409600, + 409600, + 409700, + 410100, + 410100, + 410300, + 410500, + 410500, + 410600, + 410600, + 410600, + 410800, + 411000, + 411400, + 411400, + 411600, + 411600, + 411800, + 412000, + 412000, + 412100, + 412300, + 412400, + 412500, + 412500, + 412600, + 412900, + 413300, + 413400, + 413400, + 413400, + 413600, + 413900, + 414000, + 414000, + 414100, + 414200, + 414400, + 414500, + 414500, + 414600, + 415000, + 415000, + 415100, + 415200, + 415300, + 415400, + 415600, + 415700, + 415700, + 415700, + 415900, + 416000, + 416200, + 416200, + 416300, + 416400, + 416900, + 416900, + 417000, + 417000, + 417300, + 417300, + 417300, + 417600, + 417600, + 417800, + 417800, + 418000, + 418100, + 418400, + 418400, + 418500, + 418500, + 418500, + 418600, + 418900, + 418900, + 419100, + 419200, + 419300, + 419700, + 419700, + 419900, + 420000, + 420000, + 420400, + 420400, + 420500, + 420600, + 420700, + 421100, + 421200, + 421200, + 421300, + 421700, + 421700, + 421900, + 422100, + 422400, + 422400, + 422500, + 422500, + 422600, + 422700, + 422700, + 422700, + 422800, + 422800, + 423100, + 423300, + 423300, + 423300, + 423400, + 423700, + 423900, + 424300, + 424300, + 424600, + 424700, + 424700, + 424800, + 424800, + 424900, + 425000, + 425100, + 425200, + 425400, + 425400, + 425700, + 425800, + 425900, + 426600, + 426700, + 426800, + 426900, + 427100, + 427300, + 427500, + 427900, + 428000, + 428000, + 428000, + 428100, + 428200, + 429000, + 430000, + 430400, + 430400, + 431200, + 431500, + 431600, + 431800, + 431900, + 432000, + 432000, + 432700, + 432900, + 433400, + 433800, + 434400, + 434600, + 435500, + 436900, + 437200, + 437300, + 437600, + 439300, + 439500, + 440100, + 442300, + 442800, + 443900, + 443900, + 444700, + 445800, + 447900, + 448100, + 448200, + 448300, + 449600, + 450100, + 451300, + 451700, + 451900, + 452000, + 452700, + 452900, + 453100, + 453700, + 454100, + 454100, + 454300, + 454400, + 454400, + 455500, + 458000, + 458200, + 459000, + 459600, + 460900, + 461700, + 462000, + 462200, + 463100, + 463800, + 464000, + 464800, + 464900, + 465400, + 467600, + 468900, + 469700, + 470300, + 474200, + 478400, + 486600, + 486900, + 491200, + 491900, + 496700, + 497200, + 499600, + 511600, + 513000, + 514600, + 520900, + 527300, + 593000, + 716500, + 920200, + 1084200, + 1090900, + 1097600, + 1098000, + 1098400, + 1109000, + 1115100, + 1116000, + 1119000, + 1134100, + 1136000, + 1142800, + 1158900, + 1171600, + 1175400, + 1175400, + 1182000, + 1184700, + 1187900, + 1202500, + 1207700, + 1209700, + 1210800, + 1212400, + 1221800, + 1232200, + 1243300, + 1248600, + 1262600, + 1293000, + 1298700, + 1303900, + 1305700, + 1312300, + 1319800, + 1321900, + 1326600, + 1331100, + 1347600, + 1350700, + 1354800, + 1359100, + 1360900, + 1366400, + 1385700, + 1391700, + 1415100 + ], + "min": 401000.17142857146, + "max": 420329.5386458957, + "p25": 372800, + "p50": 407297.27219965175, + "p75": 388400, + "p99": 1262600, + "p999": 1385700, + "avg": 407297.27219965175, + "ticks": 1712, + "heap": { + "_": 1667, + "total": 3532313592, + "min": 1383512, + "max": 3250272, + "avg": 2118946.4877747525 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 409729.0303738318, + 413050.26486168336, + 405996.58564814815, + 410994.61358313815, + 420329.5386458957, + 409190.72886297374, + 406343.3121019108, + 410267.21215663356, + 410282.7485380117, + 409677.52481027436, + 404672.4336793541, + 416285.6973293769, + 406070.4453441296, + 407387.1735345328, + 404864.1291810842, + 406962.26086956525, + 404409.9711815562, + 407827.600232423, + 401000.17142857146, + 405312.9907621247, + 406872.6376811594, + 406314.1864504922, + 406277.5014459225, + 408708.56144437974, + 406793.27536231885, + 408521.47846332943, + 405318.1870669746, + 407295.6471271039, + 416447.59643916914, + 409979.67289719626, + 406700.5214368482, + 407298.8972721996, + 405079.0536641662, + 405310.7390300231, + 409906.8925233645, + 405166.8013856813, + 413004.2966450853, + 408477.9394644936 + ], + "rsdPercent": 0.9174913694669828 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 5, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 214600, + 215300, + 215500, + 215600, + 215700, + 215700, + 215800, + 215800, + 215800, + 215900, + 215900, + 215900, + 215900, + 215900, + 215900, + 215900, + 216000, + 216000, + 216000, + 216000, + 216000, + 216200, + 216200, + 216300, + 216300, + 216300, + 216300, + 216400, + 216400, + 216400, + 216400, + 216400, + 216500, + 216500, + 216500, + 216500, + 216600, + 216600, + 216700, + 216700, + 216700, + 216800, + 216800, + 216800, + 216800, + 216800, + 216800, + 216900, + 216900, + 216900, + 216900, + 216900, + 217000, + 217000, + 217000, + 217000, + 217000, + 217000, + 217100, + 217100, + 217100, + 217100, + 217200, + 217200, + 217200, + 217200, + 217200, + 217300, + 217300, + 217300, + 217300, + 217400, + 217400, + 217400, + 217400, + 217400, + 217400, + 217400, + 217500, + 217500, + 217500, + 217600, + 217600, + 217600, + 217600, + 217600, + 217700, + 217700, + 217700, + 217700, + 217700, + 217800, + 217800, + 217900, + 217900, + 217900, + 217900, + 218000, + 218000, + 218100, + 218100, + 218100, + 218100, + 218100, + 218200, + 218200, + 218200, + 218200, + 218200, + 218200, + 218200, + 218300, + 218300, + 218300, + 218300, + 218300, + 218300, + 218300, + 218300, + 218300, + 218400, + 218400, + 218400, + 218400, + 218500, + 218500, + 218500, + 218500, + 218600, + 218600, + 218600, + 218600, + 218600, + 218600, + 218700, + 218700, + 218700, + 218700, + 218700, + 218700, + 218700, + 218700, + 218700, + 218700, + 218800, + 218800, + 218800, + 218800, + 218800, + 218800, + 218800, + 218800, + 218800, + 218800, + 218800, + 218800, + 218800, + 218900, + 218900, + 218900, + 218900, + 218900, + 218900, + 218900, + 218900, + 218900, + 218900, + 218900, + 218900, + 218900, + 218900, + 218900, + 219000, + 219000, + 219000, + 219000, + 219000, + 219000, + 219000, + 219000, + 219000, + 219000, + 219000, + 219000, + 219100, + 219100, + 219100, + 219100, + 219100, + 219100, + 219100, + 219100, + 219100, + 219100, + 219100, + 219100, + 219100, + 219100, + 219100, + 219200, + 219200, + 219200, + 219200, + 219200, + 219200, + 219200, + 219200, + 219200, + 219200, + 219200, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219300, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219400, + 219500, + 219500, + 219500, + 219500, + 219500, + 219500, + 219500, + 219500, + 219500, + 219500, + 219500, + 219500, + 219500, + 219500, + 219500, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219600, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219700, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219800, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 219900, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220000, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220100, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220200, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300, + 220300.00000095367, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220400, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220500, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220600, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220700, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220800, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 220900, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221000, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221100, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221200, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221300, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221400, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221500, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221600, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221700, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221800, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 221900, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222000, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222100, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222200, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222300, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222400, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222500, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222600, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222700, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222800, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 222900, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223000, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223100, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223200, + 223300, + 223300, + 223300, + 223300, + 223300, + 223300, + 223300, + 223300, + 223300, + 223300, + 223300, + 223300, + 223300, + 223300, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223400, + 223500, + 223500, + 223500, + 223500, + 223500, + 223500, + 223500, + 223500, + 223500, + 223600, + 223600, + 223600, + 223600, + 223600, + 223600, + 223600, + 223600, + 223600, + 223600, + 223600, + 223600, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223700, + 223800, + 223800, + 223800, + 223800, + 223800, + 223800, + 223800, + 223800, + 223800, + 223800, + 223800, + 223900, + 223900, + 223900, + 223900, + 223900, + 223900, + 223900, + 223900, + 224000, + 224000, + 224000, + 224000, + 224100, + 224100, + 224100, + 224100, + 224100, + 224100, + 224100, + 224100, + 224100, + 224100, + 224200, + 224200, + 224200, + 224200, + 224200, + 224200, + 224200, + 224200, + 224200, + 224200, + 224200, + 224300, + 224300, + 224300, + 224300, + 224300, + 224300, + 224300, + 224400, + 224400, + 224400, + 224400, + 224400, + 224400, + 224400, + 224400, + 224400, + 224400, + 224400, + 224400, + 224400, + 224400, + 224500, + 224500, + 224500, + 224500, + 224500, + 224500, + 224500, + 224500, + 224500, + 224600, + 224600, + 224600, + 224600, + 224600, + 224600, + 224600, + 224600, + 224600, + 224600, + 224600, + 224600, + 224700, + 224700, + 224700, + 224700, + 224700, + 224700, + 224700, + 224700, + 224700, + 224700, + 224700, + 224700, + 224700, + 224700, + 224800, + 224800, + 224800, + 224800, + 224800, + 224800, + 224800, + 224800, + 224800, + 224800, + 224800, + 224800, + 224800, + 224800, + 224800, + 224900, + 224900, + 225000, + 225000, + 225000, + 225000, + 225000, + 225100, + 225100, + 225100, + 225100, + 225100, + 225100, + 225100, + 225100, + 225100, + 225200, + 225200, + 225200, + 225200, + 225200, + 225200, + 225200, + 225200, + 225300, + 225300, + 225300, + 225300, + 225300, + 225300, + 225300, + 225300, + 225300, + 225300, + 225300, + 225400, + 225400, + 225400, + 225400, + 225400, + 225400, + 225400, + 225400, + 225400, + 225500, + 225500, + 225500, + 225500, + 225600, + 225600, + 225600, + 225600, + 225600, + 225600, + 225600, + 225700, + 225700, + 225700, + 225700, + 225700, + 225700, + 225800, + 225800, + 225800, + 225800, + 225800, + 225900, + 225900, + 225900, + 225900, + 225900, + 225900, + 225900, + 225900, + 225900, + 225900, + 225900, + 226000, + 226000, + 226000, + 226000, + 226000, + 226000, + 226000, + 226000, + 226000, + 226000, + 226100, + 226100, + 226100, + 226100, + 226100, + 226100, + 226100, + 226100, + 226100, + 226100, + 226100, + 226200, + 226200, + 226200, + 226200, + 226300, + 226300, + 226400, + 226400, + 226400, + 226500, + 226500, + 226500, + 226500, + 226500, + 226500, + 226600, + 226600, + 226600, + 226600, + 226700, + 226700, + 226700, + 226700, + 226700, + 226700, + 226700, + 226700, + 226800, + 226800, + 226800, + 226800, + 226800, + 226800, + 226900, + 226900, + 227000, + 227000, + 227000, + 227000, + 227000, + 227000, + 227000, + 227100, + 227100, + 227100, + 227200, + 227200, + 227200, + 227200, + 227200, + 227200, + 227300, + 227300, + 227300, + 227300, + 227300, + 227400, + 227500, + 227600, + 227600, + 227600, + 227700, + 227700, + 227700, + 227700, + 227700, + 227800, + 227800, + 227800, + 227800, + 227900, + 227900, + 227900, + 228000, + 228000, + 228000, + 228000, + 228100, + 228100, + 228100, + 228100, + 228100, + 228100, + 228200, + 228200, + 228200, + 228200, + 228200, + 228200, + 228300, + 228300, + 228300, + 228300, + 228300, + 228300, + 228300, + 228400, + 228400, + 228400, + 228400, + 228400, + 228500, + 228500, + 228500, + 228500, + 228600, + 228600, + 228600, + 228600, + 228600, + 228700, + 228700, + 228800, + 228800, + 228800, + 228800, + 228900, + 228900, + 228900, + 228900, + 228900, + 228900, + 228900, + 228900, + 228900, + 228900, + 228900, + 229000, + 229000, + 229000, + 229100, + 229100, + 229100, + 229100, + 229100, + 229100, + 229200, + 229200, + 229200, + 229200, + 229200, + 229200, + 229200, + 229200, + 229200, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229300, + 229400, + 229400, + 229400, + 229400, + 229400, + 229500, + 229500, + 229500, + 229500, + 229500, + 229500, + 229500, + 229500, + 229500, + 229600, + 229600, + 229600, + 229600, + 229600, + 229600, + 229600, + 229700, + 229700, + 229700, + 229700, + 229700, + 229700, + 229700, + 229700, + 229700, + 229700, + 229700, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229800, + 229900, + 229900, + 229900, + 229900, + 229900, + 229900, + 229900, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230000, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230100, + 230200, + 230200, + 230200, + 230200, + 230200, + 230200, + 230200, + 230200, + 230200, + 230300, + 230300, + 230300, + 230300, + 230300, + 230300, + 230300, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230400, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230500, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230600, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230700, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230800, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 230900, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231000, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231100, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231200, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231300, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231400, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231500, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231600, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231700, + 231800, + 231800, + 231800, + 231800, + 231800, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 231900, + 232000, + 232000, + 232000, + 232000, + 232000, + 232100, + 232100, + 232100, + 232100, + 232100, + 232100, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232200, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232300, + 232400, + 232400, + 232400, + 232400, + 232400, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232500, + 232600, + 232600, + 232600, + 232600, + 232600, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232700, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232800, + 232900, + 232900, + 233000, + 233000, + 233000, + 233000, + 233000, + 233100, + 233100, + 233100, + 233200, + 233200, + 233200, + 233300, + 233300, + 233300, + 233300, + 233300, + 233400, + 233400, + 233400, + 233400, + 233400, + 233400, + 233500, + 233500, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233600, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233700, + 233800, + 233800, + 233800, + 233800, + 233900, + 233900, + 233900, + 233900, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234000, + 234100, + 234100, + 234100, + 234100, + 234100, + 234100, + 234200, + 234200, + 234300, + 234300, + 234300, + 234400, + 234400, + 234500, + 234500, + 234500, + 234500, + 234600, + 234600, + 234600, + 234600, + 234800, + 234900, + 235000, + 235000, + 235000, + 235100, + 235100, + 235100, + 235100, + 235100, + 235200, + 235200, + 235400, + 235400, + 235400, + 235500, + 235600, + 235600, + 235700, + 235700, + 235800, + 235800, + 235900, + 236000, + 236100, + 236100, + 236200, + 236200, + 236200, + 236300, + 236300, + 236300, + 236300, + 236300, + 236400, + 236400, + 236500, + 236500, + 236500, + 236600, + 236600, + 236600, + 236800, + 236800, + 236800, + 236800, + 236900, + 236900, + 237000, + 237100, + 237200, + 237300, + 237300, + 237300, + 237400, + 237500, + 237700, + 237700, + 237700, + 237800, + 237800, + 237900, + 238000, + 238100, + 238100, + 238200, + 238200, + 238300, + 238400, + 238500, + 238500, + 238700, + 238800, + 239000, + 239000, + 239200, + 239300, + 239300, + 239300, + 239500, + 239600, + 239800, + 239800, + 239800, + 239900, + 239900, + 240100, + 240100, + 240200, + 240300, + 240500, + 240600, + 240700, + 240800, + 240900, + 240900, + 241000, + 241200, + 241300, + 241300, + 241400, + 241400, + 241500, + 241500, + 241600, + 241700, + 241700, + 241700, + 242100, + 242100, + 242100, + 242200, + 242200, + 242200, + 242300, + 242400, + 242600, + 242600, + 242600, + 242800, + 243100, + 243100, + 243200, + 243300, + 243400, + 243500, + 243500, + 243700, + 243700, + 243700, + 243800, + 244000, + 244000, + 244100, + 244200, + 244500, + 244500, + 244500, + 244500, + 244600, + 244700, + 244700, + 244900, + 244900, + 245000, + 245100, + 245100, + 245200, + 245800, + 245900, + 246000, + 246300, + 246400, + 246400, + 246400, + 246400, + 246500, + 246900, + 247100, + 247200, + 247200, + 247300, + 247400, + 247400, + 247600, + 247600, + 247700, + 247900, + 248000, + 248200, + 248300, + 248400, + 248400, + 248500, + 248900, + 249000, + 249100, + 249200, + 249200, + 249300, + 249300, + 249300, + 249500, + 249500, + 249500, + 249700, + 250000, + 250200, + 250300, + 250800, + 250900, + 251000, + 251100, + 251500, + 251600, + 251700, + 251700, + 252000, + 252000, + 252100, + 252200, + 252500, + 252600, + 252900, + 253100, + 253100, + 253100, + 253300, + 253400, + 253500, + 253700, + 254000, + 254100, + 254100, + 254200, + 254200, + 254300, + 254500, + 254600, + 254600, + 254600, + 254600, + 255100, + 255500, + 255700, + 255800, + 255900, + 255900, + 255900, + 255900, + 255900, + 256100, + 256100, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256200, + 256300, + 256500, + 256500, + 256600, + 256600, + 256800, + 256800, + 256900, + 257000, + 257100, + 257300, + 257300, + 257400, + 257500, + 257600, + 257800, + 257900, + 258100, + 258300, + 258300, + 258400, + 258400, + 258400, + 258500, + 258600, + 258600, + 258600, + 258700, + 258700, + 258800, + 258900, + 259200, + 259300, + 259300, + 259400, + 259600, + 259600, + 259600, + 259700, + 260000, + 260000, + 260000, + 260100, + 260300, + 260400, + 260400, + 260400, + 260400, + 260500, + 260900, + 261000, + 261000, + 261000, + 261200, + 261200, + 261300, + 261400, + 261500, + 261500, + 261500, + 261600, + 261700, + 261700, + 261700, + 261800, + 261800, + 261900, + 261900, + 261900, + 262000, + 262000, + 262100, + 262100, + 262100, + 262200, + 262200, + 262200, + 262400, + 262500, + 262500, + 262500, + 262500, + 262500, + 262500, + 262700, + 262700, + 262800, + 263000, + 263000, + 263000, + 263200, + 263300, + 263300, + 263300, + 263300, + 263400, + 263500, + 263500, + 263500, + 263500, + 263600, + 263600, + 263600, + 263700, + 263700, + 263700, + 263800, + 263800, + 263900, + 263900, + 263900, + 263900, + 264000, + 264000, + 264000, + 264000, + 264100, + 264100, + 264200, + 264300, + 264400, + 264400, + 264400, + 264400, + 264400, + 264400, + 264600, + 264600, + 264800, + 264800, + 264800, + 264900, + 264900, + 264900, + 264900, + 264900, + 264900, + 264900, + 265000, + 265100, + 265100, + 265200, + 265300, + 265400, + 265500, + 265700, + 265700, + 265800, + 265900, + 266100, + 266200, + 266300, + 266300, + 266300, + 266400, + 266400, + 266900, + 266900, + 267000, + 267600, + 267600, + 267800, + 267800, + 268600, + 268900, + 269500, + 269500, + 269900, + 270000, + 270100, + 270300, + 270300, + 270400, + 270500, + 270600, + 270900, + 271300, + 271400, + 271500, + 271500, + 271500, + 271900, + 272100, + 272200, + 272200, + 272400, + 272400, + 272500, + 272500, + 272500, + 272600, + 272800, + 272800, + 272800, + 272900, + 273000, + 273000, + 273100, + 273100, + 273100, + 273300, + 273500, + 273500, + 273500, + 273800, + 273800, + 273900, + 274700, + 274900, + 275100, + 275600, + 275700, + 275800, + 275900, + 275900, + 276400, + 276600, + 277800, + 277900, + 278100, + 278200, + 278300, + 279000, + 279800, + 280300, + 280300, + 280700, + 281000, + 281200, + 283400, + 287600, + 288600, + 289200, + 290900, + 291200, + 293900, + 293900, + 295100, + 296200, + 296400, + 296800, + 297300, + 297800, + 298500, + 298700, + 299900, + 300200, + 301000, + 301300, + 301700, + 301900, + 303700, + 303800, + 304800, + 305000, + 306100, + 306100, + 306800, + 307100, + 307600, + 307700, + 309200, + 312200, + 312900, + 313100, + 316700, + 317300, + 326500, + 328600, + 328900, + 332300, + 333200, + 337400, + 337400, + 339300, + 346400, + 350600, + 353900, + 358100, + 380200, + 405000, + 1696200, + 1731500, + 1770700, + 1771000, + 1776000, + 1776500, + 1780000, + 1781400, + 1784000, + 1784500, + 1786700, + 1802700, + 1804100, + 1805399.9999990463, + 1809400, + 1809600, + 1809900, + 1820600, + 1825400, + 1830400, + 1831800, + 1833400, + 1835300, + 1839100, + 1841100, + 1846500, + 1850900, + 1861100, + 1876400, + 1884500, + 1926100, + 1927100 + ], + "min": 247647.61399787912, + "max": 256711.5426896299, + "p25": 221100, + "p50": 250075.95945008798, + "p75": 231900, + "p99": 1770700, + "p999": 1876400, + "avg": 250075.95945008798, + "ticks": 2819, + "heap": { + "_": 2789, + "total": 2771715416, + "min": 257632, + "max": 1415960, + "avg": 993833.8769378596 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 248635.43809861652, + 250832.58145363408, + 248675.56818181818, + 250619.31330472103, + 249671.1586452763, + 249413.63474546102, + 248806.13692798864, + 256384.1374268992, + 256711.5426896299, + 250075.160599569, + 251547.3778735632, + 255572.12696096316, + 252028.30935251797, + 249296.44001423995, + 247647.61399787912, + 252566.67868734224, + 251574.72172351886, + 249082.29868747783, + 248913.97581792317, + 252200.28808066258, + 250774.73156764495, + 251375.46628407462, + 253357.54068716196, + 251197.20430107528, + 249026.03760198448, + 252471.9538572445, + 250699.14101646387, + 248139.1997167139, + 249417.55072979708, + 252251.83717579252, + 248723.37708407236, + 249229.13553895344, + 248912.36673773988, + 248934.40936502273, + 249714.96792587312, + 250652.2548317824, + 250076.75830060692, + 249401.60199359202 + ], + "rsdPercent": 0.8626674163474672 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 7, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 7251.611328125233, + 7255.126953125, + 7256.9091796875, + 7257.2998046875, + 7261.62109375, + 7267.919921875, + 7269.140625, + 7275.8544921875, + 7276.220703125, + 7276.904296875233, + 7278.662109374767, + 7279.370117187034, + 7283.056640625, + 7284.326171875233, + 7288.3056640625, + 7293.652343749767, + 7315.869140625, + 7364.257812500233, + 7433.7890625, + 7444.6044921875 + ], + "min": 7295.72509765625, + "max": 9421.168619791666, + "p25": 7261.62109375, + "p50": 7667.258172286209, + "p75": 7288.3056640625, + "p99": 7433.7890625, + "p999": 7433.7890625, + "avg": 7667.258172286209, + "ticks": 81920, + "heap": { + "_": 16, + "total": 90199.84375, + "min": 5466.5234375, + "max": 7425.69140625, + "avg": 5669.1504020365865 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 7295.72509765625, + 7405.159912109387, + 7487.218595805896, + 7661.689196134795, + 7550.799239309247, + 7418.767989309223, + 7445.530941611854, + 7413.895263671921, + 8205.194450827246, + 7699.596525493384, + 7861.151801215291, + 7298.085937500012, + 7677.433696546077, + 8196.547564338236, + 7556.355365954033, + 7783.464898003473, + 8153.531422334572, + 7671.810752467142, + 9421.168619791666, + 7565.996350740119, + 7715.172697368384, + 8187.129480698543, + 8118.524848090291, + 8079.743109809041, + 7885.271538628446, + 7644.337222450572, + 7749.724663628498, + 7513.770816200646, + 7512.669613486781, + 7756.431749131932, + 7644.461862664511, + 7431.938733552632, + 7945.543077256932, + 7816.495768229192, + 8397.686408547781, + 7385.812988281238, + 7662.705592105275, + 7438.3622018914475 + ], + "rsdPercent": 5.1113450864738255 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 7, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 2974.8291015625, + 2977.3193359375, + 2981.8115234375, + 2987.3291015625, + 2988.5498046875, + 2991.69921875, + 2991.8212890625, + 2992.138671875, + 2992.529296875, + 2994.3359375, + 2996.19140625, + 2997.509765625, + 2997.7783203125, + 2998.6572265625, + 3004.00390625, + 3004.736328125, + 3005.2001953125, + 3005.322265625, + 3006.73828125, + 3008.9111328125, + 3010.1318359375, + 3011.81640625, + 3012.6953125, + 3014.16015625, + 3014.7216796875, + 3016.064453125, + 3016.8701171875, + 3017.5537109375, + 3017.9443359375, + 3018.26171875, + 3021.09375, + 3021.5576171875, + 3026.7333984375, + 3027.734375, + 3027.8076171875, + 3029.6875, + 3037.890625, + 3038.4033203125, + 3039.2578125, + 3040.5029296875, + 3041.162109375, + 3044.4580078125, + 3048.3154296875, + 3051.0498046875, + 3057.8857421875, + 3059.08203125, + 3070.1416015625, + 3074.2919921875, + 3075.927734375, + 3080.95703125, + 3087.158203125, + 3104.7119140625, + 3123.1689453125 + ], + "min": 2937.870205965909, + "max": 3034.494306456368, + "p25": 2998.6572265625, + "p50": 3004.435447410301, + "p75": 3040.5029296875, + "p99": 3104.7119140625, + "p999": 3104.7119140625, + "avg": 3004.435447410301, + "ticks": 217088, + "heap": { + "_": 34, + "total": 226312.130859375, + "min": 6610.982421875, + "max": 6854.13671875, + "avg": 6655.0815728957405 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 3024.0870061910377, + 2983.8374385127313, + 3013.48876953125, + 3010.028302228009, + 3021.9017172759436, + 3005.2372685185187, + 2963.356267755682, + 2973.810040509259, + 2996.832049334491, + 3015.686939380787, + 3004.7987196180557, + 2954.6577592329545, + 3033.717202240566, + 3008.5340711805557, + 2987.5501844618057, + 2994.435402199074, + 2988.8093171296296, + 3034.494306456368, + 2973.956072771991, + 3014.4680447048613, + 2952.693536931818, + 3032.4739276238206, + 3020.0538917824074, + 2955.3599964488635, + 3010.258879484954, + 2989.4779911747687, + 3034.4920032429245, + 3013.286223234954, + 3025.4643278301887, + 2982.2758427372687, + 2993.3607313368057, + 3020.370080336085, + 2980.4163049768517, + 3000.7459852430557, + 2992.1712239583335, + 2937.870205965909, + 3004.072175202546, + 3009.521484375 + ], + "rsdPercent": 0.8250459312878332 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 9, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 92500, + 92600, + 92600, + 92600, + 92600, + 92700, + 92700, + 92700, + 92700, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98800, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99100, + 99100, + 99100, + 99100, + 99100, + 99100, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99200, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99300, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99400, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99500, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99600, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99700, + 99800, + 99800, + 99800, + 99800, + 99800, + 99900, + 99900, + 99900, + 99900, + 99900, + 99900, + 99900, + 99900, + 99900, + 100000, + 100000, + 100000, + 100000, + 100100, + 100200, + 100200, + 100200, + 100200, + 100200, + 100200, + 100300, + 100300, + 100300, + 100300, + 100300, + 100300, + 100300, + 100400, + 100500, + 100500, + 100500, + 100600, + 100600, + 100600, + 100700, + 100700, + 100700, + 100700, + 100800, + 100800, + 100900, + 101000, + 101000, + 101100, + 101300, + 101400, + 101400, + 101400, + 101500, + 101600, + 101700, + 101700, + 101900, + 101900, + 101900, + 101900, + 102000, + 102000, + 102000, + 102100, + 102200, + 102200, + 102200, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102400, + 102400, + 102400, + 102400, + 102400, + 102400, + 102400, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104700, + 104700, + 104700, + 104700, + 104700, + 104700, + 104700, + 104700, + 104700, + 104700, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104900, + 104900, + 104900, + 104900, + 104900, + 104900, + 104900, + 104900, + 104900, + 104900, + 104900, + 105000, + 105000, + 105000, + 105000, + 105000, + 105000, + 105000, + 105000, + 105000, + 105100, + 105100, + 105100, + 105100, + 105100, + 105100, + 105100, + 105200, + 105200, + 105200, + 105200, + 105200, + 105200, + 105200, + 105300, + 105300, + 105300, + 105300, + 105300, + 105300, + 105300, + 105400, + 105400, + 105400, + 105400, + 105500, + 105600, + 105600, + 105600, + 105700, + 105700, + 105700, + 105700, + 105800, + 105900, + 106000, + 106000, + 106000, + 106100, + 106200, + 106200, + 106200, + 106200, + 106200, + 106200, + 106200, + 106300, + 106300, + 106300, + 106300, + 106400, + 106400, + 106400, + 106400, + 106500, + 106500, + 106500, + 106500, + 106500, + 106600, + 106600, + 106600, + 106600, + 106700, + 106700, + 106700, + 106800, + 106800, + 106900, + 106900, + 107000, + 107000, + 107300, + 107300, + 107300, + 107400, + 107400, + 107500, + 107500, + 107500, + 107600, + 107600, + 107600, + 107600, + 107600, + 107700, + 107800, + 107900, + 108000, + 108000, + 108000, + 108100, + 108200, + 108200, + 108300, + 108400, + 108500, + 108500, + 108600, + 108600, + 108700, + 108700, + 108700, + 108800, + 108800, + 108800, + 108800, + 108900, + 108900, + 108900, + 108900, + 108900, + 109000, + 109000, + 109000, + 109000, + 109100, + 109100, + 109200, + 109200, + 109200, + 109200, + 109400, + 109400, + 109600, + 109600, + 109600, + 109700, + 109800, + 109900, + 110000, + 110000, + 110100, + 110100, + 110200, + 110200, + 110200, + 110300, + 110300, + 110400, + 110400, + 110500, + 110500, + 110700, + 111000, + 111200, + 111300, + 111400, + 111800, + 111800, + 112000, + 112100, + 112200, + 112600, + 112700, + 113000, + 113300, + 113400, + 113600, + 113700, + 114100, + 114400, + 114500, + 114900, + 114900, + 115100, + 115100, + 115100, + 115200, + 115700, + 116000, + 116100, + 116100, + 116200, + 116300, + 116600, + 117100, + 117200, + 117300, + 117300, + 117400, + 118600, + 118600, + 119200, + 119500, + 119500, + 119600, + 120300, + 120400, + 120400, + 120600, + 120700, + 120700, + 121100, + 121200, + 121400, + 121400, + 121500, + 121600, + 121700, + 121700, + 121800, + 121800, + 122500, + 122800, + 123500, + 123900, + 123900, + 124000, + 124300, + 124500, + 124500, + 124700, + 124700, + 125300, + 125600, + 125700, + 126200, + 126800, + 127300, + 128700, + 129300, + 130000, + 130300, + 130500, + 130700, + 130700, + 130900, + 131100, + 131100, + 131300, + 131700, + 131800, + 132100, + 132300, + 132800, + 133200, + 133500, + 133900, + 134000, + 134000, + 134500, + 134800, + 134800, + 135000, + 135700, + 135800, + 135900, + 135900, + 136000, + 136000, + 136200, + 136400, + 137000, + 137100, + 137200, + 137900, + 138500, + 138800, + 139400, + 139500, + 139600, + 139700, + 139900, + 140000, + 140300, + 140300, + 140600, + 140800, + 142500, + 143500, + 144300, + 144800, + 144900, + 145200, + 145500, + 145600, + 147000, + 147100, + 147100, + 148300, + 153600, + 153800, + 154000, + 154400, + 154900, + 155200, + 155700, + 155900, + 157500, + 157800, + 159200, + 160500, + 160700, + 161000, + 161100, + 161300, + 161800, + 162900, + 162900, + 163000, + 163500, + 163800, + 164700, + 164900, + 165700, + 166200, + 166300, + 166500, + 167200, + 168300, + 168800, + 169200, + 169900, + 169900, + 170400, + 170400, + 170800, + 171100, + 171100, + 171300, + 171500, + 171500, + 171700, + 171900, + 172000, + 172100, + 172600, + 172600, + 172800, + 172800, + 172900, + 172900, + 173400, + 174100, + 174500, + 174900, + 175400, + 175400, + 175900, + 176300, + 176400, + 176600, + 177100, + 177400, + 178000, + 178300, + 178300, + 180500, + 183000, + 183700, + 185400, + 186100, + 187400, + 188500, + 190100, + 190100, + 190400, + 190900, + 191800, + 195100, + 199800, + 200500, + 207700, + 209500, + 211500, + 215700, + 222400, + 227800, + 243600, + 260100, + 272300, + 285800, + 301300 + ], + "min": 93572.91500133227, + "max": 110068.91637958033, + "p25": 94100, + "p50": 101570.72706532243, + "p75": 95600, + "p99": 163000, + "p999": 211500, + "avg": 101570.72706532243, + "ticks": 7206, + "heap": { + "_": 7135, + "total": 4878229968, + "min": 74512, + "max": 1078872, + "avg": 683854.0532779475 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 97522.2175964474, + 98162.9593405058, + 102792.75892334699, + 97503.44205412907, + 102808.26748609892, + 95381.8576860402, + 95785.0347553496, + 108946.10137963106, + 105986.89291101055, + 101465.53517261303, + 99171.0615471485, + 101924.64083587288, + 108177.26643066031, + 100249.56484519903, + 97075.76678640509, + 100409.0740211489, + 104297.10553658899, + 102365.63228438229, + 107460.41284403669, + 103607.69570986289, + 101701.2011577424, + 96821.88232051813, + 103465.2679623086, + 97712.87899860917, + 107584.03001071811, + 97348.34418733546, + 101357.73448773449, + 94852.7346387576, + 102023.68573918095, + 101675.91895803183, + 93572.91500133227, + 98183.07713806596, + 98032.41696902037, + 106741.18183199149, + 108299.95375366118, + 97857.76570553002, + 110068.91637958033, + 105277.95924483068 + ], + "rsdPercent": 4.326178109901921 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 9, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 10488.37890625, + 10506.6650390625, + 10507.373046875, + 10514.013671875, + 10522.607421875, + 10526.0986328125, + 10530.1025390625, + 10539.2333984375, + 10547.607421875, + 10556.3232421875, + 10561.572265625, + 10577.001953125, + 10585.1806640625 + ], + "min": 10419.713416466346, + "max": 10679.002028245191, + "p25": 10514.013671875, + "p50": 10537.56573016827, + "p75": 10556.3232421875, + "p99": 10577.001953125, + "p999": 10577.001953125, + "avg": 10537.56573016827, + "ticks": 53248, + "heap": { + "_": 13, + "total": 57656.30078125, + "min": 4428.625, + "max": 4438.560546875, + "avg": 4434.076140245446 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 10535.550631009615, + 10472.691932091346, + 10444.501201923076, + 10632.508263221154, + 10552.202899639424, + 10518.380033052885, + 10419.713416466346, + 10557.098858173076, + 10620.025165264424, + 10490.978064903846, + 10560.39287860577, + 10494.46551983173, + 10663.27373798077, + 10496.580153245191, + 10496.1181640625, + 10501.763446514424, + 10543.141526442309, + 10547.783954326924, + 10569.711538461539, + 10679.002028245191, + 10464.676607572115, + 10562.676532451924, + 10582.230318509615, + 10546.77734375, + 10525.99346454327, + 10566.92645733173, + 10514.578951322115, + 10562.032376802885, + 10586.292442908654, + 10528.476186899039, + 10555.2490234375, + 10528.973858173076, + 10539.580829326924, + 10532.56084735577, + 10521.722881610576, + 10482.9833984375, + 10520.703125, + 10572.937950721154 + ], + "rsdPercent": 0.5112536613716755 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 11, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 6680.1025390625, + 6694.0673828125, + 6701.318359375, + 6701.4892578125, + 6723.828125, + 6726.2939453125, + 6748.33984375, + 6762.1826171875, + 6767.3095703125, + 6774.853515625, + 6775.244140625, + 6775.5126953125, + 6777.2705078125, + 6786.1083984375, + 6793.06640625, + 6799.51171875, + 6806.2255859375, + 6811.8896484375, + 6816.4306640625, + 6832.958984375, + 6848.193359375, + 6890.869140625 + ], + "min": 6570.980171535326, + "max": 7295.262451171875, + "p25": 6726.2939453125, + "p50": 6650.553200461647, + "p75": 6799.51171875, + "p99": 6848.193359375, + "p999": 6848.193359375, + "avg": 6650.553200461647, + "ticks": 90112, + "heap": { + "_": 11, + "total": 110509.162109375, + "min": 9911.87109375, + "max": 11333.046875, + "avg": 10048.39891129635 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 6772.412109375, + 6639.990234375, + 6706.059126420455, + 6639.449795809659, + 6849.211774553572, + 6570.980171535326, + 6732.723721590909, + 6597.507546164773, + 6689.462002840909, + 6645.379083806818, + 6691.139914772727, + 6636.928488991477, + 7295.262451171875, + 6598.676091974432, + 6594.992897727273, + 6591.018954190341, + 6720.530007102273, + 6720.674272017045, + 6595.250355113636, + 6655.727317116477, + 7078.251720610119, + 6630.7373046875, + 6621.35009765625, + 7168.14697265625, + 6980.230422247024, + 6629.507723721591, + 6603.087269176136, + 6821.375621448864, + 6627.732155539773, + 6639.404296875, + 6626.717862215909, + 6613.289018110795, + 6655.990323153409, + 6744.493519176136, + 6599.900124289773, + 7107.277715773809, + 6796.96044921875, + 6801.191850142045 + ], + "rsdPercent": 2.6113712425122038 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 11, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 4744.7021484375, + 4748.0224609375, + 4752.7587890625, + 4754.19921875, + 4758.88671875, + 4760.107421875, + 4764.5751953125, + 4764.84375, + 4765.13671875, + 4768.4326171875, + 4777.4658203125, + 4779.00390625, + 4783.3984375, + 4786.62109375, + 4790.6494140625, + 4790.8203125, + 4791.4306640625, + 4879.58984375, + 4898.2666015625, + 4899.951171875, + 4900.87890625, + 4906.3232421875, + 4908.544921875, + 4909.47265625, + 4909.9365234375, + 4913.3056640625, + 4914.7705078125, + 4916.259765625, + 4925.927734375, + 4929.0283203125, + 4944.970703125, + 4945.60546875 + ], + "min": 4754.603900331439, + "max": 5062.34130859375, + "p25": 4764.84375, + "p50": 4809.344100952148, + "p75": 4909.47265625, + "p99": 4944.970703125, + "p999": 4944.970703125, + "avg": 4809.344100952148, + "ticks": 131072, + "heap": { + "_": 20, + "total": 150953.564453125, + "min": 7438.08984375, + "max": 9490.546875, + "avg": 7556.366764979883 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 4836.9964599609375, + 4850.617980957031, + 4776.933288574219, + 5053.146263860887, + 4841.968536376953, + 4797.566223144531, + 4774.019738399621, + 4805.364990234375, + 4842.7764892578125, + 4803.585052490234, + 5062.34130859375, + 4788.758850097656, + 4883.21533203125, + 4889.565277099609, + 4780.133819580078, + 4823.8555908203125, + 4793.639373779297, + 4770.660955255682, + 4855.635833740234, + 4988.656123991936, + 4787.941741943359, + 4805.258941650391, + 4870.799255371094, + 4810.5926513671875, + 4784.97314453125, + 4828.556823730469, + 5044.658833165323, + 4790.580749511719, + 4813.146209716797, + 4814.195251464844, + 4800.862121582031, + 4808.095550537109, + 4857.671356201172, + 4825.9246826171875, + 4787.409973144531, + 4754.603900331439, + 4786.951446533203, + 4783.690643310547 + ], + "rsdPercent": 1.5977241400468043 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 13, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 2587.890625, + 2590.380859375, + 2592.724609375, + 2598.779296875, + 2606.2255859375, + 2606.4453125, + 2606.689453125, + 2607.421875, + 2611.181640625, + 2614.84375, + 2616.9677734375, + 2617.138671875, + 2621.9970703125, + 2622.216796875, + 2622.6806640625, + 2625.9521484375, + 2626.1962890625, + 2626.220703125, + 2626.806640625, + 2631.3720703125, + 2631.5185546875, + 2633.5205078125, + 2633.837890625, + 2633.984375, + 2635.205078125, + 2635.205078125, + 2636.1328125, + 2636.181640625, + 2636.81640625, + 2637.6953125, + 2637.79296875, + 2638.330078125, + 2638.96484375, + 2639.208984375, + 2640.380859375, + 2641.7236328125, + 2643.0908203125, + 2643.408203125, + 2644.482421875, + 2644.82421875, + 2646.3623046875, + 2650.1220703125, + 2650.634765625, + 2651.5869140625, + 2653.1494140625, + 2654.541015625, + 2656.2255859375, + 2656.93359375, + 2657.3974609375, + 2657.71484375, + 2657.9345703125, + 2658.88671875, + 2660.7666015625, + 2668.701171875, + 2668.7255859375, + 2668.994140625, + 2672.9736328125, + 2673.2666015625, + 2674.8291015625, + 2682.2265625, + 2827.880859375 + ], + "min": 2593.6159164186506, + "max": 2735.4194253177966, + "p25": 2625.9521484375, + "p50": 2644.949891137295, + "p75": 2654.541015625, + "p99": 2682.2265625, + "p999": 2682.2265625, + "avg": 2644.949891137295, + "ticks": 249856, + "heap": { + "_": 20, + "total": 229373.470703125, + "min": 11434.650390625, + "max": 11984.177734375, + "avg": 11469.47598545732 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 2640.529344902664, + 2629.463441910282, + 2629.2004000756046, + 2660.5628842213114, + 2632.041488155242, + 2654.5670306096313, + 2593.6159164186506, + 2669.718557889344, + 2670.218846055328, + 2643.5054591444673, + 2665.1923507940573, + 2624.1825226814517, + 2664.2305968237706, + 2667.0962474385246, + 2635.1365612399195, + 2670.400950947746, + 2620.5149004536293, + 2628.812531502016, + 2604.9139207409276, + 2616.253858996976, + 2654.508596951844, + 2659.3225698002047, + 2657.768874871926, + 2637.9366966985885, + 2642.752225281762, + 2668.2889344262294, + 2664.3214491547133, + 2675.4102362961066, + 2677.72436923668, + 2642.7746381915986, + 2735.4194253177966, + 2660.8374423668033, + 2646.3943231301228, + 2625.970655871976, + 2609.2757686491937, + 2637.90283203125, + 2713.748779296875, + 2638.5809129284276 + ], + "rsdPercent": 1.043713135166093 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 13, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 1759.7900390625, + 1760.3759765625, + 1761.181640625, + 1763.8427734375, + 1764.74609375, + 1765.13671875, + 1765.380859375, + 1766.015625, + 1766.50390625, + 1768.7255859375, + 1768.798828125, + 1768.84765625, + 1769.1162109375, + 1770.3857421875, + 1771.0205078125, + 1771.4111328125, + 1771.9482421875, + 1773.1689453125, + 1773.193359375, + 1775.2685546875, + 1777.9296875, + 1778.7109375, + 1779.3701171875, + 1779.443359375, + 1779.638671875, + 1781.3720703125, + 1781.93359375, + 1783.4228515625, + 1783.740234375, + 1784.47265625, + 1785.1318359375, + 1785.595703125, + 1786.23046875, + 1787.4755859375, + 1792.2607421875, + 1792.4560546875, + 1793.408203125, + 1794.2626953125, + 1794.5556640625, + 1795.6787109375, + 1795.849609375, + 1796.1181640625, + 1796.630859375, + 1797.65625, + 1797.900390625, + 1799.267578125, + 1799.51171875, + 1799.6826171875, + 1800.0244140625, + 1801.5869140625, + 1803.6865234375, + 1803.80859375, + 1804.5166015625, + 1805.7861328125, + 1805.9814453125, + 1807.470703125, + 1807.9833984375, + 1808.7646484375, + 1809.912109375, + 1810.8154296875, + 1813.4765625, + 1816.5283203125, + 1816.6015625, + 1817.6513671875, + 1818.359375, + 1819.921875, + 1820.5078125, + 1821.533203125, + 1822.998046875, + 1824.1455078125, + 1825.1708984375, + 1827.34375, + 1828.515625, + 1829.4677734375, + 1834.1796875, + 1852.294921875, + 1918.701171875, + 1937.4755859375, + 1938.0615234375, + 1949.072265625, + 1958.8623046875, + 1963.28125, + 1972.607421875, + 1974.3408203125, + 1976.7333984375, + 1980.17578125, + 1981.6162109375, + 1982.568359375, + 1994.091796875, + 2004.736328125, + 2025.927734375 + ], + "min": 1756.9782662898936, + "max": 1879.6575372869318, + "p25": 1779.3701171875, + "p50": 1825.5683647407282, + "p75": 1821.533203125, + "p99": 2004.736328125, + "p999": 2004.736328125, + "avg": 1825.5683647407282, + "ticks": 372736, + "heap": { + "_": 57, + "total": 379304.099609375, + "min": 6635.861328125, + "max": 6788.32421875, + "avg": 6654.531352488331 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 1822.767588856456, + 1850.756287306882, + 1831.0408528645833, + 1856.6968596383426, + 1852.318512991573, + 1879.6575372869318, + 1756.9782662898936, + 1873.008866743608, + 1821.3837675995878, + 1850.6498529669943, + 1863.3152650983145, + 1807.1994947350543, + 1845.8368598090278, + 1823.1949690934066, + 1805.7784370754075, + 1869.944901899858, + 1825.3047733516485, + 1835.639919704861, + 1757.0650141289893, + 1761.7374501329787, + 1809.4429347826087, + 1802.9257069463315, + 1852.8836025280898, + 1772.2754945146276, + 1811.6956773695056, + 1828.6731091174452, + 1871.8733354048295, + 1845.851779513889, + 1814.98781979739, + 1796.6069760529892, + 1823.3500386332419, + 1837.597927517361, + 1820.833243904533, + 1818.4849330357142, + 1811.6728730254122, + 1832.3760308159722, + 1857.0032698384832, + 1825.8319561298076 + ], + "rsdPercent": 1.7010597946781825 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 15, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 4530900, + 4534600, + 4534700, + 4538400, + 4538800, + 4538800, + 4542500, + 4543200, + 4544500, + 4544800, + 4545000, + 4545600, + 4546700, + 4546700, + 4547500, + 4548600, + 4549100, + 4550000, + 4550200, + 4551400, + 4552900, + 4553100, + 4553100, + 4553200, + 4554400, + 4554600, + 4554900, + 4555800, + 4555900, + 4557600, + 4558300, + 4559700, + 4561400, + 4562400, + 4565000, + 4565700, + 4566400, + 4567200, + 4567600, + 4567800, + 4572800, + 4573100, + 4574200, + 4574300, + 4576300, + 4576600, + 4576800, + 4578100, + 4580900, + 4582700, + 4587200, + 4589100, + 4592400, + 4594200, + 4595000, + 4595400, + 4597300, + 4599100, + 4603700, + 4604800, + 4605900, + 4606500, + 4606800, + 4608100, + 4608700, + 4609200, + 4612900, + 4612900, + 4615300, + 4615500, + 4619800, + 4620800, + 4622500, + 4626500, + 4626600, + 4626800, + 4627300, + 4630100, + 4634000, + 4634700, + 4635600, + 4636200, + 4637000, + 4637100, + 4637200, + 4644100, + 4645700, + 4646000, + 4647200, + 4648000, + 4648600, + 4654900, + 4657300, + 4658500, + 4658800, + 4659500, + 4661500, + 4665000, + 4671500, + 4676000, + 4694400, + 4700500, + 4703600, + 4706000, + 4710000, + 4711600, + 4722800, + 4742400, + 4743600, + 4745000, + 4745700, + 4748600, + 4749900, + 4750700, + 4754000, + 4767500, + 4767800, + 4771300, + 4772200, + 4773400, + 4779500, + 4781600, + 4786300, + 4788100, + 4798200, + 4813800, + 4839700, + 4841400, + 4841500, + 4871900, + 4879300, + 4897800, + 4908000, + 4981700, + 5608000, + 5796500, + 5853100, + 5927300, + 5934800, + 5944000, + 5989900, + 6135200, + 6261700, + 6348300, + 6448900 + ], + "min": 4569566.666666667, + "max": 4866639.007092198, + "p25": 4566400, + "p50": 4712629.452054795, + "p75": 4743600, + "p99": 6261700, + "p999": 6348300, + "avg": 4712629.452054795, + "ticks": 145, + "heap": { + "_": 137, + "total": 988818528, + "min": 6326008, + "max": 8104088, + "avg": 7217674.373821409 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 4744945.517241379, + 4741355.862068965, + 4626247.972972973, + 4744606.8965517245, + 4752625, + 4702267.808219178, + 4624687.162162162, + 4749253.1034482755, + 4706169.863013699, + 4756234.027777778, + 4763211.805555556, + 4576768, + 4690275.342465754, + 4720806.206896552, + 4726127.586206896, + 4670791.8367346935, + 4694034.931506849, + 4796915.384615385, + 4645391.216216216, + 4598830, + 4760713.888888889, + 4569566.666666667, + 4794445.454545454, + 4666717.006802721, + 4736632.413793104, + 4714880.136986301, + 4755079.861111111, + 4797109.090909091, + 4667461.904761905, + 4664601.360544218, + 4777154.861111111, + 4623463.758389262, + 4710378.767123288, + 4610288.590604027, + 4866639.007092198, + 4859546.808510638, + 4632596.621621622, + 4591299.333333333 + ], + "rsdPercent": 1.5791511313406794 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 15, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 4182000, + 4183700, + 4186800, + 4188100, + 4190500, + 4192000, + 4192100, + 4192400, + 4193700, + 4194100, + 4194100, + 4194800, + 4195700, + 4197300, + 4197500, + 4197800, + 4198800, + 4200200, + 4200900, + 4203400, + 4203900, + 4204200, + 4205100, + 4205200, + 4206200, + 4208700, + 4211900, + 4214600, + 4215800, + 4221300, + 4223400, + 4227100, + 4227300, + 4228300, + 4228500, + 4228700, + 4229400, + 4234000, + 4236700, + 4237800, + 4239200, + 4241100, + 4241700, + 4243400, + 4244000, + 4246400, + 4247500, + 4247700, + 4248600, + 4249000, + 4251400, + 4253000, + 4254000, + 4254500, + 4255800, + 4256200, + 4256900, + 4257100, + 4257200, + 4258100, + 4259600, + 4260000, + 4260100, + 4261800, + 4262300, + 4264100, + 4265800, + 4266000, + 4267100, + 4269800, + 4272200, + 4272900, + 4272900, + 4274900, + 4276200, + 4277000, + 4277200, + 4278700, + 4279100, + 4279500, + 4282800, + 4283900, + 4284800, + 4285600, + 4287500, + 4287800, + 4288200, + 4288400, + 4289400, + 4290400, + 4294000, + 4296500, + 4300100, + 4300200, + 4300600, + 4301000, + 4301100, + 4301900, + 4307800, + 4310500, + 4311900, + 4316100, + 4316200, + 4320400, + 4332000, + 4334000, + 4334700, + 4337700, + 4339600, + 4343200, + 4344600, + 4345700, + 4346700, + 4348600, + 4349600, + 4350000, + 4352500, + 4356500, + 4357300, + 4360200, + 4370700, + 4373900, + 4374400, + 4380700, + 4382900, + 4383600, + 4390300, + 4396800, + 4406400, + 4414400, + 4417900, + 4420100, + 4425900, + 4432300, + 4443200, + 4454400, + 4470300, + 4494100, + 4494700, + 4496500, + 4499600, + 4526700, + 4546900, + 4557700, + 4562500, + 5406200, + 5407000, + 5413300, + 5424100, + 5427400, + 5443400, + 5483400, + 5519200, + 5526400, + 5572800, + 5593200, + 5694000 + ], + "min": 4301750.625, + "max": 4578670.860927152, + "p25": 4237800, + "p50": 4436398.709677419, + "p75": 4356500, + "p99": 5572800, + "p999": 5593200, + "avg": 4436398.709677419, + "ticks": 157, + "heap": { + "_": 147, + "total": 1123900144, + "min": 7598096, + "max": 7655256, + "avg": 7645591.5040904125 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 4384594.267515924, + 4408566.025641026, + 4450790.322580645, + 4498821.568627451, + 4578670.860927152, + 4384543.949044586, + 4301750.625, + 4352065.189873418, + 4382186.624203822, + 4440414.838709678, + 4523567.763157895, + 4547966.225165563, + 4497796.732026144, + 4431145.806451613, + 4392073.248407643, + 4567323.178807947, + 4334887.421383648, + 4482266.883116883, + 4406226.923076923, + 4385087.898089172, + 4441728.387096774, + 4472492.207792208, + 4397861.78343949, + 4390090.445859873, + 4440482.580645162, + 4395077.070063694, + 4516184.2105263155, + 4445631.612903226, + 4390817.197452229, + 4447649.677419355, + 4414780.128205128, + 4492209.803921568, + 4466646.103896104, + 4368656.329113924, + 4433432.258064516, + 4445940.645161291, + 4403014.743589744, + 4439365.161290322 + ], + "rsdPercent": 1.4026253978892296 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + } +] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/js/controlled.txt b/docs/benchmarks/2026-08-08/js/controlled.txt new file mode 100644 index 00000000..f04b533b --- /dev/null +++ b/docs/benchmarks/2026-08-08/js/controlled.txt @@ -0,0 +1,26 @@ +# controlled — aggregate of 38 passes (ledger E6) +# +# This is NOT a single mitata run. The published statistic is the median of the per-pass +# `avg` values and the dispersion is their min…max spread, so the interval below is +# cross-process variation. Each pass's own mitata-format capture and JSON — the two views +# of one run that D11 requires — are under stability/controlled/run-.txt|.json. +# +# STABILITY: verified-with-disclosure (D13; cross-pass RSD median 1.41%, max 5.11%) +# Full verdict table: stability-summary-controlled.md + + 0 handlebars 5414.3 ns 5270.0 … 5505.8 ns RSD 0.91% + 1 eta 4235.4 ns 4180.9 … 4309.9 ns RSD 0.67% + 2 handlebars 742.5 ns 719.3 … 767.6 ns RSD 1.43% + 3 eta 135.4 ns 130.7 … 147.3 ns RSD 2.37% + 4 handlebars 407297.3 ns 401000.2 … 420329.5 ns RSD 0.92% + 5 eta 250076.0 ns 247647.6 … 256711.5 ns RSD 0.86% + 6 handlebars 7667.3 ns 7295.7 … 9421.2 ns RSD 5.11% + 7 eta 3004.4 ns 2937.9 … 3034.5 ns RSD 0.83% + 8 handlebars 101570.7 ns 93572.9 … 110068.9 ns RSD 4.33% + 9 eta 10537.6 ns 10419.7 … 10679.0 ns RSD 0.51% +10 handlebars 6650.6 ns 6571.0 … 7295.3 ns RSD 2.61% +11 eta 4809.3 ns 4754.6 … 5062.3 ns RSD 1.60% +12 handlebars 2644.9 ns 2593.6 … 2735.4 ns RSD 1.04% +13 eta 1825.6 ns 1757.0 … 1879.7 ns RSD 1.70% +14 handlebars 4712629.5 ns 4569566.7 … 4866639.0 ns RSD 1.58% +15 eta 4436398.7 ns 4301750.6 … 4578670.9 ns RSD 1.40% diff --git a/docs/benchmarks/2026-08-08/js/idiomatic.json b/docs/benchmarks/2026-08-08/js/idiomatic.json new file mode 100644 index 00000000..0243f9f6 --- /dev/null +++ b/docs/benchmarks/2026-08-08/js/idiomatic.json @@ -0,0 +1,14771 @@ +[ + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 5275.2197265625, + 5275.87890625, + 5278.5400390625, + 5282.763671875, + 5284.082031250116, + 5284.619140625, + 5285.44921875, + 5289.0869140625, + 5294.873046875, + 5295.312499999884, + 5297.94921875, + 5298.5107421875, + 5301.196289062384, + 5301.5380859375, + 5305.4443359375, + 5308.813476562733, + 5312.0361328125, + 5328.149414062384, + 5328.955078125, + 5334.3017578125, + 5339.2333984375, + 5353.369140625, + 5353.515625, + 5356.15234375, + 5382.470703124884, + 5422.4609375, + 5469.62890625, + 5917.9443359375 + ], + "min": 5270.524649784475, + "max": 5380.281284877232, + "p25": 5285.44921875, + "p50": 5322.101461476295, + "p75": 5339.2333984375, + "p99": 5469.62890625, + "p999": 5469.62890625, + "avg": 5322.101461476295, + "ticks": 114688, + "heap": { + "_": 32, + "total": 8375.107421875, + "min": 247.32421875, + "max": 388.365234375, + "avg": 261.19990303489755 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 5341.33911132812, + 5348.37036132812, + 5342.266845703125, + 5319.664264547402, + 5333.2603717672455, + 5315.558492726289, + 5313.751010237065, + 5375.588553292415, + 5296.358095366371, + 5289.450599407315, + 5376.386369977675, + 5331.357758620702, + 5340.819470635772, + 5307.039668642237, + 5296.643487338362, + 5318.377054148703, + 5342.715890066968, + 5380.281284877232, + 5317.379445043095, + 5321.266332165968, + 5301.968278556038, + 5318.317281788805, + 5322.053475215517, + 5334.659550107751, + 5312.5757677801685, + 5308.061691810365, + 5334.004579741411, + 5358.069719587058, + 5316.058560075451, + 5308.023807920263, + 5374.781145368308, + 5329.940901131457, + 5322.149447737073, + 5331.769430226297, + 5296.147629310337, + 5329.892073006466, + 5270.524649784475, + 5324.062163254298 + ], + "rsdPercent": 0.4638522221998003 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 1, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 4148.3154296875, + 4149.6826171875, + 4150.3173828125, + 4151.8798828125, + 4153.7109375, + 4153.7841796875, + 4156.93359375, + 4163.1591796875, + 4164.2822265625, + 4165.869140625, + 4168.4326171875, + 4174.072265625, + 4178.0517578125, + 4186.5966796875, + 4187.8173828125, + 4188.3056640625, + 4189.599609375, + 4197.119140625, + 4215.4296875, + 4237.0849609375, + 4242.5537109375, + 4249.6337890625, + 4254.296875, + 4265.5029296875, + 4268.9208984375, + 4270.458984375, + 4273.4375, + 4274.1455078125, + 4278.3203125, + 4281.6162109375, + 4282.03125, + 4301.220703125, + 4315.13671875, + 4334.08203125, + 4359.2529296875, + 4464.2822265625, + 4570.3369140625 + ], + "min": 4195.119826858108, + "max": 4318.273247612848, + "p25": 4165.869140625, + "p50": 4230.551559860642, + "p75": 4274.1455078125, + "p99": 4464.2822265625, + "p999": 4464.2822265625, + "avg": 4230.551559860642, + "ticks": 151552, + "heap": { + "_": 41, + "total": 10523.0390625, + "min": 249.158203125, + "max": 295.03515625, + "avg": 257.31200382100434 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 4236.9101034628375, + 4298.863389756944, + 4227.7416332347975, + 4195.119826858108, + 4236.9912637246625, + 4206.277053420608, + 4277.8214738175675, + 4241.515783361487, + 4222.910288217905, + 4226.790804476352, + 4266.142314189189, + 4212.143026815878, + 4225.154402449324, + 4208.938846072635, + 4207.7709301097975, + 4272.1884237753375, + 4224.069626266892, + 4265.2383340371625, + 4318.273247612848, + 4209.518845016892, + 4223.2949746621625, + 4281.458197699652, + 4213.8777449324325, + 4229.5654296875, + 4252.017789273648, + 4313.913302951389, + 4213.8599292652025, + 4244.139305320946, + 4208.735615498311, + 4221.394636824324, + 4221.318095439189, + 4231.537690033784, + 4231.736961570946, + 4242.5497519003375, + 4264.932828336148, + 4281.9896801097975, + 4277.289643158784, + 4213.691670185811 + ], + "rsdPercent": 0.7428037856003917 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 3, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 620.01953125, + 620.1171875, + 620.1904296875, + 620.4833984375, + 620.556640625, + 620.6298828125, + 620.6298828125, + 620.751953125, + 620.947265625, + 620.9716796875, + 621.09375, + 621.142578125, + 621.142578125, + 621.3134765625, + 621.3623046875, + 621.38671875, + 621.826171875, + 621.826171875, + 621.8505859375, + 621.9482421875, + 621.97265625, + 622.119140625, + 622.1435546875, + 622.16796875, + 622.1923828125, + 622.1923828125, + 622.265625, + 622.36328125, + 622.36328125, + 622.4365234375, + 622.509765625, + 622.55859375, + 622.65625, + 622.65625, + 622.6806640625, + 622.6806640625, + 622.7783203125, + 622.900390625, + 623.0224609375, + 623.0712890625, + 623.33984375, + 623.486328125, + 623.5595703125, + 623.6083984375, + 623.6083984375, + 623.6328125, + 623.6572265625, + 623.681640625, + 623.7548828125, + 623.7548828125, + 623.876953125, + 623.9013671875, + 623.9013671875, + 624.0234375, + 624.0478515625, + 624.0478515625, + 624.1455078125, + 624.169921875, + 624.1943359375, + 624.21875, + 624.21875, + 624.31640625, + 624.365234375, + 624.3896484375, + 624.4140625, + 624.462890625, + 624.4873046875, + 624.5361328125, + 624.560546875, + 624.560546875, + 624.70703125, + 624.70703125, + 624.755859375, + 624.8779296875, + 624.90234375, + 624.9755859375, + 624.9755859375, + 625.0732421875, + 625.09765625, + 625.1953125, + 625.1953125, + 625.3173828125, + 625.4638671875, + 625.537109375, + 625.68359375, + 625.68359375, + 625.732421875, + 625.78125, + 625.8056640625, + 625.9033203125, + 625.927734375, + 626.0498046875, + 626.1962890625, + 626.3671875, + 626.3671875, + 626.46484375, + 626.5380859375, + 626.6845703125, + 626.7333984375, + 626.85546875, + 626.8798828125, + 626.9287109375, + 626.9287109375, + 626.9775390625, + 627.001953125, + 627.05078125, + 627.099609375, + 627.1484375, + 627.1728515625, + 627.1728515625, + 627.197265625, + 627.2216796875, + 627.294921875, + 627.3681640625, + 627.392578125, + 627.5146484375, + 627.5634765625, + 627.5634765625, + 627.587890625, + 627.587890625, + 627.63671875, + 627.685546875, + 627.7587890625, + 627.83203125, + 627.83203125, + 627.880859375, + 627.9296875, + 627.9541015625, + 628.0029296875, + 628.2470703125, + 628.3203125, + 628.3447265625, + 628.369140625, + 628.515625, + 628.6865234375, + 628.7353515625, + 628.8818359375, + 628.955078125, + 629.1259765625, + 629.39453125, + 629.4189453125, + 629.443359375, + 629.5166015625, + 629.5654296875, + 629.6875, + 629.736328125, + 629.9560546875, + 630.0537109375, + 630.1513671875, + 630.2734375, + 630.2978515625, + 630.517578125, + 630.6396484375, + 630.908203125, + 630.95703125, + 631.15234375, + 631.2744140625, + 631.5673828125, + 632.5927734375, + 633.49609375, + 633.740234375, + 633.9111328125, + 634.130859375, + 634.228515625, + 634.2529296875, + 634.47265625, + 634.6923828125, + 635.302734375, + 635.546875, + 636.0595703125, + 636.181640625, + 636.474609375, + 636.7431640625, + 637.1826171875, + 637.5244140625, + 637.9150390625, + 638.0126953125, + 638.623046875, + 638.8916015625, + 639.3310546875, + 639.35546875, + 639.501953125, + 639.7705078125, + 639.7705078125, + 639.9169921875, + 640.478515625, + 640.72265625, + 640.8203125, + 641.259765625, + 641.5771484375, + 641.7236328125, + 641.7236328125, + 641.8212890625, + 642.041015625, + 642.0654296875, + 642.138671875, + 642.2607421875, + 642.6513671875, + 643.06640625, + 643.1396484375, + 643.26171875, + 643.7744140625, + 643.8720703125, + 644.1162109375, + 644.287109375, + 644.384765625, + 644.4580078125, + 644.4580078125, + 644.6044921875, + 644.62890625, + 644.9951171875, + 645.01953125, + 645.068359375, + 645.1171875, + 645.1904296875, + 645.2392578125, + 645.263671875, + 645.41015625, + 645.556640625, + 645.654296875, + 645.6787109375, + 645.703125, + 645.7763671875, + 645.8740234375, + 646.0693359375, + 646.4111328125, + 646.5087890625, + 646.8017578125, + 646.826171875, + 647.0703125, + 647.119140625, + 647.314453125, + 647.4365234375, + 647.5830078125, + 647.802734375, + 647.900390625, + 647.94921875, + 647.94921875, + 648.0224609375, + 648.388671875, + 649.2431640625, + 649.5361328125, + 650.0244140625, + 650.8544921875, + 651.26953125, + 651.4892578125, + 651.85546875, + 653.3447265625, + 653.4423828125, + 654.1748046875, + 654.8583984375, + 654.8828125, + 655.1025390625, + 655.37109375, + 655.5908203125, + 656.54296875, + 657.1533203125, + 657.7880859375, + 658.4716796875, + 658.5693359375, + 658.7890625, + 662.451171875, + 662.548828125, + 666.11328125, + 677.9296875, + 679.1259765625, + 680.4443359375, + 712.451171875 + ], + "min": 609.9209474406362, + "max": 650.8443898168103, + "p25": 624.4873046875, + "p50": 629.5051179108796, + "p75": 643.26171875, + "p99": 677.9296875, + "p999": 680.4443359375, + "avg": 629.5051179108796, + "ticks": 1097728, + "heap": { + "_": 203, + "total": 854270.408203125, + "min": 3589.533203125, + "max": 4742.5078125, + "avg": 4207.843237762359 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 634.1243914703824, + 635.2743884597378, + 626.7015070053044, + 630.1502821180555, + 641.4569206957547, + 630.0798430266203, + 632.8034813724347, + 628.2873083043982, + 641.2999336674528, + 630.9636566275558, + 626.7565512569188, + 623.142832102793, + 630.6625196038568, + 638.1835019678101, + 622.0352564102565, + 609.9209474406362, + 633.4199364505597, + 614.8522418478261, + 639.1627261513158, + 642.1777898615056, + 624.0092558019302, + 626.3978176891144, + 626.0149403251845, + 618.0063032670455, + 624.1291719324448, + 624.835833381204, + 621.9308035714286, + 626.8080820456642, + 630.5212992274628, + 639.483045993891, + 626.594301343404, + 627.2487063249539, + 641.0682303950472, + 628.9303927951389, + 618.1387606534091, + 631.8431981877324, + 650.8443898168103, + 645.5925655002377 + ], + "rsdPercent": 1.3783120810121188 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 3, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 247.6318359375, + 247.65625, + 247.705078125, + 247.8271484375, + 247.9248046875, + 248.3154296875, + 248.3642578125, + 248.5107421875, + 248.5595703125, + 248.5595703125, + 248.583984375, + 248.6572265625, + 248.681640625, + 248.681640625, + 248.7060546875, + 248.7060546875, + 248.73046875, + 248.779296875, + 248.779296875, + 248.779296875, + 248.828125, + 248.828125, + 248.92578125, + 248.974609375, + 248.9990234375, + 249.0234375, + 249.0234375, + 249.072265625, + 249.072265625, + 249.12109375, + 249.1455078125, + 249.1455078125, + 249.1943359375, + 249.1943359375, + 249.21875, + 249.2431640625, + 249.2431640625, + 249.267578125, + 249.31640625, + 249.3408203125, + 249.365234375, + 249.3896484375, + 249.3896484375, + 249.3896484375, + 249.4140625, + 249.4140625, + 249.4384765625, + 249.4384765625, + 249.4873046875, + 249.51171875, + 249.51171875, + 249.5361328125, + 249.5361328125, + 249.5361328125, + 249.560546875, + 249.5849609375, + 249.609375, + 249.6337890625, + 249.6337890625, + 249.6337890625, + 249.6826171875, + 249.70703125, + 249.7314453125, + 249.7314453125, + 249.7802734375, + 249.7802734375, + 249.7802734375, + 249.853515625, + 249.8779296875, + 249.90234375, + 249.9267578125, + 249.951171875, + 249.9755859375, + 250, + 250, + 250, + 250, + 250.048828125, + 250.0732421875, + 250.0732421875, + 250.09765625, + 250.1220703125, + 250.1220703125, + 250.1220703125, + 250.1220703125, + 250.1220703125, + 250.146484375, + 250.1953125, + 250.1953125, + 250.1953125, + 250.2197265625, + 250.2197265625, + 250.244140625, + 250.244140625, + 250.244140625, + 250.244140625, + 250.29296875, + 250.29296875, + 250.3173828125, + 250.3173828125, + 250.3173828125, + 250.341796875, + 250.3662109375, + 250.390625, + 250.4150390625, + 250.4150390625, + 250.4150390625, + 250.4150390625, + 250.439453125, + 250.439453125, + 250.4638671875, + 250.4638671875, + 250.5126953125, + 250.537109375, + 250.5615234375, + 250.5615234375, + 250.5615234375, + 250.5859375, + 250.6103515625, + 250.68359375, + 250.68359375, + 250.68359375, + 250.68359375, + 250.7080078125, + 250.732421875, + 250.732421875, + 250.7568359375, + 250.78125, + 250.78125, + 250.78125, + 250.8056640625, + 250.8056640625, + 250.8056640625, + 250.8056640625, + 250.830078125, + 250.830078125, + 250.830078125, + 250.8544921875, + 250.9033203125, + 250.9033203125, + 250.9033203125, + 250.927734375, + 250.927734375, + 250.927734375, + 250.9521484375, + 250.9765625, + 250.9765625, + 251.0009765625, + 251.0498046875, + 251.07421875, + 251.07421875, + 251.0986328125, + 251.0986328125, + 251.123046875, + 251.123046875, + 251.1474609375, + 251.1474609375, + 251.171875, + 251.171875, + 251.1962890625, + 251.1962890625, + 251.220703125, + 251.2451171875, + 251.2451171875, + 251.2451171875, + 251.26953125, + 251.26953125, + 251.26953125, + 251.2939453125, + 251.2939453125, + 251.318359375, + 251.318359375, + 251.3427734375, + 251.3427734375, + 251.3671875, + 251.3916015625, + 251.416015625, + 251.416015625, + 251.4404296875, + 251.4404296875, + 251.4404296875, + 251.46484375, + 251.4892578125, + 251.5625, + 251.5625, + 251.5625, + 251.5625, + 251.5869140625, + 251.5869140625, + 251.5869140625, + 251.5869140625, + 251.611328125, + 251.6357421875, + 251.6357421875, + 251.6357421875, + 251.66015625, + 251.66015625, + 251.6845703125, + 251.708984375, + 251.7333984375, + 251.7333984375, + 251.7333984375, + 251.7333984375, + 251.7578125, + 251.7578125, + 251.7822265625, + 251.806640625, + 251.806640625, + 251.806640625, + 251.8310546875, + 251.8310546875, + 251.85546875, + 251.85546875, + 251.8798828125, + 251.8798828125, + 251.8798828125, + 251.904296875, + 251.904296875, + 251.904296875, + 251.904296875, + 251.9287109375, + 251.9287109375, + 251.9775390625, + 252.001953125, + 252.001953125, + 252.001953125, + 252.05078125, + 252.05078125, + 252.05078125, + 252.05078125, + 252.0751953125, + 252.0751953125, + 252.099609375, + 252.099609375, + 252.099609375, + 252.099609375, + 252.1240234375, + 252.1240234375, + 252.1484375, + 252.1728515625, + 252.1728515625, + 252.197265625, + 252.197265625, + 252.197265625, + 252.197265625, + 252.2216796875, + 252.24609375, + 252.24609375, + 252.24609375, + 252.2705078125, + 252.2705078125, + 252.294921875, + 252.3193359375, + 252.34375, + 252.3681640625, + 252.3681640625, + 252.392578125, + 252.4169921875, + 252.4169921875, + 252.4169921875, + 252.4169921875, + 252.4169921875, + 252.44140625, + 252.4658203125, + 252.5146484375, + 252.5146484375, + 252.5390625, + 252.6123046875, + 252.63671875, + 252.6611328125, + 252.7099609375, + 252.734375, + 252.7587890625, + 252.783203125, + 252.8076171875, + 252.83203125, + 252.83203125, + 252.83203125, + 252.83203125, + 252.8564453125, + 252.880859375, + 252.9052734375, + 252.9296875, + 252.9296875, + 252.978515625, + 252.978515625, + 253.0029296875, + 253.0029296875, + 253.0029296875, + 253.0029296875, + 253.02734375, + 253.076171875, + 253.076171875, + 253.1494140625, + 253.1982421875, + 253.22265625, + 253.22265625, + 253.22265625, + 253.2470703125, + 253.271484375, + 253.271484375, + 253.271484375, + 253.271484375, + 253.2958984375, + 253.3203125, + 253.3203125, + 253.3447265625, + 253.369140625, + 253.369140625, + 253.41796875, + 253.466796875, + 253.4912109375, + 253.4912109375, + 253.4912109375, + 253.4912109375, + 253.4912109375, + 253.515625, + 253.515625, + 253.515625, + 253.515625, + 253.5400390625, + 253.5400390625, + 253.5400390625, + 253.564453125, + 253.564453125, + 253.5888671875, + 253.5888671875, + 253.6376953125, + 253.662109375, + 253.662109375, + 253.7109375, + 253.7109375, + 253.7109375, + 253.7353515625, + 253.759765625, + 253.759765625, + 253.80859375, + 253.80859375, + 253.8330078125, + 253.8330078125, + 253.8330078125, + 253.857421875, + 253.857421875, + 253.8818359375, + 253.8818359375, + 253.8818359375, + 253.9306640625, + 253.9306640625, + 253.955078125, + 253.955078125, + 253.9794921875, + 254.00390625, + 254.00390625, + 254.0283203125, + 254.052734375, + 254.0771484375, + 254.0771484375, + 254.1015625, + 254.1259765625, + 254.1259765625, + 254.150390625, + 254.150390625, + 254.150390625, + 254.150390625, + 254.1748046875, + 254.19921875, + 254.2236328125, + 254.248046875, + 254.248046875, + 254.2724609375, + 254.2724609375, + 254.3212890625, + 254.345703125, + 254.3701171875, + 254.39453125, + 254.39453125, + 254.443359375, + 254.443359375, + 254.4921875, + 254.5166015625, + 254.5166015625, + 254.5654296875, + 254.5654296875, + 254.6142578125, + 254.6630859375, + 254.6630859375, + 254.6875, + 254.6875, + 254.7607421875, + 254.8095703125, + 254.833984375, + 254.833984375, + 254.8583984375, + 254.8828125, + 254.9072265625, + 254.931640625, + 254.931640625, + 254.9560546875, + 254.9560546875, + 254.9560546875, + 254.9560546875, + 254.98046875, + 254.98046875, + 255.0048828125, + 255.0048828125, + 255.0048828125, + 255.029296875, + 255.029296875, + 255.0537109375, + 255.0537109375, + 255.078125, + 255.078125, + 255.1025390625, + 255.1025390625, + 255.1025390625, + 255.17578125, + 255.2001953125, + 255.224609375, + 255.2490234375, + 255.2490234375, + 255.2978515625, + 255.2978515625, + 255.2978515625, + 255.37109375, + 255.37109375, + 255.37109375, + 255.3955078125, + 255.3955078125, + 255.4443359375, + 255.46875, + 255.4931640625, + 255.517578125, + 255.517578125, + 255.5419921875, + 255.5908203125, + 255.615234375, + 255.615234375, + 255.615234375, + 255.6396484375, + 255.6640625, + 255.6640625, + 255.6640625, + 255.712890625, + 255.7373046875, + 255.7373046875, + 255.7861328125, + 255.859375, + 255.8837890625, + 255.8837890625, + 255.8837890625, + 255.908203125, + 255.9326171875, + 255.9814453125, + 256.005859375, + 256.0546875, + 256.1279296875, + 256.1279296875, + 256.1767578125, + 256.3232421875, + 256.3720703125, + 256.3720703125, + 256.4208984375, + 256.494140625, + 256.54296875, + 256.5673828125, + 256.5673828125, + 256.5673828125, + 256.6162109375, + 256.689453125, + 256.689453125, + 256.689453125, + 256.7138671875, + 256.7626953125, + 256.8115234375, + 256.8359375, + 256.8603515625, + 256.884765625, + 256.884765625, + 256.9091796875, + 256.93359375, + 256.982421875, + 256.982421875, + 256.982421875, + 257.03125, + 257.0556640625, + 257.080078125, + 257.080078125, + 257.2265625, + 257.275390625, + 257.2998046875, + 257.3486328125, + 257.3486328125, + 257.373046875, + 257.4462890625, + 257.4951171875, + 257.51953125, + 257.568359375, + 257.5927734375, + 257.6171875, + 257.6416015625, + 257.666015625, + 257.7880859375, + 257.8125, + 257.8857421875, + 257.958984375, + 258.0078125, + 258.0322265625, + 258.056640625, + 258.1298828125, + 258.154296875, + 258.1787109375, + 258.251953125, + 258.5693359375, + 258.59375, + 258.7890625, + 258.7890625, + 258.8134765625, + 259.1064453125, + 259.228515625, + 259.326171875, + 259.375, + 259.912109375, + 260.0341796875, + 260.107421875, + 260.400390625, + 260.6201171875, + 260.64453125, + 260.6689453125, + 260.7666015625, + 261.328125, + 261.4501953125, + 262.20703125, + 262.255859375, + 262.3779296875, + 262.5244140625, + 262.548828125, + 262.6953125, + 263.0859375, + 263.3544921875, + 263.3544921875, + 263.4765625, + 263.6962890625, + 263.916015625, + 264.013671875, + 264.501953125, + 264.8193359375, + 264.892578125, + 264.94140625, + 265.0390625, + 265.1123046875, + 265.185546875, + 265.234375, + 265.380859375, + 265.478515625, + 265.5517578125, + 265.673828125, + 265.6982421875, + 265.72265625, + 265.7958984375, + 265.9423828125, + 265.9423828125, + 265.9423828125, + 265.966796875, + 265.966796875, + 266.259765625, + 266.30859375, + 266.3818359375, + 266.4306640625, + 266.69921875, + 266.748046875, + 266.796875, + 266.845703125, + 266.943359375, + 266.9677734375, + 266.9677734375, + 267.041015625, + 267.1630859375, + 267.236328125, + 267.3583984375, + 267.724609375, + 267.7978515625, + 267.9931640625, + 267.9931640625, + 268.06640625, + 268.0908203125, + 268.1396484375, + 268.1884765625, + 268.26171875, + 268.408203125, + 268.408203125, + 268.603515625, + 268.6279296875, + 268.6279296875, + 268.6279296875, + 268.7255859375, + 268.9697265625, + 269.091796875, + 269.3359375, + 269.43359375, + 269.7265625, + 269.873046875, + 269.8974609375, + 270.1904296875, + 270.1904296875, + 270.2880859375, + 270.2880859375, + 270.556640625, + 270.5810546875, + 270.5810546875, + 270.7763671875, + 270.9228515625, + 270.9716796875, + 271.0205078125, + 271.4599609375, + 271.7529296875, + 271.8017578125, + 271.9482421875, + 271.9482421875, + 272.021484375, + 272.0458984375, + 272.16796875, + 272.1923828125, + 272.314453125, + 272.4609375, + 272.802734375, + 273.92578125, + 274.3896484375, + 274.4873046875, + 274.5361328125, + 275.0732421875, + 275.439453125, + 275.9033203125, + 275.927734375, + 276.5380859375, + 277.0751953125, + 277.44140625, + 277.9541015625, + 280.17578125, + 282.7880859375, + 284.5947265625, + 395.5810546875, + 395.80078125, + 398.486328125, + 399.31640625, + 399.4140625, + 400.1220703125, + 401.3671875, + 401.6357421875, + 404.6142578125, + 406.8603515625, + 411.3525390625, + 423.73046875, + 432.373046875, + 432.861328125, + 433.2763671875, + 445.5078125, + 447.75390625, + 448.92578125 + ], + "min": 244.65545086731044, + "max": 276.0939393174475, + "p25": 251.2451171875, + "p50": 253.64036923746974, + "p75": 257.373046875, + "p99": 411.3525390625, + "p999": 447.75390625, + "avg": 253.64036923746974, + "ticks": 2695168, + "heap": { + "_": 590, + "total": 1055290.65234375, + "min": 1402.197265625, + "max": 2287.9765625, + "avg": 1788.568787324711 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 260.05403002707067, + 252.02065019790132, + 253.30298755787038, + 253.9777509170691, + 265.87867084224337, + 252.43470858683628, + 261.3495526328364, + 247.99269633300074, + 244.67015518821532, + 249.5921960538321, + 245.41061160554162, + 250.4735541727672, + 247.14066169165463, + 274.03067564352966, + 254.4245402018229, + 252.32171252765488, + 251.29635081571692, + 257.6610519225339, + 260.2722632467656, + 261.07932520276717, + 251.06590147760647, + 258.08226986708144, + 273.77049372746393, + 276.0939393174475, + 244.65545086731044, + 261.23162599149464, + 254.27674793061755, + 265.08251574612405, + 260.49912451246195, + 251.21306700853523, + 248.53799509447674, + 266.88763741955927, + 248.58348757721657, + 271.55187270220586, + 261.64151346282495, + 252.17465200958702, + 252.15463103797936, + 251.8091575386598 + ], + "rsdPercent": 3.283195698211891 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 5, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 312700, + 314100, + 314200, + 314200, + 314400, + 314600, + 314600, + 314600, + 314900, + 315000, + 315100, + 315100, + 315100, + 315200, + 315200, + 315300, + 315300, + 315500, + 315600, + 315600, + 315600, + 315700, + 315800, + 315900, + 315900, + 316000, + 316100, + 316200, + 316200, + 316200, + 316400, + 316400, + 316600, + 316700, + 316800, + 316800, + 316900, + 316900, + 317000, + 317000, + 317100, + 317100, + 317100, + 317100, + 317400, + 317400, + 317500, + 317600, + 317600, + 317800, + 317800, + 317800, + 317800, + 317800, + 317900, + 317900, + 318000, + 318000, + 318000, + 318100, + 318100, + 318100, + 318100, + 318100, + 318100, + 318100, + 318100, + 318100, + 318200, + 318200, + 318300, + 318300, + 318400, + 318400, + 318400, + 318400, + 318400, + 318400, + 318400, + 318400, + 318400, + 318400, + 318400, + 318500, + 318500, + 318500, + 318600, + 318600, + 318600, + 318600, + 318600, + 318600, + 318700, + 318700, + 318700, + 318700, + 318700, + 318700, + 318700, + 318800, + 318800, + 318800, + 318800, + 318800, + 318900, + 318900, + 318900, + 318900, + 318900, + 318900, + 319000, + 319000, + 319000, + 319000, + 319000, + 319100, + 319100, + 319100, + 319100, + 319100, + 319100, + 319100, + 319100, + 319100, + 319200, + 319200, + 319200, + 319200, + 319200, + 319200, + 319200, + 319300, + 319300, + 319300, + 319300, + 319300, + 319300, + 319300, + 319400, + 319400, + 319400, + 319400, + 319400, + 319400, + 319400, + 319400, + 319400, + 319400, + 319400, + 319500, + 319500, + 319500, + 319500, + 319500, + 319500, + 319600, + 319600, + 319600, + 319600, + 319600, + 319700, + 319700, + 319700, + 319700, + 319700, + 319800, + 319800, + 319800, + 319800, + 319800, + 319800, + 319800, + 319800, + 319800, + 319800, + 319900, + 319900, + 319900, + 319900, + 319900, + 319900, + 319900, + 319900, + 319900, + 319900, + 319900, + 319900, + 319900, + 320000, + 320000, + 320000, + 320000, + 320000, + 320000, + 320000, + 320000, + 320000, + 320100, + 320100, + 320100, + 320100, + 320100, + 320100, + 320100, + 320100, + 320100, + 320100, + 320100, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320200, + 320300, + 320300, + 320300, + 320300, + 320300, + 320300, + 320300, + 320300, + 320400, + 320400, + 320400, + 320400, + 320400, + 320400, + 320400, + 320400, + 320400, + 320400, + 320400, + 320400, + 320500, + 320500, + 320500, + 320500, + 320500, + 320500, + 320500, + 320500, + 320500, + 320500, + 320600, + 320600, + 320600, + 320600, + 320600, + 320600, + 320600, + 320600, + 320600, + 320700, + 320700, + 320700, + 320700, + 320700, + 320700, + 320700, + 320700, + 320700, + 320700, + 320700, + 320800, + 320800, + 320800, + 320800, + 320800, + 320800, + 320800, + 320800, + 320800, + 320800, + 320900, + 320900, + 320900, + 320900, + 320900, + 320900, + 320900, + 320900, + 321000, + 321000, + 321000, + 321000, + 321000, + 321000, + 321000, + 321000, + 321000, + 321000, + 321000, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321500, + 321500, + 321500, + 321500, + 321500, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321700, + 321800, + 321800, + 321800, + 321800, + 321800, + 321800, + 321800, + 321800, + 321800, + 321800, + 321800, + 321800, + 321900, + 321900, + 321900, + 321900, + 321900, + 321900, + 321900, + 321900, + 321900, + 321900, + 321900, + 321900, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322200, + 322200, + 322200, + 322200, + 322200, + 322200, + 322200, + 322200, + 322200, + 322200, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323100, + 323100, + 323100, + 323100, + 323100, + 323100, + 323100, + 323100, + 323100, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324300, + 324300, + 324300, + 324300, + 324300, + 324300, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324500, + 324500, + 324500, + 324500, + 324500, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324700, + 324700, + 324700, + 324700, + 324700, + 324700, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 325000, + 325000, + 325000, + 325000, + 325000, + 325100, + 325100, + 325100, + 325100, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325300, + 325300, + 325300, + 325300, + 325300, + 325300, + 325300, + 325300, + 325400, + 325400, + 325400, + 325400, + 325400, + 325400, + 325400, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325600, + 325600, + 325600, + 325600, + 325600, + 325700, + 325700, + 325700, + 325700, + 325700, + 325700, + 325700, + 325700, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325900, + 325900, + 325900, + 325900, + 325900, + 325900, + 325900, + 325900, + 325900, + 326000, + 326000, + 326000, + 326000, + 326100, + 326100, + 326100, + 326100, + 326100, + 326100, + 326100, + 326100, + 326200, + 326200, + 326200, + 326200, + 326200, + 326200, + 326200, + 326300, + 326300, + 326300, + 326300, + 326400, + 326400, + 326400, + 326500, + 326500, + 326500, + 326500, + 326500, + 326500, + 326500, + 326500, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326800, + 326800, + 326800, + 326800, + 326800, + 326900, + 326900, + 326900, + 326900, + 326900, + 326900, + 326900, + 326900, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327100, + 327100, + 327100, + 327100, + 327100, + 327100, + 327100, + 327200, + 327200, + 327200, + 327300, + 327300, + 327300, + 327300, + 327300, + 327300, + 327300, + 327400, + 327400, + 327400, + 327400, + 327400, + 327400, + 327400, + 327400, + 327500, + 327500, + 327500, + 327500, + 327500, + 327600, + 327600, + 327600, + 327700, + 327700, + 327700, + 327700, + 327700, + 327700, + 327800, + 327800, + 327800, + 327800, + 327800, + 327800, + 327800, + 327800, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 328000, + 328000, + 328000, + 328000, + 328000, + 328000, + 328100, + 328100, + 328100, + 328100, + 328100, + 328100, + 328100, + 328100, + 328100, + 328200, + 328200, + 328200, + 328200, + 328300, + 328300, + 328300, + 328300, + 328300, + 328300, + 328300, + 328400, + 328400, + 328400, + 328400, + 328400, + 328400, + 328400, + 328400, + 328500, + 328500, + 328500, + 328600, + 328600, + 328600, + 328700, + 328700, + 328700, + 328700, + 328700, + 328700, + 328700, + 328800, + 328800, + 328900, + 328900, + 328900, + 328900, + 328900, + 329000, + 329000, + 329000, + 329000, + 329000, + 329000, + 329000, + 329100, + 329100, + 329100, + 329100, + 329100, + 329100, + 329100, + 329200, + 329200, + 329200, + 329200, + 329200, + 329200, + 329300, + 329300, + 329300, + 329300, + 329300, + 329300, + 329300, + 329400, + 329400, + 329400, + 329400, + 329500, + 329500, + 329500, + 329500, + 329600, + 329600, + 329600, + 329600, + 329600, + 329700, + 329700, + 329700, + 329700, + 329700, + 329800, + 329800, + 329900, + 329900, + 329900, + 329900, + 329900, + 329900, + 329900, + 329900, + 330000, + 330000, + 330000, + 330000, + 330100, + 330100, + 330100, + 330200, + 330200, + 330200, + 330200, + 330200, + 330200, + 330300, + 330300, + 330300, + 330300, + 330300, + 330400, + 330400, + 330400, + 330400, + 330400, + 330400, + 330400, + 330400, + 330500, + 330500, + 330500, + 330500, + 330500, + 330500, + 330500, + 330600, + 330600, + 330700, + 330700, + 330800, + 330800, + 330800, + 330800, + 330800, + 330800, + 330800, + 330800, + 330800, + 330900, + 330900, + 331000, + 331000, + 331000, + 331000, + 331100, + 331100, + 331100, + 331100, + 331100, + 331100, + 331100, + 331100, + 331100, + 331100, + 331200, + 331200, + 331200, + 331200, + 331200, + 331200, + 331200, + 331200, + 331200, + 331300, + 331300, + 331400, + 331400, + 331400, + 331400, + 331400, + 331400, + 331400, + 331400, + 331400, + 331400, + 331500, + 331500, + 331500, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331700, + 331700, + 331700, + 331700, + 331700, + 331700, + 331700, + 331700, + 331700, + 331700, + 331800, + 331800, + 331800, + 331800, + 331800, + 331800, + 331800, + 331900, + 331900, + 331900, + 332000, + 332000, + 332000, + 332000, + 332000, + 332000, + 332000, + 332000, + 332100, + 332100, + 332100, + 332200, + 332200, + 332200, + 332200, + 332200, + 332200, + 332200, + 332200, + 332200, + 332300, + 332300, + 332300, + 332300, + 332300, + 332400, + 332400, + 332400, + 332400, + 332500, + 332500, + 332500, + 332500, + 332500, + 332500, + 332500, + 332500, + 332500, + 332500, + 332500, + 332500, + 332500, + 332600, + 332600, + 332600, + 332600, + 332600, + 332600, + 332600, + 332600, + 332600, + 332600, + 332700, + 332700, + 332700, + 332700, + 332700, + 332700, + 332700, + 332700, + 332700, + 332700, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332900, + 332900, + 332900, + 332900, + 332900, + 333000, + 333000, + 333000, + 333000, + 333000, + 333000, + 333000, + 333000, + 333000, + 333100, + 333100, + 333100, + 333100, + 333100, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333300, + 333300, + 333300, + 333300, + 333300, + 333300, + 333300, + 333300, + 333400, + 333400, + 333400, + 333500, + 333500, + 333500, + 333500, + 333500, + 333500, + 333500, + 333500, + 333500, + 333500, + 333600, + 333600, + 333600, + 333600, + 333700, + 333700, + 333700, + 333700, + 333700, + 333700, + 333800, + 333800, + 333800, + 333800, + 333900, + 333900, + 333900, + 333900, + 333900, + 333900, + 333900, + 333900, + 333900, + 333900, + 333900, + 334000, + 334000, + 334000, + 334000, + 334000, + 334000, + 334100, + 334100, + 334100, + 334100, + 334100, + 334200, + 334200, + 334200, + 334200, + 334200, + 334300, + 334300, + 334300, + 334300, + 334300, + 334300, + 334400, + 334400, + 334400, + 334400, + 334400, + 334400, + 334400, + 334500, + 334500, + 334500, + 334500, + 334600, + 334600, + 334600, + 334600, + 334600, + 334700, + 334700, + 334700, + 334700, + 334800, + 334800, + 334800, + 334800, + 334800, + 334800, + 334900, + 334900, + 334900, + 334900, + 334900, + 335000, + 335000, + 335000, + 335000, + 335000, + 335000, + 335000, + 335000, + 335000, + 335000, + 335000, + 335000, + 335100, + 335100, + 335100, + 335100, + 335100, + 335100, + 335200, + 335200, + 335200, + 335200, + 335200, + 335200, + 335200, + 335300, + 335300, + 335300, + 335300, + 335300, + 335300, + 335300, + 335400, + 335400, + 335500, + 335500, + 335500, + 335600, + 335600, + 335700, + 335700, + 335800, + 335800, + 335800, + 335800, + 335800, + 335800, + 335800, + 335900, + 335900, + 335900, + 335900, + 336000, + 336000, + 336100, + 336100, + 336100, + 336100, + 336100, + 336100, + 336200, + 336200, + 336200, + 336300, + 336300, + 336300, + 336400, + 336400, + 336400, + 336400, + 336400, + 336400, + 336400, + 336500, + 336700, + 336700, + 336700, + 336800, + 336900, + 336900, + 336900, + 337000, + 337100, + 337100, + 337200, + 337200, + 337200, + 337300, + 337400, + 337500, + 337500, + 337500, + 337600, + 337600, + 337600, + 337700, + 337700, + 337800, + 337800, + 337800, + 337800, + 337900, + 337900, + 338000, + 338000, + 338100, + 338100, + 338100, + 338100, + 338100, + 338200, + 338400, + 338400, + 338400, + 338500, + 338500, + 338500, + 338600, + 338600, + 338700, + 338700, + 338700, + 338700, + 338800, + 338800, + 338800, + 339000, + 339100, + 339100, + 339200, + 339200, + 339200, + 339300, + 339500, + 339500, + 339500, + 339500, + 339600, + 339600, + 339700, + 339700, + 339700, + 339700, + 339800, + 339900, + 339900, + 339900, + 340100, + 340200, + 340200, + 340400, + 340400, + 340400, + 340400, + 340600, + 340600, + 340700, + 340900, + 340900, + 341000, + 341200, + 341200, + 341300, + 341400, + 341400, + 341700, + 342100, + 342200, + 342300, + 342400, + 342600, + 342700, + 342800, + 343000, + 343000, + 343200, + 343300, + 343300, + 343400, + 343500, + 343600, + 343600, + 343700, + 343900, + 343900, + 344300, + 344500, + 344500, + 344700, + 344700, + 345000, + 345400, + 345400, + 345600, + 345700, + 346000, + 346000, + 346400, + 346500, + 347000, + 347000, + 347200, + 347300, + 347300, + 347600, + 347900, + 348000, + 348400, + 348700, + 348900, + 349400, + 349700, + 349800, + 350100, + 350200, + 350600, + 350700, + 350800, + 350900, + 350900, + 351200, + 351300, + 352100, + 352300, + 352300, + 352300, + 352700, + 352900, + 352900, + 352900, + 352900, + 352900, + 353000, + 353200, + 353500, + 353700, + 354600, + 354600, + 354600, + 355500, + 355900, + 356200, + 356300, + 356600, + 356700, + 356900, + 357100, + 357200, + 357400, + 357500, + 358000, + 358500, + 358500, + 358600, + 359100, + 359200, + 359700, + 359800, + 360100, + 360300, + 360300, + 360800, + 360800, + 361200, + 361300, + 361400, + 361600, + 361800, + 362200, + 362200, + 362500, + 362500, + 362600, + 363000, + 363400, + 363700, + 364100, + 364200, + 364300, + 364300, + 364400, + 364400, + 364500, + 364600, + 364600, + 364700, + 365000, + 365400, + 365400, + 365500, + 366000, + 366100, + 366100, + 366200, + 366200, + 366400, + 366500, + 366500, + 366600, + 366800, + 367100, + 367100, + 367300, + 367300, + 367400, + 367400, + 367400, + 367600, + 367600, + 367700, + 367800, + 367900, + 368000, + 368100, + 368400, + 368500, + 368500, + 368600, + 368700, + 368800, + 368900, + 369000, + 369100, + 369300, + 369400, + 369400, + 369500, + 369600, + 369800, + 369800, + 370300, + 370500, + 370500, + 370900, + 371000, + 371000, + 371200, + 371500, + 371500, + 371700, + 371700, + 371900, + 372100, + 372100, + 372500, + 372800, + 372800, + 372800, + 372900, + 372900, + 373100, + 373300, + 373400, + 374000, + 374100, + 374300, + 374500, + 374600, + 374600, + 374600, + 374700, + 375000, + 375000, + 375800, + 376200, + 376200, + 376300, + 376900, + 377000, + 377100, + 377200, + 377200, + 377400, + 377400, + 377800, + 378400, + 378700, + 378700, + 378800, + 379200, + 379200, + 379300, + 379800, + 379900, + 379900, + 380200, + 380200, + 380300, + 380400, + 380500, + 381500, + 381600, + 381800, + 382000, + 382700, + 382700, + 383000, + 383300, + 383500, + 383900, + 385200, + 385800, + 386500, + 386600, + 386900, + 387000, + 387900, + 388400, + 388500, + 388700, + 390200, + 390700, + 390800, + 390900, + 391000, + 392000, + 392800, + 392900, + 393200, + 393600, + 395800, + 395900, + 396100, + 396500, + 397500, + 398400, + 398800, + 399100, + 400300, + 401700, + 402000, + 402100, + 406300, + 406600, + 407600, + 408500, + 408900, + 409200, + 414000, + 414500, + 414700, + 414700, + 414900, + 415300, + 416000, + 416200, + 418200, + 424000, + 424200, + 424500, + 426000, + 429200, + 429600, + 430800, + 431000, + 431500, + 431600, + 438000, + 438800, + 439300, + 444400, + 447900, + 450300, + 457300, + 466100, + 478100, + 486500, + 487100, + 489200, + 491200, + 509900, + 562100, + 733700, + 891900, + 1030700, + 1040900, + 1041200, + 1044900, + 1045400, + 1051100, + 1051600, + 1051900, + 1054000, + 1055700, + 1056800, + 1057000, + 1059400, + 1066000, + 1071200, + 1102000, + 1103600, + 1105500, + 1113000, + 1116300, + 1117900, + 1122400, + 1122900, + 1123100, + 1125800, + 1128600, + 1129500, + 1131600, + 1135200, + 1136500, + 1138600, + 1140300, + 1155500, + 1170600, + 1186600, + 1201800, + 1232900, + 1244800, + 1246400, + 1249800, + 1253400, + 1255900, + 1256200, + 1260500, + 1264000, + 1271900, + 1276000, + 1276900, + 1282500, + 1293000, + 1302100, + 1317400, + 1330100, + 1404900 + ], + "min": 352404.5682730924, + "max": 441995.40880503145, + "p25": 322400, + "p50": 355768.3437486185, + "p75": 335500, + "p99": 1170600, + "p999": 1317400, + "avg": 355768.3437486185, + "ticks": 1963, + "heap": { + "_": 1911, + "total": 4049138576, + "min": 1228704, + "max": 2840888, + "avg": 2118795.4422914665 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 357521.7524197657, + 356539.01572805684, + 418565.23553965415, + 356425.62151192286, + 356398.730964467, + 356902.1860701576, + 354601.7685699848, + 354455.4265522463, + 354635.77564426477, + 355784.43204868154, + 356443.5819381025, + 354175.6306760848, + 358219.64285714284, + 354908.2406471183, + 354727.7918140475, + 356086.5550481989, + 355300.91093117406, + 354682.0707070707, + 356996.03255340795, + 354003.8325769037, + 353792.5907258064, + 362829.7157622739, + 353134.6250629089, + 356312.2842639594, + 354616.32137443154, + 441995.40880503145, + 355269.9898785425, + 357756.93170234456, + 362381.2596799174, + 360199.4869163674, + 355118.5128983308, + 356217.80821917806, + 352404.5682730924, + 359008.7468030691, + 354098.13414019166, + 353858.5685483871, + 355474.6835443038, + 355752.2554485555 + ], + "rsdPercent": 4.769475744740417 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 5, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 315900, + 316000, + 316500, + 316600, + 316700, + 316800, + 317200, + 317700, + 317800, + 317900, + 317900, + 318000, + 318200, + 318200, + 318600, + 318600, + 318600, + 318700, + 318700, + 318900, + 318900, + 319000, + 319000, + 319000, + 319000, + 319200, + 319200, + 319200, + 319300, + 319400, + 319400, + 319400, + 319500, + 319500, + 319500, + 319500, + 319600, + 319600, + 319700, + 319700, + 319800, + 319900, + 319900, + 319900, + 320000, + 320000, + 320000, + 320000, + 320000, + 320000, + 320100, + 320100, + 320100, + 320100, + 320200, + 320300, + 320400, + 320400, + 320400, + 320400, + 320400, + 320500, + 320500, + 320500, + 320500, + 320600, + 320600, + 320600, + 320700, + 320700, + 320700, + 320700, + 320700, + 320700, + 320800, + 320800, + 320800, + 320800, + 320800, + 320900, + 320900, + 320900, + 321000, + 321000, + 321000, + 321000, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321100, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321200, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321300, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321400, + 321500, + 321500, + 321500, + 321500, + 321500, + 321500, + 321500, + 321500, + 321500, + 321500, + 321500, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321600, + 321700, + 321700, + 321700, + 321800, + 321800, + 321800, + 321800, + 321800, + 321800, + 321900, + 321900, + 321900, + 321900, + 321900, + 321900, + 321900, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322000, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322100, + 322200, + 322200, + 322200, + 322200, + 322200, + 322200, + 322200, + 322200, + 322200, + 322200, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322300, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322400, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322500, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322600, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322700, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322800, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 322900, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323000, + 323100, + 323100, + 323100, + 323100, + 323100, + 323100, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323200, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323300, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323400, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323500, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323600, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323700, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323800, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 323900, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324000, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324100, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324200, + 324300, + 324300, + 324300, + 324300, + 324300, + 324300, + 324300, + 324300, + 324300, + 324300, + 324300, + 324300, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324400, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324500, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324600, + 324700, + 324700, + 324700, + 324700, + 324700, + 324700, + 324700, + 324700, + 324700, + 324700, + 324700, + 324700, + 324700, + 324700, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324800, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 324900, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325000, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325100, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325200, + 325300, + 325300, + 325300, + 325300, + 325300, + 325300, + 325300, + 325300, + 325300, + 325400, + 325400, + 325400, + 325400, + 325400, + 325400, + 325400, + 325400, + 325400, + 325400, + 325400, + 325400, + 325400, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325500, + 325600, + 325600, + 325600, + 325600, + 325600, + 325600, + 325600, + 325600, + 325600, + 325600, + 325600, + 325600, + 325600, + 325700, + 325700, + 325700, + 325700, + 325700, + 325700, + 325700, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325800, + 325900, + 325900, + 325900, + 325900, + 325900, + 325900, + 325900, + 325900, + 325900, + 325900, + 325900, + 326000, + 326000, + 326000, + 326000, + 326000, + 326000, + 326000, + 326000, + 326000, + 326000, + 326000, + 326000, + 326000, + 326000, + 326100, + 326100, + 326100, + 326100, + 326100, + 326100, + 326100, + 326100, + 326100, + 326100, + 326200, + 326200, + 326200, + 326200, + 326200, + 326200, + 326200, + 326200, + 326200, + 326300, + 326300, + 326300, + 326300, + 326300, + 326300, + 326300, + 326300, + 326400, + 326400, + 326400, + 326400, + 326400, + 326400, + 326500, + 326500, + 326500, + 326500, + 326500, + 326500, + 326500, + 326500, + 326500, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326600, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326700, + 326800, + 326800, + 326800, + 326800, + 326800, + 326800, + 326800, + 326800, + 326800, + 326900, + 326900, + 326900, + 326900, + 326900, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327000, + 327100, + 327100, + 327100, + 327100, + 327100, + 327100, + 327100, + 327100, + 327100, + 327100, + 327100, + 327100, + 327100, + 327200, + 327200, + 327200, + 327200, + 327200, + 327200, + 327200, + 327200, + 327300, + 327300, + 327300, + 327300, + 327300, + 327300, + 327300, + 327300, + 327300, + 327400, + 327400, + 327400, + 327400, + 327400, + 327400, + 327400, + 327400, + 327500, + 327500, + 327500, + 327500, + 327500, + 327500, + 327600, + 327600, + 327600, + 327600, + 327600, + 327600, + 327600, + 327600, + 327600, + 327700, + 327700, + 327700, + 327700, + 327700, + 327700, + 327700, + 327700, + 327700, + 327700, + 327700, + 327700, + 327800, + 327800, + 327800, + 327800, + 327800, + 327800, + 327800, + 327800, + 327800, + 327800, + 327800, + 327800, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 327900, + 328000, + 328000, + 328000, + 328000, + 328000, + 328000, + 328000, + 328000, + 328100, + 328100, + 328100, + 328100, + 328100, + 328100, + 328200, + 328200, + 328200, + 328200, + 328200, + 328200, + 328300, + 328300, + 328300, + 328300, + 328300, + 328300, + 328300, + 328300, + 328400, + 328400, + 328400, + 328400, + 328400, + 328400, + 328400, + 328400, + 328400, + 328400, + 328400, + 328400, + 328500, + 328500, + 328500, + 328500, + 328500, + 328500, + 328500, + 328500, + 328600, + 328600, + 328600, + 328600, + 328600, + 328600, + 328600, + 328600, + 328600, + 328700, + 328700, + 328700, + 328700, + 328700, + 328700, + 328800, + 328800, + 328800, + 328800, + 328800, + 328800, + 328800, + 328800, + 328900, + 328900, + 328900, + 328900, + 329000, + 329000, + 329000, + 329000, + 329000, + 329000, + 329000, + 329100, + 329100, + 329100, + 329100, + 329100, + 329100, + 329100, + 329100, + 329100, + 329100, + 329100, + 329200, + 329200, + 329200, + 329200, + 329200, + 329200, + 329200, + 329200, + 329200, + 329300, + 329300, + 329300, + 329300, + 329300, + 329300, + 329300, + 329300, + 329300, + 329400, + 329400, + 329400, + 329400, + 329400, + 329400, + 329500, + 329500, + 329500, + 329500, + 329500, + 329500, + 329500, + 329500, + 329600, + 329600, + 329600, + 329600, + 329600, + 329600, + 329600, + 329600, + 329600, + 329700, + 329700, + 329700, + 329800, + 329800, + 329800, + 329800, + 329800, + 329900, + 329900, + 329900, + 329900, + 329900, + 329900, + 329900, + 329900, + 329900, + 330000, + 330000, + 330000, + 330000, + 330000, + 330000, + 330000, + 330100, + 330100, + 330100, + 330100, + 330100, + 330100, + 330200, + 330200, + 330200, + 330200, + 330200, + 330200, + 330300, + 330300, + 330300, + 330400, + 330400, + 330400, + 330400, + 330500, + 330500, + 330500, + 330500, + 330500, + 330500, + 330500, + 330600, + 330600, + 330600, + 330600, + 330600, + 330600, + 330600, + 330700, + 330700, + 330700, + 330800, + 330800, + 330800, + 330800, + 330800, + 330800, + 330900, + 330900, + 330900, + 330900, + 330900, + 331000, + 331000, + 331000, + 331000, + 331100, + 331100, + 331100, + 331100, + 331100, + 331200, + 331200, + 331200, + 331200, + 331200, + 331200, + 331200, + 331200, + 331300, + 331300, + 331300, + 331400, + 331400, + 331400, + 331400, + 331400, + 331400, + 331400, + 331400, + 331500, + 331500, + 331500, + 331500, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331600, + 331700, + 331700, + 331700, + 331700, + 331700, + 331700, + 331700, + 331700, + 331800, + 331800, + 331800, + 331800, + 331800, + 331800, + 331900, + 331900, + 331900, + 331900, + 331900, + 331900, + 332000, + 332000, + 332000, + 332000, + 332000, + 332100, + 332100, + 332100, + 332100, + 332200, + 332300, + 332300, + 332300, + 332300, + 332300, + 332300, + 332300, + 332300, + 332400, + 332400, + 332400, + 332400, + 332400, + 332500, + 332500, + 332500, + 332500, + 332500, + 332600, + 332600, + 332600, + 332600, + 332600, + 332600, + 332600, + 332700, + 332700, + 332700, + 332700, + 332700, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332800, + 332900, + 332900, + 332900, + 332900, + 332900, + 333000, + 333000, + 333000, + 333000, + 333000, + 333000, + 333000, + 333000, + 333100, + 333100, + 333100, + 333100, + 333100, + 333100, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333200, + 333300, + 333300, + 333400, + 333400, + 333400, + 333400, + 333400, + 333400, + 333400, + 333400, + 333400, + 333400, + 333500, + 333500, + 333500, + 333500, + 333500, + 333500, + 333500, + 333500, + 333500, + 333500, + 333600, + 333600, + 333600, + 333600, + 333600, + 333600, + 333600, + 333600, + 333600, + 333600, + 333600, + 333700, + 333700, + 333700, + 333700, + 333700, + 333700, + 333700, + 333700, + 333700, + 333700, + 333800, + 333800, + 333800, + 333800, + 333800, + 333900, + 333900, + 333900, + 333900, + 333900, + 334000, + 334000, + 334000, + 334000, + 334000, + 334000, + 334000, + 334000, + 334000, + 334100, + 334100, + 334100, + 334200, + 334200, + 334200, + 334200, + 334200, + 334200, + 334200, + 334200, + 334200, + 334200, + 334200, + 334300, + 334300, + 334300, + 334300, + 334300, + 334300, + 334300, + 334300, + 334300, + 334300, + 334400, + 334400, + 334400, + 334400, + 334400, + 334400, + 334400, + 334400, + 334400, + 334400, + 334400, + 334400, + 334400, + 334500, + 334500, + 334500, + 334500, + 334500, + 334500, + 334600, + 334600, + 334600, + 334700, + 334700, + 334700, + 334700, + 334700, + 334700, + 334700, + 334700, + 334700, + 334700, + 334800, + 334800, + 334800, + 334800, + 334900, + 334900, + 334900, + 334900, + 334900, + 334900, + 335000, + 335000, + 335000, + 335000, + 335100, + 335100, + 335100, + 335100, + 335100, + 335100, + 335200, + 335200, + 335200, + 335200, + 335200, + 335200, + 335300, + 335300, + 335300, + 335300, + 335300, + 335300, + 335300, + 335300, + 335300, + 335300, + 335300, + 335400, + 335400, + 335400, + 335400, + 335400, + 335400, + 335500, + 335500, + 335500, + 335500, + 335600, + 335600, + 335600, + 335600, + 335600, + 335700, + 335700, + 335800, + 335800, + 335800, + 335800, + 335800, + 335800, + 335800, + 335800, + 335800, + 335900, + 335900, + 335900, + 336000, + 336000, + 336000, + 336100, + 336100, + 336100, + 336100, + 336100, + 336100, + 336200, + 336200, + 336200, + 336200, + 336200, + 336200, + 336300, + 336300, + 336300, + 336300, + 336300, + 336300, + 336400, + 336400, + 336400, + 336400, + 336400, + 336400, + 336400, + 336500, + 336500, + 336600, + 336600, + 336600, + 336600, + 336600, + 336600, + 336700, + 336700, + 336800, + 336800, + 336800, + 336800, + 336900, + 336900, + 336900, + 336900, + 336900, + 336900, + 336900, + 337000, + 337000, + 337100, + 337100, + 337200, + 337300, + 337300, + 337300, + 337300, + 337300, + 337300, + 337400, + 337400, + 337400, + 337500, + 337500, + 337500, + 337500, + 337500, + 337600, + 337600, + 337600, + 337600, + 337600, + 337600, + 337600, + 337600, + 337700, + 337700, + 337700, + 337700, + 337800, + 337800, + 337900, + 337900, + 337900, + 337900, + 337900, + 338000, + 338000, + 338000, + 338000, + 338000, + 338000, + 338100, + 338100, + 338100, + 338100, + 338100, + 338200, + 338200, + 338200, + 338200, + 338200, + 338300, + 338300, + 338400, + 338400, + 338400, + 338400, + 338400, + 338500, + 338500, + 338500, + 338500, + 338600, + 338600, + 338700, + 338700, + 338700, + 338700, + 338700, + 338700, + 338700, + 338800, + 338800, + 338800, + 338800, + 338800, + 338900, + 338900, + 338900, + 338900, + 338900, + 338900, + 338900, + 339000, + 339000, + 339000, + 339000, + 339000, + 339000, + 339100, + 339100, + 339100, + 339100, + 339100, + 339200, + 339200, + 339200, + 339200, + 339300, + 339300, + 339300, + 339300, + 339400, + 339400, + 339400, + 339400, + 339500, + 339500, + 339600, + 339600, + 339600, + 339700, + 339700, + 339700, + 339800, + 339800, + 339800, + 339900, + 339900, + 339900, + 340000, + 340000, + 340000, + 340000, + 340100, + 340300, + 340300, + 340300, + 340300, + 340500, + 340600, + 340600, + 340600, + 340600, + 340800, + 340800, + 341000, + 341000, + 341000, + 341100, + 341200, + 341200, + 341200, + 341300, + 341300, + 341400, + 341400, + 341400, + 341500, + 341600, + 341600, + 341800, + 341800, + 342000, + 342000, + 342100, + 342100, + 342100, + 342200, + 342300, + 342300, + 342300, + 342400, + 342600, + 342600, + 342800, + 342800, + 342800, + 342800, + 342900, + 343000, + 343000, + 343000, + 343100, + 343100, + 343200, + 343300, + 343300, + 343500, + 343500, + 343700, + 343700, + 344000, + 344100, + 344400, + 344400, + 344600, + 344700, + 344700, + 345000, + 345100, + 345300, + 345300, + 345400, + 345600, + 345600, + 345600, + 345700, + 345900, + 346000, + 346100, + 346100, + 346200, + 346400, + 346600, + 346600, + 346600, + 346700, + 346800, + 347000, + 347100, + 347500, + 347600, + 348400, + 348400, + 348500, + 348500, + 349300, + 349400, + 350000, + 350700, + 350800, + 351600, + 351600, + 351700, + 351900, + 353000, + 353500, + 354000, + 355100, + 355400, + 355500, + 356300, + 356300, + 356900, + 357000, + 357000, + 357100, + 357200, + 357500, + 357500, + 357900, + 358000, + 358100, + 358500, + 359200, + 359300, + 359300, + 360000, + 360500, + 361800, + 362100, + 362200, + 362500, + 362800, + 363000, + 363200, + 363200, + 363400, + 363500, + 364300, + 365000, + 365300, + 365800, + 365800, + 365800, + 366000, + 366200, + 366300, + 366400, + 366400, + 366400, + 366500, + 366600, + 366600, + 366800, + 366800, + 366900, + 366900, + 367300, + 367500, + 367600, + 367600, + 367700, + 367700, + 367800, + 368100, + 368400, + 368500, + 368500, + 368800, + 369100, + 369500, + 369700, + 370200, + 370300, + 370300, + 370300, + 370300, + 370700, + 370800, + 371100, + 371100, + 371200, + 371200, + 371300, + 371300, + 371400, + 371400, + 371500, + 371500, + 371700, + 371800, + 371900, + 371900, + 372000, + 372100, + 372100, + 372100, + 372400, + 372500, + 372600, + 373100, + 373200, + 373200, + 373300, + 373400, + 373500, + 373500, + 373600, + 373700, + 373700, + 373800, + 373800, + 373900, + 374000, + 374000, + 374300, + 374500, + 374500, + 374500, + 374700, + 375100, + 375200, + 375400, + 375500, + 375800, + 376000, + 376000, + 376000, + 376100, + 376400, + 376600, + 376600, + 376700, + 376800, + 376900, + 376900, + 377000, + 377000, + 377100, + 378000, + 378100, + 378400, + 378900, + 379200, + 379400, + 379800, + 379800, + 379800, + 380000, + 380100, + 380500, + 380800, + 380900, + 381000, + 381000, + 381100, + 381400, + 381500, + 381700, + 381800, + 382100, + 382400, + 382600, + 382700, + 383900, + 384100, + 384300, + 384600, + 384600, + 385000, + 385400, + 385700, + 386900, + 387900, + 387900, + 388600, + 388600, + 388800, + 388800, + 389100, + 390600, + 390700, + 390700, + 390800, + 391200, + 391600, + 391900, + 392400, + 392400, + 392800, + 393800, + 394000, + 394000, + 394000, + 394100, + 394100, + 394100, + 394100, + 394200, + 394500, + 394600, + 395000, + 395600, + 396300, + 400700, + 401300, + 401700, + 402800, + 405100, + 405600, + 407000, + 407300, + 407700, + 409300, + 409400, + 410600, + 410700, + 410900, + 413100, + 413100, + 414100, + 414400, + 415000, + 417300, + 417300, + 418700, + 420100, + 421500, + 422100, + 423300, + 426100, + 427100, + 427400, + 428300, + 429000, + 432500, + 435900, + 440500, + 476900, + 541300, + 1316800, + 1324600, + 1325800, + 1337900, + 1341200, + 1362900, + 1367600, + 1370800, + 1371500, + 1371600, + 1373100, + 1374200, + 1375100, + 1380700, + 1381800, + 1382000, + 1384400, + 1385500, + 1386500, + 1388300, + 1388800, + 1389400, + 1389600, + 1390600, + 1392700, + 1394500, + 1395900, + 1408700, + 1409400, + 1415100, + 1416100, + 1423900, + 1431400, + 1434600, + 1438600, + 1442000, + 1446200, + 1478300 + ], + "min": 352378.2630522088, + "max": 361565.79082946933, + "p25": 324600, + "p50": 355803.0172413793, + "p75": 337300, + "p99": 1385500, + "p999": 1442000, + "avg": 355803.0172413793, + "ticks": 1972, + "heap": { + "_": 1936, + "total": 3037341552, + "min": 1036328, + "max": 1830928, + "avg": 1568890.485417793 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 355848.4279918864, + 356841.86164801626, + 358448.5188968335, + 356820.2846975089, + 356018.20486815413, + 355727.11606690317, + 359701.28139415686, + 354145.61049445, + 356133.07965499745, + 353707.7620967742, + 356709.85772357724, + 354354.49494949495, + 359343.1131592422, + 352379.1666666667, + 356291.6708989335, + 353783.8205645161, + 355671.2620375063, + 355222.77327935223, + 355618.94630192505, + 354503.99191510864, + 356351.16751269036, + 353411.32930513594, + 356281.269035533, + 354943.5508345979, + 352378.2630522088, + 357173.63867684477, + 354976.78300455236, + 355256.5789473684, + 361565.79082946933, + 358621.2570260603, + 353120.3219315895, + 355108.90237733943, + 355757.6064908722, + 357528.7315333673, + 356899.6948118006, + 357395.51934826886, + 354177.9011099899, + 356183.14720812184 + ], + "rsdPercent": 0.5556285024247445 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 7, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 6364.84375, + 6365.9423828125, + 6366.2109375, + 6369.2626953125, + 6369.3603515625, + 6369.7998046875, + 6370.0927734375, + 6375.0244140625, + 6376.953124999767, + 6388.330078124767, + 6391.259765624767, + 6392.96875, + 6395.556640625233, + 6397.36328125, + 6399.365234375233, + 6401.611328124767, + 6418.9208984375, + 6430.859375, + 6434.887695312966, + 6469.189453125233, + 6489.3798828125, + 6562.3779296875, + 6598.193359375 + ], + "min": 6267.920939127624, + "max": 7750.397049753351, + "p25": 6369.7998046875, + "p50": 6470.911175271719, + "p75": 6418.9208984375, + "p99": 6562.3779296875, + "p999": 6562.3779296875, + "avg": 6470.911175271719, + "ticks": 94208, + "heap": { + "_": 18, + "total": 100942.890625, + "min": 5468.55078125, + "max": 7428.00390625, + "avg": 5635.218416892848 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 6412.94582201088, + 6739.930308948853, + 6771.656383167603, + 6319.904891304358, + 6382.938816236403, + 6408.123513926641, + 6810.045276988594, + 6506.623641304338, + 6320.642620584249, + 6518.843410326057, + 6594.572310014173, + 6589.146839488679, + 6469.076936141294, + 6467.606784986504, + 6313.067626953106, + 6353.030528192985, + 6441.693911345078, + 6267.920939127624, + 6338.325832201158, + 6338.293987771739, + 6569.271573153398, + 7750.397049753351, + 6568.568004261353, + 6472.745414402144, + 6907.972935267835, + 6412.018087635859, + 6590.204412286985, + 6518.204398777174, + 6656.21559836652, + 6823.778187144908, + 6300.427246093779, + 6443.883746603271, + 6653.915127840941, + 6346.164869225574, + 6573.999023437511, + 6545.437754755435, + 6389.742909307075, + 6458.16066576088 + ], + "rsdPercent": 3.9429941998628566 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 7, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 4961.23046875, + 4961.7431640625, + 4963.0615234375, + 4963.28125, + 4963.76953125, + 4973.0224609375, + 4974.560546875, + 4974.755859375, + 4975.390625, + 4978.076171875, + 4980.0048828125, + 4980.17578125, + 4980.46875, + 4981.005859375, + 4992.724609375, + 4995.3125, + 5004.0283203125, + 5004.98046875, + 5006.591796875, + 5008.8623046875, + 5015.234375, + 5015.52734375, + 5018.75, + 5019.9951171875, + 5033.0810546875, + 5036.6943359375, + 5043.017578125, + 5074.4140625, + 5084.4970703125, + 5090.1123046875, + 5199.072265625 + ], + "min": 4922.476688508064, + "max": 5046.697013608871, + "p25": 4974.755859375, + "p50": 4955.589245211693, + "p75": 5018.75, + "p99": 5090.1123046875, + "p999": 5090.1123046875, + "avg": 4955.589245211693, + "ticks": 126976, + "heap": { + "_": 34, + "total": 16798.23828125, + "min": 419.775390625, + "max": 1073.58203125, + "avg": 493.7634330253484 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 5008.175560735887, + 4979.0330456149195, + 4937.288936491936, + 4929.3598790322585, + 4969.624968497984, + 4936.072171118952, + 4947.239635836693, + 4964.942981350807, + 4957.169858870968, + 4930.523878528225, + 4941.734658518145, + 4930.419134324597, + 4955.887726814516, + 4963.128465221775, + 4964.194020917339, + 4958.732358870968, + 5046.697013608871, + 4968.929561491936, + 4987.141664566532, + 4950.048828125, + 4968.279832409275, + 4936.208417338709, + 4984.285219254032, + 4970.1612903225805, + 4937.821320564516, + 4955.290763608871, + 4966.414125504032, + 4922.476688508064, + 4936.1769153225805, + 4954.963930191532, + 4946.520602318548, + 4942.363911290323, + 5004.748928931452, + 4982.459677419355, + 4939.6586756552415, + 4930.979082661291, + 4948.534368699597, + 4957.628213205645 + ], + "rsdPercent": 0.5105072982087009 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 9, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 91800, + 91800, + 91900, + 91900, + 92000, + 92100, + 92100, + 92100, + 92100, + 92100, + 92100, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92200, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92300, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92400, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92500, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92600, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92700, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92800, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 92900, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93000, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93100, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93200, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93300, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93400, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93500, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93600, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93700, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93800, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 93900, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94000, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94100, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94200, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94300, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94400, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94500, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94600, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94700, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94800, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 94900, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95000, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95100, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95200, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95300, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95400, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95500, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95600, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95700, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95800, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 95900, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96000, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96100, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96200, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96300, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96400, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96500, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96600, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96700, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96800, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 96900, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97000, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97100, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97200, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97300, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97400, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97500, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97600, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97700, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97800, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 97900, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98000, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98100, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98200, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98300, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98400, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98500, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98600, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98700, + 98800, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 98900, + 99000, + 99000, + 99000, + 99000, + 99000, + 99000, + 99100, + 99100, + 99100, + 99200, + 99200, + 99300, + 99300, + 99300, + 99300, + 99300, + 99400, + 99400, + 99400, + 99400, + 99500, + 99500, + 99500, + 99500, + 99600, + 99600, + 99600, + 99600, + 99700, + 99700, + 99700, + 99700, + 99800, + 99800, + 99800, + 99800, + 99900, + 99900, + 99900, + 99900, + 100000, + 100100, + 100100, + 100100, + 100100, + 100200, + 100200, + 100200, + 100200, + 100200, + 100200, + 100200, + 100200, + 100300, + 100300, + 100400, + 100500, + 100600, + 100600, + 100700, + 100700, + 100800, + 100800, + 100800, + 101000, + 101000, + 101100, + 101100, + 101100, + 101100, + 101100, + 101200, + 101200, + 101300, + 101300, + 101300, + 101400, + 101400, + 101400, + 101400, + 101400, + 101500, + 101500, + 101500, + 101500, + 101600, + 101600, + 101600, + 101600, + 101700, + 101700, + 101700, + 101800, + 101800, + 101800, + 101900, + 101900, + 101900, + 101900, + 101900, + 101900, + 101900, + 101900, + 102000, + 102000, + 102000, + 102000, + 102000, + 102000, + 102000, + 102000, + 102000, + 102000, + 102000, + 102100, + 102100, + 102100, + 102100, + 102100, + 102100, + 102100, + 102100, + 102100, + 102100, + 102100, + 102200, + 102200, + 102200, + 102200, + 102200, + 102200, + 102200, + 102200, + 102200, + 102200, + 102200, + 102200, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102300, + 102400, + 102400, + 102400, + 102400, + 102400, + 102400, + 102400, + 102400, + 102400, + 102400, + 102400, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102500, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102600, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102700, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102800, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 102900, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103000, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103100, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103200, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103300, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103400, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103500, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103600, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103700, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103800, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 103900, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104000, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104100, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104200, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104300, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104400, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104500, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104600, + 104700, + 104700, + 104700, + 104700, + 104700, + 104700, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104800, + 104900, + 104900, + 104900, + 104900, + 104900, + 104900, + 105000, + 105000, + 105000, + 105100, + 105100, + 105200, + 105300, + 105400, + 105400, + 105500, + 105500, + 105500, + 105600, + 105600, + 105600, + 105600, + 105700, + 105700, + 105800, + 105800, + 105800, + 105800, + 105800, + 105900, + 105900, + 106000, + 106000, + 106000, + 106000, + 106000, + 106100, + 106200, + 106200, + 106300, + 106300, + 106300, + 106300, + 106300, + 106300, + 106400, + 106400, + 106400, + 106400, + 106500, + 106500, + 106600, + 106700, + 106700, + 106700, + 106800, + 106800, + 106800, + 106800, + 106900, + 106900, + 106900, + 106900, + 107000, + 107000, + 107100, + 107100, + 107200, + 107200, + 107400, + 107500, + 107500, + 107500, + 107600, + 107700, + 107700, + 107800, + 107800, + 107800, + 107900, + 107900, + 107900, + 107900, + 108000, + 108100, + 108100, + 108500, + 108800, + 108900, + 109000, + 109100, + 109200, + 109300, + 109400, + 109700, + 109800, + 109900, + 110300, + 110400, + 110500, + 110600, + 110700, + 110900, + 111600, + 111700, + 111900, + 111900, + 112100, + 112300, + 112500, + 112600, + 113100, + 114300, + 114800, + 115400, + 115900, + 116100, + 116500, + 117000, + 117100, + 117300, + 118300, + 118300, + 118500, + 118800, + 118800, + 119000, + 119200, + 119300, + 119300, + 119400, + 119900, + 119900, + 120000, + 120000, + 120000, + 120300, + 120400, + 120400, + 120400, + 120500, + 120700, + 120800, + 121300, + 121400, + 121600, + 123200, + 123600, + 123600, + 123800, + 123800, + 124000, + 124100, + 124100, + 125800, + 125800, + 128600, + 129000, + 129200, + 129400, + 130000, + 130000, + 130400, + 131100, + 133000, + 133600, + 134300, + 134800, + 134800, + 135100, + 135400, + 138000, + 140300, + 143800, + 149200, + 149900, + 151200, + 151700, + 152100, + 152600, + 153000, + 153200, + 153500, + 153800, + 154000, + 155100, + 156400, + 157200, + 157500, + 157600, + 159000, + 160000, + 160500, + 160900, + 161900, + 162900, + 162900, + 163100, + 163100, + 163200, + 163200, + 164400, + 164500, + 164900, + 165200, + 166100, + 166500, + 166800, + 167400, + 167400, + 167800, + 168500, + 168700, + 168800, + 168800, + 169300, + 169600, + 169700, + 169700, + 170900, + 171000, + 171000, + 171200, + 171300, + 171600, + 171700, + 171800, + 172300, + 172600, + 173400, + 173400, + 174200, + 174300, + 174500, + 174800, + 174800, + 176600, + 176600, + 176700, + 177100, + 177100, + 179100, + 179300, + 181100, + 182700, + 185000, + 186200, + 186300, + 186300, + 189000, + 190000, + 190800, + 194800, + 200200, + 200300, + 205800, + 208400, + 210000, + 210200, + 231400, + 240700, + 255800, + 270700 + ], + "min": 90994.05209278216, + "max": 110659.55905511811, + "p25": 93800, + "p50": 98231.1010897524, + "p75": 95200, + "p99": 157600, + "p999": 200300, + "avg": 98231.1010897524, + "ticks": 7269, + "heap": { + "_": 7195, + "total": 4921323600, + "min": 58976, + "max": 1120576, + "avg": 683782.5918757269 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 96647.42055303343, + 100513.81974248927, + 105430.04201680672, + 90994.05209278216, + 98167.88208996927, + 97709.49930458971, + 95150.81278786236, + 101611.82764603817, + 104633.41772151898, + 95134.04197698037, + 95149.2345210676, + 106300.07564296521, + 110395.00392772978, + 103899.6894409938, + 95165.02236075349, + 100049.95728929384, + 95205.17615176152, + 110659.55905511811, + 99553.49298568798, + 101969.07560586272, + 102608.80549065421, + 94580.29629629629, + 98294.32008953554, + 95466.20905260296, + 105312.0335681103, + 95411.61684782608, + 95631.67279161562, + 94501.19736311045, + 96961.65309783358, + 98790.01827639533, + 96206.16522811344, + 95982.5659243066, + 93352.98338870432, + 99659.64539007092, + 102465.3689122193, + 96362.25483472775, + 99142.18397291197, + 101972.10854738065 + ], + "rsdPercent": 4.66597131519921 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 9, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 15327.8564453125, + 15366.650390625, + 15377.4169921875, + 15381.103515625, + 15385.7666015625, + 15386.3525390625, + 15400.3173828125, + 15416.5283203125, + 15452.0263671875, + 15477.001953125, + 15492.919921875, + 15563.18359375 + ], + "min": 15211.5234375, + "max": 15772.664388020834, + "p25": 15377.4169921875, + "p50": 15325.762939453125, + "p75": 15452.0263671875, + "p99": 15492.919921875, + "p999": 15492.919921875, + "avg": 15325.762939453125, + "ticks": 49152, + "heap": { + "_": 11, + "total": 28703.994140625, + "min": 2608.193359375, + "max": 2613.16796875, + "avg": 2608.2310668361247 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 15418.927001953125, + 15693.221028645834, + 15405.391438802084, + 15294.057210286459, + 15772.664388020834, + 15218.853759765625, + 15345.902506510416, + 15218.98193359375, + 15300.626627604166, + 15235.697428385416, + 15431.264241536459, + 15228.104654947916, + 15415.590413411459, + 15528.843180338541, + 15317.946370442709, + 15235.414632161459, + 15260.524495442709, + 15217.791748046875, + 15429.547119140625, + 15211.5234375, + 15296.221923828125, + 15407.979329427084, + 15219.948323567709, + 15361.936442057291, + 15477.276611328125, + 15277.956136067709, + 15333.579508463541, + 15215.987141927084, + 15290.887451171875, + 15421.575927734375, + 15233.013916015625, + 15348.478190104166, + 15248.59619140625, + 15365.037027994791, + 15367.628987630209, + 15457.224527994791, + 15254.742431640625, + 15551.588948567709 + ], + "rsdPercent": 0.8550677198938949 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 11, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 5645.9716796875, + 5652.6611328125, + 5678.22265625, + 5680.1513671875, + 5680.810546875, + 5681.982421875, + 5682.3974609375, + 5684.6435546875, + 5689.1357421875, + 5696.7529296875, + 5697.7783203125, + 5699.609375, + 5700.6591796875, + 5705.2490234375, + 5708.7158203125, + 5712.98828125, + 5715.8935546875, + 5724.9267578125, + 5725.9765625, + 5741.9189453125, + 5744.580078125, + 5750.9033203125, + 5764.2578125, + 5768.1396484375, + 5770.458984375, + 5879.3701171875 + ], + "min": 5679.519314236111, + "max": 6391.665251358696, + "p25": 5682.3974609375, + "p50": 5763.22256234976, + "p75": 5725.9765625, + "p99": 5770.458984375, + "p999": 5770.458984375, + "avg": 5763.22256234976, + "ticks": 106496, + "heap": { + "_": 12, + "total": 120757.07421875, + "min": 9911.591796875, + "max": 11682.185546875, + "avg": 10056.875732961018 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 5714.7752028245195, + 5839.943284254808, + 5768.215707632212, + 5785.660494290865, + 5718.317119891827, + 5762.961989182692, + 5694.289822048611, + 5795.441143329327, + 5820.519080528846, + 5714.9461012620195, + 6391.665251358696, + 5802.206655649038, + 5874.7633713942305, + 5718.435434194712, + 5990.2236328125, + 5907.978515625, + 5744.3800706129805, + 5750.684532752404, + 5720.620492788462, + 5726.247934194712, + 5703.285569411058, + 5763.483135516827, + 5741.555551382212, + 5699.199969951923, + 5783.644456129808, + 5768.035419170673, + 5733.836012620192, + 5851.4939528245195, + 5729.794546274038, + 5754.541015625, + 5711.908428485577, + 6080.0068359375, + 6332.090250651042, + 5840.250338040865, + 5679.519314236111, + 5807.7927809495195, + 5768.318997896635, + 5700.0075120192305 + ], + "rsdPercent": 2.6828150020327195 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 11, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 6367.96875, + 6373.828125, + 6383.7890625, + 6393.0419921875, + 6394.4580078125, + 6396.9482421875, + 6411.4501953125, + 6419.43359375, + 6481.8115234375, + 6492.87109375, + 6495.068359375, + 6496.0693359375, + 6505.0048828125, + 6512.9150390625, + 6518.9208984375, + 6524.3896484375, + 6535.05859375, + 6544.287109375, + 6545.2880859375, + 6548.4375, + 6552.734375, + 6560.791015625, + 6561.7431640625 + ], + "min": 6428.438136888587, + "max": 6800.248579545455, + "p25": 6396.9482421875, + "p50": 6508.170749830163, + "p75": 6535.05859375, + "p99": 6560.791015625, + "p999": 6560.791015625, + "avg": 6508.170749830163, + "ticks": 94208, + "heap": { + "_": 17, + "total": 113965.16796875, + "min": 6559.435546875, + "max": 8436.62890625, + "avg": 6699.295480828535 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 6478.969938858696, + 6490.382982336957, + 6591.017747961957, + 6596.691363790761, + 6496.431300951087, + 6551.524286684783, + 6800.248579545455, + 6462.605086616848, + 6484.085215692935, + 6618.451723845109, + 6721.932705965909, + 6470.383619225543, + 6721.586470170455, + 6636.944025213068, + 6568.403957201087, + 6523.59035326087, + 6463.930876358696, + 6732.633833451705, + 6428.438136888587, + 6482.161812160326, + 6497.889775815217, + 6497.035283627717, + 6545.960003396739, + 6644.495738636364, + 6506.407099184783, + 6506.255307404891, + 6476.71535326087, + 6481.832753057065, + 6442.771314538043, + 6571.437669836957, + 6662.385697798295, + 6509.934400475543, + 6778.574440696023, + 6498.857846467391, + 6441.896654211957, + 6493.226689877717, + 6798.036887428977, + 6728.524502840909 + ], + "rsdPercent": 1.660986929755109 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 13, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 2430.517578125, + 2430.908203125, + 2433.5693359375, + 2434.3505859375, + 2435.3759765625, + 2435.986328125, + 2436.083984375, + 2436.1572265625, + 2436.71875, + 2437.0361328125, + 2438.1103515625, + 2438.3056640625, + 2440.576171875, + 2442.3583984375, + 2443.603515625, + 2444.921875, + 2446.2158203125, + 2446.9970703125, + 2447.2900390625, + 2447.3876953125, + 2447.4609375, + 2447.9736328125, + 2448.388671875, + 2448.9501953125, + 2449.0234375, + 2450.6103515625, + 2450.9521484375, + 2451.66015625, + 2451.6845703125, + 2451.9775390625, + 2452.392578125, + 2453.2958984375, + 2453.7841796875, + 2454.443359375, + 2454.6875, + 2454.931640625, + 2455.6396484375, + 2456.005859375, + 2456.0546875, + 2456.1767578125, + 2456.54296875, + 2457.177734375, + 2458.056640625, + 2460.1318359375, + 2460.205078125, + 2460.205078125, + 2460.7421875, + 2462.2802734375, + 2462.4267578125, + 2463.037109375, + 2464.2333984375, + 2464.306640625, + 2464.74609375, + 2464.84375, + 2465.9912109375, + 2466.845703125, + 2468.5302734375, + 2469.6533203125, + 2477.2216796875, + 2478.271484375, + 2479.2724609375, + 2479.9072265625, + 2481.9091796875, + 2489.111328125, + 2494.140625, + 2709.66796875 + ], + "min": 2443.3947207322763, + "max": 2721.4260295286017, + "p25": 2446.2158203125, + "p50": 2472.882080078125, + "p75": 2462.4267578125, + "p99": 2494.140625, + "p999": 2494.140625, + "avg": 2472.882080078125, + "ticks": 270336, + "heap": { + "_": 22, + "total": 251608.53515625, + "min": 11311.037109375, + "max": 12208.21875, + "avg": 11437.242651383878 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 2458.303370620265, + 2468.1292909564395, + 2473.180782433712, + 2460.5672200520835, + 2476.290246212121, + 2498.498722956731, + 2469.0806995738635, + 2495.001502403846, + 2493.0341045673076, + 2484.3964092548076, + 2553.280258178711, + 2480.300440932765, + 2465.877648555871, + 2457.715213660038, + 2492.6220703125, + 2443.3947207322763, + 2465.1437470407195, + 2468.362334280303, + 2475.5996241714015, + 2494.849384014423, + 2456.0073390151515, + 2485.1893028846152, + 2459.2762340198865, + 2463.1236683238635, + 2472.583377722538, + 2721.4260295286017, + 2485.2324969951924, + 2449.749940814394, + 2494.814453125, + 2477.6448567708335, + 2449.414432410038, + 2476.766320430871, + 2462.4774354876895, + 2476.3013435132575, + 2462.7452503551135, + 2471.169581557765, + 2450.1812559185605, + 2485.2925931490386 + ], + "rsdPercent": 1.7958560495042384 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 13, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n for (let o = 0; o < 1024; o++) {\n \n\n $fn();\n$fn();\n$fn();\n$fn();\n }\n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) / 4096; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff / 4096;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length * 4096,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 1827.685546875, + 1827.7587890625, + 1829.052734375, + 1829.443359375, + 1830.8349609375, + 1831.2744140625, + 1831.787109375, + 1832.8125, + 1833.0322265625, + 1833.203125, + 1833.740234375, + 1833.740234375, + 1833.7890625, + 1833.8134765625, + 1834.1796875, + 1834.6435546875, + 1834.716796875, + 1834.8876953125, + 1835.3515625, + 1835.400390625, + 1835.4736328125, + 1835.888671875, + 1836.767578125, + 1836.9873046875, + 1837.20703125, + 1837.3046875, + 1837.744140625, + 1838.134765625, + 1838.18359375, + 1838.818359375, + 1838.916015625, + 1839.2333984375, + 1839.4775390625, + 1839.5751953125, + 1839.9658203125, + 1840.283203125, + 1840.3564453125, + 1840.5029296875, + 1840.9912109375, + 1841.0888671875, + 1841.3818359375, + 1842.2607421875, + 1842.7490234375, + 1842.8466796875, + 1843.310546875, + 1843.9208984375, + 1844.482421875, + 1844.580078125, + 1844.6044921875, + 1844.6533203125, + 1845.1904296875, + 1845.3369140625, + 1845.5810546875, + 1845.5810546875, + 1845.5810546875, + 1846.1669921875, + 1846.1669921875, + 1846.8994140625, + 1847.8759765625, + 1847.900390625, + 1848.3642578125, + 1848.92578125, + 1850.439453125, + 1850.4638671875, + 1850.9765625, + 1851.6357421875, + 1852.63671875, + 1854.9560546875, + 1855.419921875, + 1855.76171875, + 1861.9384765625, + 1870.703125, + 1881.54296875, + 2006.8115234375, + 2007.4951171875, + 2009.423828125, + 2012.4755859375, + 2013.1103515625, + 2015.087890625, + 2019.9462890625, + 2022.9736328125, + 2027.099609375, + 2028.5400390625, + 2031.103515625, + 2031.1279296875, + 2038.5986328125, + 2038.6474609375, + 2066.162109375 + ], + "min": 1811.7764315762363, + "max": 1998.867834619729, + "p25": 1835.888671875, + "p50": 1859.3095757988062, + "p75": 1851.6357421875, + "p99": 2038.6474609375, + "p999": 2038.6474609375, + "avg": 1859.3095757988062, + "ticks": 360448, + "heap": { + "_": 55, + "total": 370726.07421875, + "min": 6721.30078125, + "max": 6904.802734375, + "avg": 6740.3765454376435 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 1872.9941628196023, + 1833.3634440104167, + 1827.726326407967, + 1836.469997829861, + 1852.222502633427, + 1869.6319237183989, + 1876.6107732599432, + 1833.9168294270833, + 1867.1792705407304, + 1893.5386920797414, + 1858.4170909410113, + 1843.6119249131943, + 1855.8939387289327, + 1811.7764315762363, + 1884.2246315696023, + 1828.1730232657967, + 1881.2480579723012, + 1998.867834619729, + 1866.9891700316011, + 1889.0314275568182, + 1827.8331043956043, + 1864.645968662219, + 1824.1881653502746, + 1823.3674772493132, + 1880.166348544034, + 1849.1899956597222, + 1877.9557661576705, + 1846.614040798611, + 1846.8340386284722, + 1877.5609796697443, + 1844.3183051215278, + 1877.436689897017, + 1852.1018038974719, + 1833.242458767361, + 1882.2004838423295, + 1886.8513627485795, + 1860.2020606566011, + 1899.3862809806035 + ], + "rsdPercent": 1.7396073878028904 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "handlebars", + "group": 15, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 4330500, + 4330900, + 4331200, + 4331500, + 4332900, + 4334300, + 4334400, + 4334600, + 4334800, + 4335700, + 4335900, + 4336700, + 4339600, + 4339700, + 4340300, + 4340700, + 4340700, + 4341600, + 4342000, + 4342800, + 4342900, + 4343200, + 4343300, + 4343400, + 4344400, + 4344600, + 4344600, + 4344700, + 4344900, + 4345300, + 4345600, + 4346400, + 4347800, + 4347900, + 4348400, + 4348600, + 4348800, + 4350000, + 4350600, + 4350600, + 4351200, + 4351200, + 4351400, + 4351600, + 4352000, + 4352000, + 4352100, + 4352200, + 4352300, + 4352400, + 4352600, + 4352600, + 4352700, + 4353200, + 4353300, + 4353700, + 4354400, + 4355700, + 4356000, + 4356100, + 4356500, + 4357000, + 4358400, + 4358400, + 4358600, + 4359500, + 4359900, + 4360400, + 4360400, + 4360900, + 4363000, + 4364700, + 4365500, + 4366100, + 4366200, + 4366700, + 4366900, + 4369500, + 4370600, + 4370900, + 4372200, + 4373800, + 4373800, + 4375900, + 4376600, + 4377700, + 4378400, + 4381000, + 4382300, + 4384000, + 4389300, + 4390200, + 4415500, + 4421600, + 4424600, + 4424900, + 4426200, + 4426900, + 4440900, + 4441700, + 4448000, + 4450100, + 4452000, + 4453300, + 4455300, + 4461900, + 4467000, + 4474600, + 4479800, + 4481100, + 4484300, + 4488700, + 4490200, + 4496100, + 4498300, + 4499200, + 4500600, + 4513600, + 4518300, + 4521400, + 4524000, + 4527900, + 4530200, + 4561100, + 4562900, + 4564600, + 4570600, + 4574600, + 4576500, + 4580600, + 4584300, + 4613600, + 4615400, + 4647100, + 4648000, + 4673900, + 4701000, + 4764000, + 4795800, + 4802100, + 5614800, + 5619400, + 5646500, + 5736900, + 5738700, + 5757900, + 5843700, + 5885000, + 5915400, + 5940700, + 5995800, + 6163700 + ], + "min": 4394283.439490446, + "max": 4898513.571428572, + "p25": 4350000, + "p50": 4553071.19205298, + "p75": 4496100, + "p99": 5940700, + "p999": 5995800, + "avg": 4553071.19205298, + "ticks": 152, + "heap": { + "_": 143, + "total": 1032091024, + "min": 6568616, + "max": 7867240, + "avg": 7217455.434220568 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 4525418.421052632, + 4597749.6644295305, + 4463060.389610389, + 4586179.333333333, + 4493101.307189543, + 4518540.131578947, + 4597526.174496644, + 4898513.571428572, + 4529199.342105263, + 4666872.789115646, + 4593514, + 4526102.631578947, + 4462693.506493507, + 4450152.597402598, + 4613073.154362416, + 4646318.243243244, + 4510320.394736842, + 4717595.862068965, + 4550850.993377483, + 4535034.437086092, + 4658959.863945578, + 4555291.390728476, + 4451705.844155844, + 4601961.744966443, + 4499117.647058823, + 4656770.06802721, + 4690184.931506849, + 4437865.161290322, + 4708081.506849315, + 4591634.666666667, + 4532151.97368421, + 4571964.666666667, + 4600653.691275168, + 4479058.169934641, + 4568316, + 4532467.763157895, + 4394283.439490446, + 4515655.921052632 + ], + "rsdPercent": 2.0938902876966274 + } + }, + "args": {}, + "name": "handlebars" + } + ], + "style": { + "highlight": false, + "compact": false + } + }, + { + "kind": "static", + "args": {}, + "alias": "eta", + "group": 15, + "baseline": false, + "runs": [ + { + "stats": { + "kind": "fn", + "debug": "async function anonymous($fn,$gc,$now,$heap,$params,$counters\n) {\n\n \n \n\n let _ = 0; let t = 0;\n let samples = new Array(2 ** 20);\n const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };\n \n\n \n\n $gc();\n\n for (; _ < 1000000000; _++) {\n if (_ >= 12 && t >= 706200000) break;\n\n \n\n \n\n \n const h0 = $heap();\n const t0 = $now();\n\n \n \n $fn();\n \n \n\n const t1 = $now();\n \n\n \n heap: {\n const t0 = $now();\n const h1 = ($heap() - h0) ; t += $now() - t0;\n\n if (0 <= h1) {\n heap._++;\n heap.total += h1;\n heap.min = Math.min(h1, heap.min);\n heap.max = Math.max(h1, heap.max);\n }\n }\n \n\n ;\n\n const diff = t1 - t0;\n t += t1 - t0;\n samples[_] = diff ;\n }\n\n samples.length = _;\n samples.sort((a, b) => a - b);\n if (samples.length > 12) samples = samples.slice(2, -2);\n\n return {\n samples,\n min: samples[0],\n max: samples[samples.length - 1],\n p25: samples[(.25 * (samples.length - 1)) | 0],\n p50: samples[(.50 * (samples.length - 1)) | 0],\n p75: samples[(.75 * (samples.length - 1)) | 0],\n p99: samples[(.99 * (samples.length - 1)) | 0],\n p999: samples[(.999 * (samples.length - 1)) | 0],\n avg: samples.reduce((a, v) => a + v, 0) / samples.length,\n ticks: samples.length ,\n heap: { ...heap, avg: heap.total / heap._ },\n \n \n };\n\n \n \n}", + "samples": [ + 4337000, + 4337600, + 4337800, + 4337800, + 4338100, + 4338400, + 4338700, + 4339000, + 4340100, + 4340400, + 4340400, + 4341300, + 4341300, + 4341400, + 4341500, + 4342000, + 4342200, + 4342400, + 4342400, + 4342700, + 4344300, + 4347100, + 4347200, + 4349000, + 4349100, + 4349200, + 4349200, + 4349300, + 4350200, + 4350300, + 4350500, + 4350600, + 4351100, + 4352500, + 4352700, + 4353600, + 4355500, + 4356600, + 4356800, + 4357200, + 4357500, + 4358500, + 4358500, + 4358700, + 4359000, + 4359100, + 4359700, + 4359700, + 4360200, + 4360500, + 4360500, + 4360800, + 4360900, + 4361900, + 4362800, + 4363000, + 4363100, + 4363400, + 4363500, + 4363900, + 4364300, + 4364500, + 4365500, + 4365500, + 4367200, + 4367500, + 4368200, + 4369400, + 4369400, + 4369800, + 4369900, + 4371400, + 4372200, + 4373000, + 4374300, + 4375700, + 4376100, + 4376300, + 4376800, + 4377100, + 4379300, + 4380300, + 4380700, + 4381300, + 4383100, + 4383300, + 4383500, + 4384100, + 4384500, + 4385800, + 4386300, + 4386500, + 4387000, + 4388200, + 4389000, + 4389400, + 4391000, + 4394200, + 4398100, + 4398600, + 4398700, + 4399700, + 4401300, + 4404300, + 4407400, + 4407600, + 4412000, + 4412200, + 4416300, + 4418700, + 4419100, + 4423000, + 4425200, + 4431000, + 4432200, + 4432600, + 4440400, + 4444800, + 4444900, + 4445500, + 4448200, + 4453800, + 4470200, + 4474200, + 4474900, + 4524500, + 4534100, + 4542200, + 4542600, + 4556800, + 4558000, + 4562700, + 4563500, + 4564000, + 4577900, + 4598800, + 4601100, + 4602900, + 4611000, + 4625600, + 4669200, + 5572300, + 5590300, + 5610200, + 5641300, + 5651200, + 5655800, + 5673900, + 5674000, + 5689400, + 5701400, + 5757700, + 5758700 + ], + "min": 4297611.25, + "max": 4747080, + "p25": 4356800, + "p50": 4448684.706744868, + "p75": 4432200, + "p99": 5701400, + "p999": 5757700, + "avg": 4448684.706744868, + "ticks": 153, + "heap": { + "_": 143, + "total": 1097646208, + "min": 7675680, + "max": 7683512, + "avg": 7675594.7865585955 + }, + "aggregate": { + "passes": 38, + "source": [ + "run-1.json", + "run-2.json", + "run-3.json", + "run-4.json", + "run-5.json", + "run-6.json", + "run-7.json", + "run-8.json", + "run-9.json", + "run-10.json", + "run-11.json", + "run-12.json", + "run-13.json", + "run-14.json", + "run-15.json", + "run-16.json", + "run-17.json", + "run-18.json", + "run-19.json", + "run-20.json", + "run-21.json", + "run-22.json", + "run-23.json", + "run-24.json", + "run-25.json", + "run-26.json", + "run-27.json", + "run-28.json", + "run-29.json", + "run-30.json", + "run-31.json", + "run-32.json", + "run-33.json", + "run-34.json", + "run-35.json", + "run-36.json", + "run-37.json", + "run-38.json" + ], + "statistic": "median of per-pass avg", + "dispersion": "min...max of per-pass avg (cross-process)", + "perPassAvg": [ + 4497629.411764706, + 4511232.679738563, + 4297611.25, + 4397778.343949044, + 4421535.897435897, + 4560655.629139073, + 4706253.424657534, + 4334078.616352201, + 4467159.090909091, + 4339057.232704403, + 4473915.584415585, + 4589774.666666667, + 4503089.54248366, + 4390098.726114649, + 4393310.828025478, + 4360687.341772152, + 4501235.294117647, + 4514355.263157895, + 4410905.128205128, + 4495092.810457516, + 4329198.113207547, + 4643373.6486486485, + 4430210.322580645, + 4477170.12987013, + 4407577.564102564, + 4529418.421052632, + 4402757.051282051, + 4387457.3248407645, + 4381395.541401274, + 4655689.189189189, + 4366967.088607595, + 4401421.153846154, + 4533296.052631579, + 4372973.248407643, + 4575863.576158941, + 4421437.179487179, + 4479705.844155844, + 4747080 + ], + "rsdPercent": 2.3780230524845685 + } + }, + "args": {}, + "name": "eta" + } + ], + "style": { + "highlight": false, + "compact": false + } + } +] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/js/idiomatic.txt b/docs/benchmarks/2026-08-08/js/idiomatic.txt new file mode 100644 index 00000000..1c95f69e --- /dev/null +++ b/docs/benchmarks/2026-08-08/js/idiomatic.txt @@ -0,0 +1,26 @@ +# idiomatic — aggregate of 38 passes (ledger E6) +# +# This is NOT a single mitata run. The published statistic is the median of the per-pass +# `avg` values and the dispersion is their min…max spread, so the interval below is +# cross-process variation. Each pass's own mitata-format capture and JSON — the two views +# of one run that D11 requires — are under stability/idiomatic/run-.txt|.json. +# +# STABILITY: verified (D13; cross-pass RSD median 1.77%, max 4.77%) +# Full verdict table: stability-summary-idiomatic.md + + 0 handlebars 5322.1 ns 5270.5 … 5380.3 ns RSD 0.46% + 1 eta 4230.6 ns 4195.1 … 4318.3 ns RSD 0.74% + 2 handlebars 629.5 ns 609.9 … 650.8 ns RSD 1.38% + 3 eta 253.6 ns 244.7 … 276.1 ns RSD 3.28% + 4 handlebars 355768.3 ns 352404.6 … 441995.4 ns RSD 4.77% + 5 eta 355803.0 ns 352378.3 … 361565.8 ns RSD 0.56% + 6 handlebars 6470.9 ns 6267.9 … 7750.4 ns RSD 3.94% + 7 eta 4955.6 ns 4922.5 … 5046.7 ns RSD 0.51% + 8 handlebars 98231.1 ns 90994.1 … 110659.6 ns RSD 4.67% + 9 eta 15325.8 ns 15211.5 … 15772.7 ns RSD 0.86% +10 handlebars 5763.2 ns 5679.5 … 6391.7 ns RSD 2.68% +11 eta 6508.2 ns 6428.4 … 6800.2 ns RSD 1.66% +12 handlebars 2472.9 ns 2443.4 … 2721.4 ns RSD 1.80% +13 eta 1859.3 ns 1811.8 … 1998.9 ns RSD 1.74% +14 handlebars 4553071.2 ns 4394283.4 … 4898513.6 ns RSD 2.09% +15 eta 4448684.7 ns 4297611.3 … 4747080.0 ns RSD 2.38% diff --git a/docs/benchmarks/2026-08-08/js/stability-summary-controlled.md b/docs/benchmarks/2026-08-08/js/stability-summary-controlled.md new file mode 100644 index 00000000..f32ddfd6 --- /dev/null +++ b/docs/benchmarks/2026-08-08/js/stability-summary-controlled.md @@ -0,0 +1,36 @@ +# JS stability summary — `controlled` + +Phase 4 D13 verdict computed from **38 consecutive passes** of +`bench/controlled.mjs`, each a separate node process. Thresholds are per cell on the +cross-pass RSD of mitata's `avg`: ≤ 5% verified; 5–10% publishable but the report must carry +this table; > 10% blocks publication. + +STABILITY: verified-with-disclosure + +- passes: 38 (run-1.json … run-38.json) +- cells: 16 +- cross-pass RSD: median 1.41% · max 5.11% (handlebars, cell 6) +- cells above 5%: 1 · above 10%: 0 + +| # | Engine | Published (median of passes) | Cross-pass min … max | RSD | +| ---: | --- | ---: | --- | ---: | +| 0 | handlebars | 5414.3 ns | 5270.0 … 5505.8 ns | 0.91% | +| 1 | eta | 4235.4 ns | 4180.9 … 4309.9 ns | 0.67% | +| 2 | handlebars | 742.5 ns | 719.3 … 767.6 ns | 1.43% | +| 3 | eta | 135.4 ns | 130.7 … 147.3 ns | 2.37% | +| 4 | handlebars | 407297.3 ns | 401000.2 … 420329.5 ns | 0.92% | +| 5 | eta | 250076.0 ns | 247647.6 … 256711.5 ns | 0.86% | +| 6 | handlebars | 7667.3 ns | 7295.7 … 9421.2 ns | 5.11% | +| 7 | eta | 3004.4 ns | 2937.9 … 3034.5 ns | 0.83% | +| 8 | handlebars | 101570.7 ns | 93572.9 … 110068.9 ns | 4.33% | +| 9 | eta | 10537.6 ns | 10419.7 … 10679.0 ns | 0.51% | +| 10 | handlebars | 6650.6 ns | 6571.0 … 7295.3 ns | 2.61% | +| 11 | eta | 4809.3 ns | 4754.6 … 5062.3 ns | 1.60% | +| 12 | handlebars | 2644.9 ns | 2593.6 … 2735.4 ns | 1.04% | +| 13 | eta | 1825.6 ns | 1757.0 … 1879.7 ns | 1.70% | +| 14 | handlebars | 4712629.5 ns | 4569566.7 … 4866639.0 ns | 1.58% | +| 15 | eta | 4436398.7 ns | 4301750.6 … 4578670.9 ns | 1.40% | + +The published artifact `controlled.json` carries this aggregate: `stats.avg` is the median +of the per-pass averages and `stats.min`/`stats.max` span the passes, so its dispersion is +cross-process variation. Per-cell provenance is under `stats.aggregate`. diff --git a/docs/benchmarks/2026-08-08/js/stability-summary-idiomatic.md b/docs/benchmarks/2026-08-08/js/stability-summary-idiomatic.md new file mode 100644 index 00000000..47842730 --- /dev/null +++ b/docs/benchmarks/2026-08-08/js/stability-summary-idiomatic.md @@ -0,0 +1,36 @@ +# JS stability summary — `idiomatic` + +Phase 4 D13 verdict computed from **38 consecutive passes** of +`bench/idiomatic.mjs`, each a separate node process. Thresholds are per cell on the +cross-pass RSD of mitata's `avg`: ≤ 5% verified; 5–10% publishable but the report must carry +this table; > 10% blocks publication. + +STABILITY: verified + +- passes: 38 (run-1.json … run-38.json) +- cells: 16 +- cross-pass RSD: median 1.77% · max 4.77% (handlebars, cell 4) +- cells above 5%: 0 · above 10%: 0 + +| # | Engine | Published (median of passes) | Cross-pass min … max | RSD | +| ---: | --- | ---: | --- | ---: | +| 0 | handlebars | 5322.1 ns | 5270.5 … 5380.3 ns | 0.46% | +| 1 | eta | 4230.6 ns | 4195.1 … 4318.3 ns | 0.74% | +| 2 | handlebars | 629.5 ns | 609.9 … 650.8 ns | 1.38% | +| 3 | eta | 253.6 ns | 244.7 … 276.1 ns | 3.28% | +| 4 | handlebars | 355768.3 ns | 352404.6 … 441995.4 ns | 4.77% | +| 5 | eta | 355803.0 ns | 352378.3 … 361565.8 ns | 0.56% | +| 6 | handlebars | 6470.9 ns | 6267.9 … 7750.4 ns | 3.94% | +| 7 | eta | 4955.6 ns | 4922.5 … 5046.7 ns | 0.51% | +| 8 | handlebars | 98231.1 ns | 90994.1 … 110659.6 ns | 4.67% | +| 9 | eta | 15325.8 ns | 15211.5 … 15772.7 ns | 0.86% | +| 10 | handlebars | 5763.2 ns | 5679.5 … 6391.7 ns | 2.68% | +| 11 | eta | 6508.2 ns | 6428.4 … 6800.2 ns | 1.66% | +| 12 | handlebars | 2472.9 ns | 2443.4 … 2721.4 ns | 1.80% | +| 13 | eta | 1859.3 ns | 1811.8 … 1998.9 ns | 1.74% | +| 14 | handlebars | 4553071.2 ns | 4394283.4 … 4898513.6 ns | 2.09% | +| 15 | eta | 4448684.7 ns | 4297611.3 … 4747080.0 ns | 2.38% | + +The published artifact `idiomatic.json` carries this aggregate: `stats.avg` is the median +of the per-pass averages and `stats.min`/`stats.max` span the passes, so its dispersion is +cross-process variation. Per-cell provenance is under `stats.aggregate`. diff --git a/docs/benchmarks/2026-08-08/jvm/jmh-result.json b/docs/benchmarks/2026-08-08/jvm/jmh-result.json new file mode 100644 index 00000000..d45d8bc7 --- /dev/null +++ b/docs/benchmarks/2026-08-08/jvm/jmh-result.json @@ -0,0 +1,9956 @@ +[ + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.ComposedPageBench.jteControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 14436.756535660032, + "scoreError" : 33.92867373936426, + "scoreConfidence" : [ + 14402.827861920667, + 14470.685209399397 + ], + "scorePercentiles" : { + "0.0" : 14345.253268792874, + "50.0" : 14436.876812744405, + "90.0" : 14489.939902377038, + "95.0" : 14499.441134866089, + "99.0" : 14503.319423918398, + "99.9" : 14503.319423918398, + "99.99" : 14503.319423918398, + "99.999" : 14503.319423918398, + "99.9999" : 14503.319423918398, + "100.0" : 14503.319423918398 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 14503.319423918398, + 14453.213579195126, + 14434.704696053012, + 14384.153994169934, + 14386.850315586675 + ], + [ + 14454.452415664651, + 14393.245147375988, + 14346.171038869865, + 14373.94333821797, + 14345.253268792874 + ], + [ + 14419.401953158758, + 14408.38099903468, + 14466.287325572988, + 14486.089850249584, + 14490.391793744033 + ], + [ + 14457.045845313607, + 14434.455779372352, + 14482.039818271262, + 14483.311154825273, + 14489.63864146571 + ], + [ + 14479.061903936188, + 14435.629943992148, + 14433.593445744205, + 14441.40090623106, + 14436.876812744405 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 24115.445786785524, + "scoreError" : 56.712205435550416, + "scoreConfidence" : [ + 24058.733581349974, + 24172.157992221073 + ], + "scorePercentiles" : { + "0.0" : 24003.718212152344, + "50.0" : 24115.037711851724, + "90.0" : 24239.528426026864, + "95.0" : 24268.40718552512, + "99.0" : 24269.011634468294, + "99.9" : 24269.011634468294, + "99.99" : 24269.011634468294, + "99.999" : 24269.011634468294, + "99.9999" : 24269.011634468294, + "100.0" : 24269.011634468294 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 24003.718212152344, + 24088.046961560114, + 24117.95276895766, + 24203.945966371793, + 24198.166912931043 + ], + [ + 24086.335688369483, + 24186.9520234635, + 24266.996804657712, + 24221.216173606295, + 24269.011634468294 + ], + [ + 24145.05433319021, + 24163.365997846973, + 24065.986502133033, + 24033.54113352273, + 24026.717048376093 + ], + [ + 24082.16534627719, + 24117.95064257814, + 24040.361787165337, + 24038.0734129532, + 24026.914052151424 + ], + [ + 24044.090160796768, + 24116.26719501939, + 24120.454450249414, + 24107.821748988215, + 24115.037711851724 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 365136.1015124029, + "scoreError" : 3.031104520526598E-4, + "scoreConfidence" : [ + 365136.1012092924, + 365136.10181551334 + ], + "scorePercentiles" : { + "0.0" : 365136.10059146176, + "50.0" : 365136.1016210286, + "90.0" : 365136.10203594057, + "95.0" : 365136.1021593235, + "99.0" : 365136.1021906248, + "99.9" : 365136.1021906248, + "99.99" : 365136.1021906248, + "99.999" : 365136.1021906248, + "99.9999" : 365136.1021906248, + "100.0" : 365136.1021906248 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 365136.10200237617, + 365136.10188728286, + 365136.101642178, + 365136.1013225348, + 365136.10098773596 + ], + [ + 365136.1016210286, + 365136.10145219264, + 365136.1010931702, + 365136.10137057153, + 365136.10059146176 + ], + [ + 365136.10186385503, + 365136.1007391185, + 365136.10156893934, + 365136.1016277219, + 365136.1020862872 + ], + [ + 365136.101717935, + 365136.1016685398, + 365136.10162919236, + 365136.1015968526, + 365136.1017307553 + ], + [ + 365136.1021906248, + 365136.10092961485, + 365136.1013140244, + 365136.10182112036, + 365136.1013549588 + ] + ] + }, + "gc.count" : { + "score" : 339.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 339.0, + 339.0 + ], + "scorePercentiles" : { + "0.0" : 13.0, + "50.0" : 14.0, + "90.0" : 14.0, + "95.0" : 14.0, + "99.0" : 14.0, + "99.9" : 14.0, + "99.99" : 14.0, + "99.999" : 14.0, + "99.9999" : 14.0, + "100.0" : 14.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 13.0, + 14.0, + 13.0, + 14.0, + 13.0 + ], + [ + 13.0, + 14.0, + 13.0, + 14.0, + 13.0 + ], + [ + 13.0, + 14.0, + 13.0, + 14.0, + 14.0 + ], + [ + 14.0, + 14.0, + 14.0, + 13.0, + 14.0 + ], + [ + 14.0, + 13.0, + 14.0, + 13.0, + 14.0 + ] + ] + }, + "gc.time" : { + "score" : 274.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 274.0, + 274.0 + ], + "scorePercentiles" : { + "0.0" : 10.0, + "50.0" : 11.0, + "90.0" : 12.0, + "95.0" : 12.0, + "99.0" : 12.0, + "99.9" : 12.0, + "99.99" : 12.0, + "99.999" : 12.0, + "99.9999" : 12.0, + "100.0" : 12.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 11.0, + 11.0, + 11.0, + 11.0, + 10.0 + ], + [ + 11.0, + 11.0, + 10.0, + 11.0, + 10.0 + ], + [ + 11.0, + 12.0, + 10.0, + 11.0, + 11.0 + ], + [ + 12.0, + 11.0, + 11.0, + 11.0, + 11.0 + ], + [ + 12.0, + 11.0, + 11.0, + 11.0, + 11.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.ComposedPageBench.jteIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 14510.638934538649, + "scoreError" : 27.34997326099579, + "scoreConfidence" : [ + 14483.288961277653, + 14537.988907799645 + ], + "scorePercentiles" : { + "0.0" : 14450.196202896877, + "50.0" : 14509.131890591254, + "90.0" : 14559.008761272793, + "95.0" : 14571.39348750591, + "99.0" : 14574.33708258057, + "99.9" : 14574.33708258057, + "99.99" : 14574.33708258057, + "99.999" : 14574.33708258057, + "99.9999" : 14574.33708258057, + "100.0" : 14574.33708258057 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 14552.885706801711, + 14555.331202789077, + 14543.546394150397, + 14527.38781376577, + 14518.230835012248 + ], + [ + 14489.283903400119, + 14469.877428307123, + 14472.62482662968, + 14450.196202896877, + 14457.593793790902 + ], + [ + 14530.500928181924, + 14509.131890591254, + 14517.728676438606, + 14550.756253635835, + 14564.525098998369 + ], + [ + 14539.160088228466, + 14532.787979966612, + 14496.831943962025, + 14503.619050379732, + 14508.086733585365 + ], + [ + 14574.33708258057, + 14489.963207601832, + 14455.2591287266, + 14495.32878241083, + 14460.998410634302 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 23999.571330382616, + "scoreError" : 45.4069253455604, + "scoreConfidence" : [ + 23954.164405037056, + 24044.978255728176 + ], + "scorePercentiles" : { + "0.0" : 23894.945049981427, + "50.0" : 24001.42517198234, + "90.0" : 24089.410087805016, + "95.0" : 24097.589949869944, + "99.0" : 24100.185568242265, + "99.9" : 24100.185568242265, + "99.99" : 24100.185568242265, + "99.999" : 24100.185568242265, + "99.9999" : 24100.185568242265, + "100.0" : 24100.185568242265 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 23929.29477868558, + 23923.981577478324, + 23945.010534804747, + 23972.608039608396, + 23986.34358867551 + ], + [ + 24035.377515986638, + 24068.333351970705, + 24062.24897218991, + 24100.185568242265, + 24087.99447500756 + ], + [ + 23967.206922037167, + 24001.42517198234, + 23986.989408625024, + 23933.621985446338, + 23909.769590428277 + ], + [ + 23951.55598832304, + 23963.895804163472, + 24021.98984074051, + 24011.71491914292, + 24002.47502379533 + ], + [ + 23894.945049981427, + 24033.706203788006, + 24091.5335070012, + 24025.9641949057, + 24081.111246554894 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 365240.1020538822, + "scoreError" : 2.2618786262310073E-4, + "scoreConfidence" : [ + 365240.10182769434, + 365240.1022800701 + ], + "scorePercentiles" : { + "0.0" : 365240.10152636445, + "50.0" : 365240.1019670465, + "90.0" : 365240.1025664935, + "95.0" : 365240.1025711141, + "99.0" : 365240.10257155733, + "99.9" : 365240.10257155733, + "99.99" : 365240.10257155733, + "99.999" : 365240.10257155733, + "99.9999" : 365240.10257155733, + "100.0" : 365240.10257155733 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 365240.10244768474, + 365240.1020337013, + 365240.10257155733, + 365240.1024375372, + 365240.1022712449 + ], + [ + 365240.10198907676, + 365240.10152636445, + 365240.1019417476, + 365240.1017946794, + 365240.1019343841 + ], + [ + 365240.10256410256, + 365240.1018133326, + 365240.1018369507, + 365240.1021524142, + 365240.1022594922 + ], + [ + 365240.1021592756, + 365240.1019670465, + 365240.1016556675, + 365240.1022667981, + 365240.10173959646 + ], + [ + 365240.10257007985, + 365240.1017440176, + 365240.1019181881, + 365240.1018015276, + 365240.1019505852 + ] + ] + }, + "gc.count" : { + "score" : 338.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 338.0, + 338.0 + ], + "scorePercentiles" : { + "0.0" : 13.0, + "50.0" : 14.0, + "90.0" : 14.0, + "95.0" : 14.0, + "99.0" : 14.0, + "99.9" : 14.0, + "99.99" : 14.0, + "99.999" : 14.0, + "99.9999" : 14.0, + "100.0" : 14.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 13.0, + 13.0, + 14.0, + 13.0, + 13.0 + ], + [ + 13.0, + 14.0, + 13.0, + 14.0, + 14.0 + ], + [ + 14.0, + 14.0, + 13.0, + 14.0, + 14.0 + ], + [ + 13.0, + 14.0, + 13.0, + 13.0, + 14.0 + ], + [ + 13.0, + 14.0, + 14.0, + 13.0, + 14.0 + ] + ] + }, + "gc.time" : { + "score" : 273.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 273.0, + 273.0 + ], + "scorePercentiles" : { + "0.0" : 10.0, + "50.0" : 11.0, + "90.0" : 11.400000000000002, + "95.0" : 12.0, + "99.0" : 12.0, + "99.9" : 12.0, + "99.99" : 12.0, + "99.999" : 12.0, + "99.9999" : 12.0, + "100.0" : 12.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 11.0, + 11.0, + 11.0, + 11.0, + 10.0 + ], + [ + 11.0, + 11.0, + 10.0, + 11.0, + 11.0 + ], + [ + 12.0, + 11.0, + 10.0, + 11.0, + 11.0 + ], + [ + 11.0, + 11.0, + 10.0, + 11.0, + 11.0 + ], + [ + 11.0, + 11.0, + 12.0, + 11.0, + 11.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.ComposedPageBench.thymeleafControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 21517.49661598815, + "scoreError" : 101.44997337177426, + "scoreConfidence" : [ + 21416.046642616377, + 21618.946589359926 + ], + "scorePercentiles" : { + "0.0" : 21320.62051183703, + "50.0" : 21560.10385021438, + "90.0" : 21690.333338580724, + "95.0" : 21717.80442734334, + "99.0" : 21728.960858421306, + "99.9" : 21728.960858421306, + "99.99" : 21728.960858421306, + "99.999" : 21728.960858421306, + "99.9999" : 21728.960858421306, + "100.0" : 21728.960858421306 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 21689.373727749145, + 21691.772754828093, + 21614.918988982503, + 21596.837970257497, + 21560.10385021438 + ], + [ + 21350.94608992116, + 21361.95526911093, + 21390.82660859912, + 21406.86389773626, + 21423.228952772075 + ], + [ + 21362.376110731373, + 21374.036121429486, + 21367.896726247676, + 21323.946033505264, + 21320.62051183703 + ], + [ + 21685.446985446986, + 21671.591548685978, + 21574.33378573429, + 21521.544549345148, + 21522.2733231609 + ], + [ + 21728.960858421306, + 21643.06348382633, + 21610.439904209186, + 21566.91024314537, + 21577.147103806303 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 15750.185518797613, + "scoreError" : 74.2608408439207, + "scoreConfidence" : [ + 15675.924677953692, + 15824.446359641533 + ], + "scorePercentiles" : { + "0.0" : 15596.55315087774, + "50.0" : 15718.239967444728, + "90.0" : 15880.842070520119, + "95.0" : 15893.790845981608, + "99.0" : 15894.227259136793, + "99.9" : 15894.227259136793, + "99.99" : 15894.227259136793, + "99.999" : 15894.227259136793, + "99.9999" : 15894.227259136793, + "100.0" : 15894.227259136793 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 15625.185383690437, + 15623.269412118034, + 15677.873891668618, + 15691.874589062809, + 15718.239967444728 + ], + [ + 15872.888418453858, + 15863.535861023875, + 15842.571217846033, + 15830.959852151931, + 15818.70447786455 + ], + [ + 15864.426936205475, + 15855.808608361445, + 15860.178841961408, + 15892.77254861951, + 15894.227259136793 + ], + [ + 15628.075033685831, + 15637.945566138413, + 15708.350376592329, + 15746.700814401755, + 15746.339583315252 + ], + [ + 15596.55315087774, + 15658.512412520175, + 15681.196505310021, + 15713.530126158592, + 15704.917135330732 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 355424.151956972, + "scoreError" : 0.0011511616949755998, + "scoreConfidence" : [ + 355424.15080581035, + 355424.1531081337 + ], + "scorePercentiles" : { + "0.0" : 355424.1499508988, + "50.0" : 355424.1518768379, + "90.0" : 355424.15498558455, + "95.0" : 355424.1557314874, + "99.0" : 355424.1558712368, + "99.9" : 355424.1558712368, + "99.99" : 355424.1558712368, + "99.999" : 355424.1558712368, + "99.9999" : 355424.1558712368, + "100.0" : 355424.1558712368 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 355424.154705704, + 355424.1520741318, + 355424.1517390365, + 355424.15229543933, + 355424.1520263719 + ], + [ + 355424.15290858725, + 355424.15058261127, + 355424.1499508988, + 355424.15083046537, + 355424.1502395619 + ], + [ + 355424.1532809296, + 355424.15063404635, + 355424.1506822987, + 355424.1503900422, + 355424.15035479126 + ], + [ + 355424.1554054054, + 355424.15205437934, + 355424.15200672136, + 355424.1517451988, + 355424.15164084156 + ], + [ + 355424.1558712368, + 355424.1518768379, + 355424.1522297254, + 355424.15140541474, + 355424.1519936239 + ] + ] + }, + "gc.count" : { + "score" : 255.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 255.0, + 255.0 + ], + "scorePercentiles" : { + "0.0" : 10.0, + "50.0" : 10.0, + "90.0" : 11.0, + "95.0" : 11.0, + "99.0" : 11.0, + "99.9" : 11.0, + "99.99" : 11.0, + "99.999" : 11.0, + "99.9999" : 11.0, + "100.0" : 11.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 10.0, + 10.0, + 10.0, + 11.0, + 10.0 + ], + [ + 10.0, + 10.0, + 10.0, + 10.0, + 11.0 + ], + [ + 10.0, + 10.0, + 10.0, + 10.0, + 11.0 + ], + [ + 10.0, + 10.0, + 11.0, + 10.0, + 10.0 + ], + [ + 10.0, + 10.0, + 11.0, + 10.0, + 10.0 + ] + ] + }, + "gc.time" : { + "score" : 206.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 206.0, + 206.0 + ], + "scorePercentiles" : { + "0.0" : 8.0, + "50.0" : 8.0, + "90.0" : 9.0, + "95.0" : 10.399999999999999, + "99.0" : 11.0, + "99.9" : 11.0, + "99.99" : 11.0, + "99.999" : 11.0, + "99.9999" : 11.0, + "100.0" : 11.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 8.0, + 9.0, + 8.0, + 8.0, + 8.0 + ], + [ + 8.0, + 8.0, + 8.0, + 8.0, + 8.0 + ], + [ + 8.0, + 8.0, + 8.0, + 8.0, + 9.0 + ], + [ + 8.0, + 8.0, + 9.0, + 8.0, + 8.0 + ], + [ + 8.0, + 8.0, + 11.0, + 8.0, + 8.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.ComposedPageBench.thymeleafIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 21440.9336713081, + "scoreError" : 68.17109098072646, + "scoreConfidence" : [ + 21372.762580327373, + 21509.104762288825 + ], + "scorePercentiles" : { + "0.0" : 21310.59268868426, + "50.0" : 21432.61009252913, + "90.0" : 21580.91438150473, + "95.0" : 21674.818728657716, + "99.0" : 21696.49069601196, + "99.9" : 21696.49069601196, + "99.99" : 21696.49069601196, + "99.999" : 21696.49069601196, + "99.9999" : 21696.49069601196, + "100.0" : 21696.49069601196 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 21378.028169014084, + 21434.429528764424, + 21429.643989375374, + 21432.61009252913, + 21468.686717007036 + ], + [ + 21357.866319518544, + 21327.570322663196, + 21352.88723984988, + 21310.59268868426, + 21329.726331045655 + ], + [ + 21449.11255272229, + 21459.150067540042, + 21458.07909846602, + 21466.988541264323, + 21411.33411789879 + ], + [ + 21489.783122181663, + 21397.902860318954, + 21399.132793643334, + 21415.40535913021, + 21360.807666858764 + ], + [ + 21696.49069601196, + 21624.250804831147, + 21552.023432620448, + 21491.32141861014, + 21529.517852152792 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 15779.485116513693, + "scoreError" : 49.856301947765246, + "scoreConfidence" : [ + 15729.628814565927, + 15829.34141846146 + ], + "scorePercentiles" : { + "0.0" : 15593.863958788836, + "50.0" : 15783.945038681937, + "90.0" : 15862.3265777164, + "95.0" : 15872.178333445327, + "99.0" : 15875.980195883494, + "99.9" : 15875.980195883494, + "99.99" : 15875.980195883494, + "99.999" : 15875.980195883494, + "99.9999" : 15875.980195883494, + "100.0" : 15875.980195883494 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 15825.010986743579, + 15783.369753060515, + 15786.259866852435, + 15783.945038681937, + 15757.309938174254 + ], + [ + 15841.291998199411, + 15863.307321089605, + 15844.43362757866, + 15875.980195883494, + 15861.67274880093 + ], + [ + 15773.684283592502, + 15765.95822275952, + 15767.215007265504, + 15760.378045033498, + 15801.226283793956 + ], + [ + 15743.997038662335, + 15810.246931524656, + 15809.901990502212, + 15798.315333000824, + 15838.181712204958 + ], + [ + 15593.863958788836, + 15646.074705331945, + 15698.841566011466, + 15742.702799682236, + 15713.95855962303 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 354825.7513953184, + "scoreError" : 9.78602714397158, + "scoreConfidence" : [ + 354815.9653681744, + 354835.5374224624 + ], + "scorePercentiles" : { + "0.0" : 354800.1503843107, + "50.0" : 354832.15060357214, + "90.0" : 354832.15352237056, + "95.0" : 354832.1550416033, + "99.0" : 354832.1554491692, + "99.9" : 354832.1554491692, + "99.99" : 354832.1554491692, + "99.999" : 354832.1554491692, + "99.9999" : 354832.1554491692, + "100.0" : 354832.1554491692 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 354800.15245411865, + 354800.1503843107, + 354800.1504584012, + 354800.1511309116, + 354800.1513643384 + ], + [ + 354832.1531435401, + 354832.1504766373, + 354832.15046059364, + 354832.1500542288, + 354832.1503900422 + ], + [ + 354832.15295351873, + 354832.15060357214, + 354832.15116976603, + 354832.15140981076, + 354832.15029421204 + ], + [ + 354832.15409061627, + 354832.1501560563, + 354832.15071448404, + 354832.1503295951, + 354832.1506051098 + ], + [ + 354832.1554491692, + 354832.151761986, + 354832.15196743555, + 354832.1513870712, + 354832.1516734378 + ] + ] + }, + "gc.count" : { + "score" : 254.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 254.0, + 254.0 + ], + "scorePercentiles" : { + "0.0" : 10.0, + "50.0" : 10.0, + "90.0" : 11.0, + "95.0" : 11.0, + "99.0" : 11.0, + "99.9" : 11.0, + "99.99" : 11.0, + "99.999" : 11.0, + "99.9999" : 11.0, + "100.0" : 11.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 11.0, + 10.0, + 10.0, + 10.0, + 10.0 + ], + [ + 10.0, + 10.0, + 10.0, + 10.0, + 11.0 + ], + [ + 10.0, + 10.0, + 10.0, + 10.0, + 10.0 + ], + [ + 11.0, + 10.0, + 10.0, + 10.0, + 10.0 + ], + [ + 11.0, + 10.0, + 10.0, + 10.0, + 10.0 + ] + ] + }, + "gc.time" : { + "score" : 206.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 206.0, + 206.0 + ], + "scorePercentiles" : { + "0.0" : 7.0, + "50.0" : 8.0, + "90.0" : 9.0, + "95.0" : 9.7, + "99.0" : 10.0, + "99.9" : 10.0, + "99.99" : 10.0, + "99.999" : 10.0, + "99.9999" : 10.0, + "100.0" : 10.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 9.0, + 8.0, + 8.0, + 7.0, + 8.0 + ], + [ + 8.0, + 7.0, + 9.0, + 8.0, + 10.0 + ], + [ + 8.0, + 8.0, + 8.0, + 7.0, + 8.0 + ], + [ + 9.0, + 8.0, + 9.0, + 8.0, + 9.0 + ], + [ + 9.0, + 8.0, + 8.0, + 8.0, + 9.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.ConditionalHeavyBench.jteControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 7422.925638550641, + "scoreError" : 86.45708490031316, + "scoreConfidence" : [ + 7336.468553650328, + 7509.3827234509545 + ], + "scorePercentiles" : { + "0.0" : 7287.536685722609, + "50.0" : 7407.954511801463, + "90.0" : 7578.98602629895, + "95.0" : 7664.5615923726555, + "99.0" : 7699.436428868392, + "99.9" : 7699.436428868392, + "99.99" : 7699.436428868392, + "99.999" : 7699.436428868392, + "99.9999" : 7699.436428868392, + "100.0" : 7699.436428868392 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 7699.436428868392, + 7583.186973882604, + 7574.845906598601, + 7560.4524080880965, + 7571.164763063805 + ], + [ + 7429.741353740286, + 7384.268718765203, + 7344.201137823454, + 7341.846235115445, + 7323.4516994567875 + ], + [ + 7407.954511801463, + 7330.539645802511, + 7346.248944683038, + 7355.315194875788, + 7307.213964868714 + ], + [ + 7442.739526519937, + 7496.367694197298, + 7440.797995345275, + 7449.489932686007, + 7430.994881851744 + ], + [ + 7576.185394576512, + 7296.2304207308625, + 7302.046758022853, + 7290.8837866787135, + 7287.536685722609 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 5177.202803354501, + "scoreError" : 59.66157215047173, + "scoreConfidence" : [ + 5117.54123120403, + 5236.8643755049725 + ], + "scorePercentiles" : { + "0.0" : 4990.322788129226, + "50.0" : 5186.47534607365, + "90.0" : 5267.639685522161, + "95.0" : 5271.448932468645, + "99.0" : 5272.097655438341, + "99.9" : 5272.097655438341, + "99.99" : 5272.097655438341, + "99.999" : 5272.097655438341, + "99.9999" : 5272.097655438341, + "100.0" : 5272.097655438341 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 4990.322788129226, + 5066.919605617874, + 5072.045458197205, + 5081.944124789913, + 5074.493849481655 + ], + [ + 5171.43064169598, + 5203.109640100055, + 5231.3932269463685, + 5233.2900171021565, + 5246.156484841116 + ], + [ + 5186.47534607365, + 5241.4231865176025, + 5229.80349413727, + 5223.516647425703, + 5257.706008950031 + ], + [ + 5162.206653290751, + 5125.296051686282, + 5163.413828280858, + 5157.700733051914, + 5170.179570819302 + ], + [ + 5071.527453557496, + 5266.1093121773665, + 5261.573060015066, + 5269.935245539354, + 5272.097655438341 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 40296.05218071593, + "scoreError" : 6.586673357113471E-4, + "scoreConfidence" : [ + 40296.0515220486, + 40296.052839383265 + ], + "scorePercentiles" : { + "0.0" : 40296.05101006048, + "50.0" : 40296.05217688439, + "90.0" : 40296.05341107344, + "95.0" : 40296.05417045771, + "99.0" : 40296.05444774649, + "99.9" : 40296.05444774649, + "99.99" : 40296.05444774649, + "99.999" : 40296.05444774649, + "99.9999" : 40296.05444774649, + "100.0" : 40296.05444774649 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 40296.05444774649, + 40296.053219781636, + 40296.05312157307, + 40296.05301492177, + 40296.05333615535 + ], + [ + 40296.05220383224, + 40296.051774210195, + 40296.05179665994, + 40296.05176853829, + 40296.051352912364 + ], + [ + 40296.05235881186, + 40296.051210687445, + 40296.05156553977, + 40296.051829760974, + 40296.05130190264 + ], + [ + 40296.05231167056, + 40296.05260477517, + 40296.05246603761, + 40296.05230237684, + 40296.05217688439 + ], + [ + 40296.053523450566, + 40296.05101006048, + 40296.051486362245, + 40296.0511807868, + 40296.05115245967 + ] + ] + }, + "gc.count" : { + "score" : 136.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 136.0, + 136.0 + ], + "scorePercentiles" : { + "0.0" : 4.0, + "50.0" : 6.0, + "90.0" : 6.0, + "95.0" : 6.0, + "99.0" : 6.0, + "99.9" : 6.0, + "99.99" : 6.0, + "99.999" : 6.0, + "99.9999" : 6.0, + "100.0" : 6.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 6.0, + 6.0, + 6.0, + 5.0, + 6.0 + ], + [ + 6.0, + 6.0, + 6.0, + 6.0, + 6.0 + ], + [ + 5.0, + 4.0, + 5.0, + 5.0, + 5.0 + ], + [ + 6.0, + 6.0, + 5.0, + 6.0, + 6.0 + ], + [ + 5.0, + 5.0, + 5.0, + 5.0, + 4.0 + ] + ] + }, + "gc.time" : { + "score" : 130.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 130.0, + 130.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 5.0, + "90.0" : 9.0, + "95.0" : 9.7, + "99.0" : 10.0, + "99.9" : 10.0, + "99.99" : 10.0, + "99.999" : 10.0, + "99.9999" : 10.0, + "100.0" : 10.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 10.0, + 5.0, + 5.0, + 3.0, + 5.0 + ], + [ + 9.0, + 5.0, + 4.0, + 5.0, + 4.0 + ], + [ + 8.0, + 4.0, + 4.0, + 3.0, + 4.0 + ], + [ + 9.0, + 5.0, + 4.0, + 5.0, + 5.0 + ], + [ + 9.0, + 4.0, + 5.0, + 3.0, + 3.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.ConditionalHeavyBench.jteIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 12444.177590810717, + "scoreError" : 28.720310916354578, + "scoreConfidence" : [ + 12415.457279894363, + 12472.897901727072 + ], + "scorePercentiles" : { + "0.0" : 12382.712581666996, + "50.0" : 12446.350900766398, + "90.0" : 12473.846033879026, + "95.0" : 12558.800856382732, + "99.0" : 12587.391818456275, + "99.9" : 12587.391818456275, + "99.99" : 12587.391818456275, + "99.999" : 12587.391818456275, + "99.9999" : 12587.391818456275, + "100.0" : 12587.391818456275 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 12449.356409810402, + 12441.450320014914, + 12443.308291251025, + 12457.933721740863, + 12414.714785499838 + ], + [ + 12492.088611544461, + 12457.713004484305, + 12446.350900766398, + 12451.669401352427, + 12453.421196734369 + ], + [ + 12446.406351102483, + 12418.540225745968, + 12413.257331414678, + 12416.170429300138, + 12382.712581666996 + ], + [ + 12461.684315435405, + 12451.620687081768, + 12587.391818456275, + 12457.93373096415, + 12418.278983261005 + ], + [ + 12450.346483534257, + 12442.720814203774, + 12430.732610749266, + 12431.668198871965, + 12386.968565280835 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 12831.249888156106, + "scoreError" : 29.4639905124542, + "scoreConfidence" : [ + 12801.785897643651, + 12860.713878668561 + ], + "scorePercentiles" : { + "0.0" : 12684.819868418695, + "50.0" : 12829.353598120766, + "90.0" : 12874.063288192367, + "95.0" : 12893.42891993768, + "99.0" : 12894.920582613126, + "99.9" : 12894.920582613126, + "99.99" : 12894.920582613126, + "99.999" : 12894.920582613126, + "99.9999" : 12894.920582613126, + "100.0" : 12894.920582613126 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 12826.285265925524, + 12834.053182686452, + 12831.440142652275, + 12817.172387636641, + 12861.472347598545 + ], + [ + 12782.373091515747, + 12817.022502464935, + 12828.282789505474, + 12823.34013150131, + 12820.999274735454 + ], + [ + 12829.353598120766, + 12857.337822606147, + 12863.473231190626, + 12860.273392311845, + 12894.920582613126 + ], + [ + 12813.566057032675, + 12823.50896980209, + 12684.819868418695, + 12816.371284525678, + 12857.973234244966 + ], + [ + 12825.075466726226, + 12832.68877390016, + 12845.190543936222, + 12844.304888556157, + 12889.948373694975 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 167464.08755935225, + "scoreError" : 2.7560358124257054E-4, + "scoreConfidence" : [ + 167464.08728374867, + 167464.08783495583 + ], + "scorePercentiles" : { + "0.0" : 167464.08689492327, + "50.0" : 167464.08753690793, + "90.0" : 167464.0881045973, + "95.0" : 167464.08832827996, + "99.0" : 167464.08835664688, + "99.9" : 167464.08835664688, + "99.99" : 167464.08835664688, + "99.999" : 167464.08835664688, + "99.9999" : 167464.08835664688, + "100.0" : 167464.08835664688 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 167464.08786621277, + 167464.08689492327, + 167464.0877633772, + 167464.0878398566, + 167464.08753690793 + ], + [ + 167464.0882620905, + 167464.0874937718, + 167464.0877873992, + 167464.08731105807, + 167464.08781362008 + ], + [ + 167464.08799960182, + 167464.08721890405, + 167464.08713342928, + 167464.08717560474, + 167464.0869134825 + ], + [ + 167464.08770399902, + 167464.08736535735, + 167464.08835664688, + 167464.08746217733, + 167464.08748915064 + ], + [ + 167464.08758506575, + 167464.08739253232, + 167464.08770446974, + 167464.0876587075, + 167464.08725545966 + ] + ] + }, + "gc.count" : { + "score" : 205.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 205.0, + 205.0 + ], + "scorePercentiles" : { + "0.0" : 8.0, + "50.0" : 8.0, + "90.0" : 9.0, + "95.0" : 9.0, + "99.0" : 9.0, + "99.9" : 9.0, + "99.99" : 9.0, + "99.999" : 9.0, + "99.9999" : 9.0, + "100.0" : 9.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 8.0, + 8.0, + 8.0, + 9.0, + 8.0 + ], + [ + 8.0, + 8.0, + 8.0, + 9.0, + 8.0 + ], + [ + 8.0, + 8.0, + 8.0, + 9.0, + 8.0 + ], + [ + 8.0, + 8.0, + 8.0, + 8.0, + 9.0 + ], + [ + 8.0, + 8.0, + 8.0, + 9.0, + 8.0 + ] + ] + }, + "gc.time" : { + "score" : 166.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 166.0, + 166.0 + ], + "scorePercentiles" : { + "0.0" : 6.0, + "50.0" : 7.0, + "90.0" : 7.0, + "95.0" : 7.699999999999999, + "99.0" : 8.0, + "99.9" : 8.0, + "99.99" : 8.0, + "99.999" : 8.0, + "99.9999" : 8.0, + "100.0" : 8.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 7.0, + 7.0, + 6.0, + 6.0, + 7.0 + ], + [ + 6.0, + 7.0, + 6.0, + 8.0, + 6.0 + ], + [ + 7.0, + 7.0, + 6.0, + 7.0, + 6.0 + ], + [ + 6.0, + 7.0, + 7.0, + 6.0, + 7.0 + ], + [ + 7.0, + 7.0, + 6.0, + 7.0, + 7.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.ConditionalHeavyBench.thymeleafControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 461899.9717730614, + "scoreError" : 3351.4892233579785, + "scoreConfidence" : [ + 458548.4825497034, + 465251.46099641937 + ], + "scorePercentiles" : { + "0.0" : 453688.77320054325, + "50.0" : 462891.7668825162, + "90.0" : 467249.9805680979, + "95.0" : 467579.57301238255, + "99.0" : 467625.2803738318, + "99.9" : 467625.2803738318, + "99.99" : 467625.2803738318, + "99.999" : 467625.2803738318, + "99.9999" : 467625.2803738318, + "100.0" : 467625.2803738318 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 463158.00185013877, + 459566.5137614679, + 462891.7668825162, + 463206.1574074074, + 461991.5512465374 + ], + [ + 465365.3953488372, + 466528.05219012115, + 467625.2803738318, + 467472.9225023343, + 466583.4575955266 + ], + [ + 465181.4591078067, + 463911.48148148146, + 467101.3526119403, + 465447.3953488372, + 466984.0951492537 + ], + [ + 456120.28258887876, + 453688.77320054325, + 456644.3176631675, + 453770.566893424, + 454742.9090909091 + ], + [ + 459169.8026617715, + 458349.03846153844, + 460634.576427256, + 460045.1034482759, + 461319.041032734 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 1901.299654719565, + "scoreError" : 13.855969320819398, + "scoreConfidence" : [ + 1887.4436853987456, + 1915.1556240403845 + ], + "scorePercentiles" : { + "0.0" : 1877.7295503593275, + "50.0" : 1897.0008355753373, + "90.0" : 1932.581544915495, + "95.0" : 1935.4171091510764, + "99.0" : 1935.5360434951317, + "99.9" : 1935.5360434951317, + "99.99" : 1935.5360434951317, + "99.999" : 1935.5360434951317, + "99.9999" : 1935.5360434951317, + "100.0" : 1935.5360434951317 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 1896.1867845796653, + 1910.7686547116216, + 1897.0008355753373, + 1895.7692709611467, + 1900.6421230368035 + ], + [ + 1887.2756637997086, + 1882.2888250353528, + 1877.7295503593275, + 1878.4218955454712, + 1881.889838627879 + ], + [ + 1887.9731517066557, + 1892.821550351493, + 1879.881094820621, + 1886.655277805701, + 1880.2557609470189 + ], + [ + 1925.4599593716155, + 1935.5360434951317, + 1922.9272055428992, + 1935.1395956816139, + 1930.8761777380826 + ], + [ + 1912.6726837515298, + 1915.7149580774615, + 1906.319732851982, + 1908.8123712011336, + 1903.472362413857 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 920979.0082883426, + "scoreError" : 34.07782617181877, + "scoreConfidence" : [ + 920944.9304621709, + 921013.0861145144 + ], + "scorePercentiles" : { + "0.0" : 920955.2, + "50.0" : 920955.2910447761, + "90.0" : 921063.1537437799, + "95.0" : 921083.3029027405, + "99.0" : 921091.3190697675, + "99.9" : 921091.3190697675, + "99.99" : 921091.3190697675, + "99.999" : 921091.3190697675, + "99.9999" : 921091.3190697675, + "100.0" : 921091.3190697675 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 921062.1905642924, + 920956.0954128441, + 920955.2636447734, + 920955.2666666667, + 920955.2576177286 + ], + [ + 921091.3190697675, + 920989.5917986953, + 920955.2971962617, + 920955.2941176471, + 920955.2879776328 + ], + [ + 921064.5985130111, + 920956.1703703704, + 920955.2910447761, + 920955.2669767442, + 920955.2910447761 + ], + [ + 921056.0109389244, + 920956.2082390222, + 920955.2204472844, + 920955.2, + 920955.2072727273 + ], + [ + 921057.9054612208, + 920956.2564102564, + 920955.2338858196, + 920955.2294252873, + 920955.2531120332 + ] + ] + }, + "gc.count" : { + "score" : 55.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 55.0, + 55.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 2.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 2.0, + 2.0, + 2.0, + 3.0, + 2.0 + ], + [ + 2.0, + 2.0, + 2.0, + 2.0, + 3.0 + ], + [ + 2.0, + 2.0, + 2.0, + 2.0, + 3.0 + ], + [ + 2.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 2.0, + 2.0, + 2.0, + 3.0, + 2.0 + ] + ] + }, + "gc.time" : { + "score" : 109.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 109.0, + 109.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 4.0, + "90.0" : 6.0, + "95.0" : 6.699999999999999, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 4.0, + 4.0, + 3.0, + 6.0, + 5.0 + ], + [ + 4.0, + 4.0, + 3.0, + 4.0, + 6.0 + ], + [ + 4.0, + 4.0, + 4.0, + 4.0, + 7.0 + ], + [ + 3.0, + 4.0, + 6.0, + 4.0, + 4.0 + ], + [ + 4.0, + 4.0, + 4.0, + 5.0, + 5.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.ConditionalHeavyBench.thymeleafIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 457644.490039231, + "scoreError" : 2891.145587389209, + "scoreConfidence" : [ + 454753.34445184184, + 460535.6356266202 + ], + "scorePercentiles" : { + "0.0" : 452758.118498417, + "50.0" : 457878.32647462277, + "90.0" : 463874.8665249922, + "95.0" : 465050.79291107564, + "99.0" : 465330.83720930235, + "99.9" : 465330.83720930235, + "99.99" : 465330.83720930235, + "99.999" : 465330.83720930235, + "99.9999" : 465330.83720930235, + "100.0" : 465330.83720930235 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 459292.4346629986, + 459688.9756545705, + 454930.3774442929, + 454115.5485040798, + 454054.5825771325 + ], + [ + 463526.5400648448, + 464397.35621521337, + 458703.75974323705, + 459792.32536764705, + 465330.83720930235 + ], + [ + 460849.08003679855, + 461458.07195571956, + 457123.185759927, + 459099.4042163153, + 461660.93173431733 + ], + [ + 459280.1652892562, + 457878.32647462277, + 453192.39130434784, + 453456.0235507246, + 453318.115942029 + ], + [ + 455493.906321055, + 454321.2891511575, + 453780.0724637681, + 453610.43083900225, + 452758.118498417 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 2034.3656776355847, + "scoreError" : 29.846894891036584, + "scoreConfidence" : [ + 2004.5187827445482, + 2064.2125725266214 + ], + "scorePercentiles" : { + "0.0" : 1955.8588119415526, + "50.0" : 2047.1680276026627, + "90.0" : 2075.632230017872, + "95.0" : 2076.412804283042, + "99.0" : 2076.6027176144544, + "99.9" : 2076.6027176144544, + "99.99" : 2076.6027176144544, + "99.999" : 2076.6027176144544, + "99.9999" : 2076.6027176144544, + "100.0" : 2076.6027176144544 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 2049.0374917416157, + 2047.1680276026627, + 2068.6523659069676, + 2072.441314041752, + 2072.6264348543914 + ], + [ + 2030.2176118316552, + 2026.5505097077878, + 2051.592675030629, + 2046.850056387121, + 2022.4224216358564 + ], + [ + 2042.0115503203635, + 2039.4957559752559, + 2058.673323648132, + 2049.9457812718642, + 2038.436779806352 + ], + [ + 2049.049053672485, + 2055.385175396323, + 2076.6027176144544, + 2075.407267912178, + 2075.969673176413 + ], + [ + 1955.8588119415526, + 1960.5613097520625, + 1963.0790289417066, + 1963.7555828523293, + 1967.3512198677104 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 976457.6236052735, + "scoreError" : 16137.250466966187, + "scoreConfidence" : [ + 960320.3731383074, + 992594.8740722397 + ], + "scorePercentiles" : { + "0.0" : 934219.1811594203, + "50.0" : 987019.1985494107, + "90.0" : 987020.6415945299, + "95.0" : 987038.8634734269, + "99.0" : 987046.667903525, + "99.9" : 987046.667903525, + "99.99" : 987046.667903525, + "99.999" : 987046.667903525, + "99.9999" : 987046.667903525, + "100.0" : 987046.667903525 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 986971.3085740486, + 987020.6338998622, + 987019.2087312415, + 987019.1985494107, + 987019.2014519057 + ], + [ + 986989.9842519684, + 987046.667903525, + 987019.235213205, + 987019.2279411765, + 987019.2818604651 + ], + [ + 986967.8344066237, + 987020.6531365314, + 987019.2204472844, + 987019.2337305225, + 987019.2546125462 + ], + [ + 986960.1910009183, + 987019.5262917238, + 987019.195652174, + 987019.195652174, + 987019.195652174 + ], + [ + 934331.4597544338, + 934224.1089423513, + 934219.1811594203, + 934219.2, + 934219.1913161465 + ] + ] + }, + "gc.count" : { + "score" : 59.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 59.0, + 59.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 2.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 2.0, + 3.0, + 2.0, + 3.0, + 2.0 + ], + [ + 2.0, + 3.0, + 2.0, + 2.0, + 3.0 + ], + [ + 2.0, + 3.0, + 2.0, + 2.0, + 3.0 + ], + [ + 3.0, + 2.0, + 2.0, + 3.0, + 2.0 + ], + [ + 2.0, + 2.0, + 3.0, + 2.0, + 2.0 + ] + ] + }, + "gc.time" : { + "score" : 113.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 113.0, + 113.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 4.0, + "90.0" : 6.0, + "95.0" : 6.0, + "99.0" : 6.0, + "99.9" : 6.0, + "99.99" : 6.0, + "99.999" : 6.0, + "99.9999" : 6.0, + "100.0" : 6.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 4.0, + 5.0, + 4.0, + 6.0, + 3.0 + ], + [ + 3.0, + 6.0, + 4.0, + 4.0, + 5.0 + ], + [ + 4.0, + 6.0, + 4.0, + 3.0, + 6.0 + ], + [ + 6.0, + 4.0, + 5.0, + 6.0, + 3.0 + ], + [ + 4.0, + 4.0, + 6.0, + 4.0, + 4.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.EncodedLoopBench.jteControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1402244.3376164355, + "scoreError" : 339086.5670981891, + "scoreConfidence" : [ + 1063157.7705182463, + 1741330.9047146246 + ], + "scorePercentiles" : { + "0.0" : 1266106.329113924, + "50.0" : 1303947.0052083333, + "90.0" : 1415611.6126918383, + "95.0" : 2952147.976698735, + "99.0" : 3561855.1601423486, + "99.9" : 3561855.1601423486, + "99.99" : 3561855.1601423486, + "99.999" : 3561855.1601423486, + "99.9999" : 3561855.1601423486, + "100.0" : 3561855.1601423486 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1529497.8819969743, + 3561855.1601423486, + 1300877.8933680104, + 1299107.3929961089, + 1294520.1811125486 + ], + [ + 1274125.699745547, + 1272058.3227445998, + 1271256.035578145, + 1266106.329113924, + 1272075.6345177665 + ], + [ + 1302228.478543563, + 1292114.8387096773, + 1308028.2352941176, + 1300029.571984436, + 1308967.4934725848 + ], + [ + 1298886.5110246434, + 1303947.0052083333, + 1311386.9109947644, + 1311816.3612565445, + 1309114.9019607843 + ], + [ + 1339687.4331550803, + 1327762.4668435014, + 1330994.680851064, + 1335427.8666666667, + 1334235.153129161 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 7384.593319282563, + "scoreError" : 742.8024098656095, + "scoreConfidence" : [ + 6641.790909416954, + 8127.395729148173 + ], + "scorePercentiles" : { + "0.0" : 2787.7517557692004, + "50.0" : 7615.020770998845, + "90.0" : 7807.535757540917, + "95.0" : 7832.62929839992, + "99.0" : 7842.134111277666, + "99.9" : 7842.134111277666, + "99.99" : 7842.134111277666, + "99.999" : 7842.134111277666, + "99.9999" : 7842.134111277666, + "100.0" : 7842.134111277666 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 6489.451673100531, + 2787.7517557692004, + 7632.378685938768, + 7643.266711530422, + 7669.622391857015 + ], + [ + 7793.212160436831, + 7805.591994778076, + 7810.45140168518, + 7842.134111277666, + 7805.3836428453305 + ], + [ + 7625.220922175036, + 7684.9854800626335, + 7590.806231525276, + 7637.951178067648, + 7585.335185082739 + ], + [ + 7644.835657833605, + 7615.020770998845, + 7571.369556686471, + 7568.876420600756, + 7584.387955639491 + ], + [ + 7411.956449509008, + 7477.786677194495, + 7459.89825109722, + 7435.331650271449, + 7441.826066100396 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 1.0413865869724024E7, + "scoreError" : 2.3922280968055634, + "scoreConfidence" : [ + 1.0413863477495927E7, + 1.041386826195212E7 + ], + "scorePercentiles" : { + "0.0" : 1.0413864842639593E7, + "50.0" : 1.0413865196358908E7, + "90.0" : 1.0413865952303672E7, + "95.0" : 1.04138767869065E7, + "99.0" : 1.0413881110320285E7, + "99.9" : 1.0413881110320285E7, + "99.99" : 1.0413881110320285E7, + "99.999" : 1.0413881110320285E7, + "99.9999" : 1.0413881110320285E7, + "100.0" : 1.0413881110320285E7 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 1.0413866698940998E7, + 1.0413881110320285E7, + 1.0413865175552666E7, + 1.0413865151750972E7, + 1.0413865128072444E7 + ], + [ + 1.041386499745547E7, + 1.0413864965692503E7, + 1.0413864965692503E7, + 1.0413864891139241E7, + 1.0413864842639593E7 + ], + [ + 1.0413865196358908E7, + 1.0413865063225806E7, + 1.0413865223529411E7, + 1.0413865151750972E7, + 1.041386521148825E7 + ], + [ + 1.0413865172503242E7, + 1.0413865145833334E7, + 1.0413865235602094E7, + 1.0413865235602094E7, + 1.0413865223529411E7 + ], + [ + 1.0413865454545455E7, + 1.0413865358090186E7, + 1.0413865382978724E7, + 1.0413865365333334E7, + 1.0413865395472704E7 + ] + ] + }, + "gc.count" : { + "score" : 142.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 142.0, + 142.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 6.0, + "90.0" : 6.0, + "95.0" : 6.0, + "99.0" : 6.0, + "99.9" : 6.0, + "99.99" : 6.0, + "99.999" : 6.0, + "99.9999" : 6.0, + "100.0" : 6.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 5.0, + 2.0, + 6.0, + 6.0, + 6.0 + ], + [ + 6.0, + 6.0, + 6.0, + 6.0, + 6.0 + ], + [ + 6.0, + 6.0, + 6.0, + 5.0, + 6.0 + ], + [ + 6.0, + 5.0, + 6.0, + 6.0, + 6.0 + ], + [ + 5.0, + 6.0, + 6.0, + 6.0, + 6.0 + ] + ] + }, + "gc.time" : { + "score" : 134.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 134.0, + 134.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 5.0, + "90.0" : 7.400000000000002, + "95.0" : 8.0, + "99.0" : 8.0, + "99.9" : 8.0, + "99.99" : 8.0, + "99.999" : 8.0, + "99.9999" : 8.0, + "100.0" : 8.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 7.0, + 2.0, + 5.0, + 6.0, + 4.0 + ], + [ + 8.0, + 5.0, + 5.0, + 6.0, + 4.0 + ], + [ + 7.0, + 6.0, + 5.0, + 4.0, + 5.0 + ], + [ + 8.0, + 4.0, + 5.0, + 5.0, + 5.0 + ], + [ + 7.0, + 6.0, + 5.0, + 5.0, + 5.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.EncodedLoopBench.jteIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1072306.7145508153, + "scoreError" : 6388.23628040969, + "scoreConfidence" : [ + 1065918.4782704057, + 1078694.950831225 + ], + "scorePercentiles" : { + "0.0" : 1056750.0527983105, + "50.0" : 1072088.449197861, + "90.0" : 1083972.6406926408, + "95.0" : 1084356.0064935065, + "99.0" : 1084449.6753246754, + "99.9" : 1084449.6753246754, + "99.99" : 1084449.6753246754, + "99.999" : 1084449.6753246754, + "99.9999" : 1084449.6753246754, + "100.0" : 1084449.6753246754 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1083541.2972972973, + 1079094.9353448276, + 1083579.6536796538, + 1084137.445887446, + 1083862.7705627705 + ], + [ + 1067548.5592315902, + 1066142.0212765958, + 1075111.2781954887, + 1064161.2765957448, + 1065435.319148936 + ], + [ + 1079611.2068965517, + 1078379.5258620689, + 1084449.6753246754, + 1083170.3783783785, + 1073826.287553648 + ], + [ + 1072232.0855614974, + 1066728.9669861554, + 1066525.0266240682, + 1063339.638682253, + 1056750.0527983105 + ], + [ + 1072088.449197861, + 1064247.3963868225, + 1065043.9361702127, + 1064860.1487778958, + 1063800.531349628 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 5300.614381439394, + "scoreError" : 31.564907459933927, + "scoreConfidence" : [ + 5269.049473979459, + 5332.179288899328 + ], + "scorePercentiles" : { + "0.0" : 5240.684854880882, + "50.0" : 5301.534142269072, + "90.0" : 5343.632442056125, + "95.0" : 5368.176294775333, + "99.0" : 5378.010563127357, + "99.9" : 5378.010563127357, + "99.99" : 5378.010563127357, + "99.999" : 5378.010563127357, + "99.9999" : 5378.010563127357, + "100.0" : 5378.010563127357 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 5245.592984465146, + 5266.880440777946, + 5244.896310778412, + 5242.371354283969, + 5243.5115728080145 + ], + [ + 5323.797717397405, + 5331.176152269283, + 5286.534351340781, + 5340.998578975254, + 5334.182130558118 + ], + [ + 5264.658685165486, + 5270.541750575469, + 5240.684854880882, + 5247.074754911925, + 5292.57456458413 + ], + [ + 5300.864250620049, + 5328.050351062745, + 5329.2211378986485, + 5345.229668620612, + 5378.010563127357 + ], + [ + 5301.534142269072, + 5340.479728067015, + 5336.393627914542, + 5337.532238286138, + 5342.567624346468 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 5960848.384987824, + "scoreError" : 9.533013767634525, + "scoreConfidence" : [ + 5960838.851974056, + 5960857.918001591 + ], + "scorePercentiles" : { + "0.0" : 5960823.602956706, + "50.0" : 5960855.5063829785, + "90.0" : 5960855.6269592475, + "95.0" : 5960855.636363637, + "99.0" : 5960855.636363637, + "99.9" : 5960855.636363637, + "99.99" : 5960855.636363637, + "99.999" : 5960855.636363637, + "99.9999" : 5960855.636363637, + "100.0" : 5960855.636363637 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 5960855.610810811, + 5960855.6034482755, + 5960855.636363637, + 5960852.909090909, + 5960823.636363637 + ], + [ + 5960855.547491996, + 5960855.5063829785, + 5960855.578947368, + 5960851.089361702, + 5960823.659574468 + ], + [ + 5960855.620689655, + 5960855.6034482755, + 5960855.636363637, + 5960852.557837837, + 5960823.725321888 + ], + [ + 5960855.5636363635, + 5960855.514376997, + 5960855.514376997, + 5960850.746014878, + 5960823.602956706 + ], + [ + 5960855.5636363635, + 5960855.498405951, + 5960855.5063829785, + 5960850.54197662, + 5960823.651434644 + ] + ] + }, + "gc.count" : { + "score" : 127.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 127.0, + 127.0 + ], + "scorePercentiles" : { + "0.0" : 4.0, + "50.0" : 5.0, + "90.0" : 6.0, + "95.0" : 6.0, + "99.0" : 6.0, + "99.9" : 6.0, + "99.99" : 6.0, + "99.999" : 6.0, + "99.9999" : 6.0, + "100.0" : 6.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 5.0, + 5.0, + 5.0, + 5.0, + 5.0 + ], + [ + 5.0, + 6.0, + 4.0, + 5.0, + 6.0 + ], + [ + 5.0, + 5.0, + 5.0, + 5.0, + 5.0 + ], + [ + 5.0, + 6.0, + 5.0, + 5.0, + 5.0 + ], + [ + 5.0, + 5.0, + 5.0, + 5.0, + 5.0 + ] + ] + }, + "gc.time" : { + "score" : 137.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 137.0, + 137.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 5.0, + "90.0" : 9.0, + "95.0" : 9.7, + "99.0" : 10.0, + "99.9" : 10.0, + "99.99" : 10.0, + "99.999" : 10.0, + "99.9999" : 10.0, + "100.0" : 10.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 9.0, + 6.0, + 4.0, + 5.0, + 4.0 + ], + [ + 10.0, + 6.0, + 3.0, + 4.0, + 5.0 + ], + [ + 9.0, + 6.0, + 4.0, + 4.0, + 4.0 + ], + [ + 9.0, + 6.0, + 4.0, + 5.0, + 4.0 + ], + [ + 9.0, + 4.0, + 4.0, + 5.0, + 4.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.EncodedLoopBench.thymeleafControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 8309713.960434449, + "scoreError" : 37794.1838722099, + "scoreConfidence" : [ + 8271919.776562239, + 8347508.144306659 + ], + "scorePercentiles" : { + "0.0" : 8218213.1147540985, + "50.0" : 8300337.190082645, + "90.0" : 8380472.5, + "95.0" : 8400104.833333334, + "99.0" : 8407605.833333334, + "99.9" : 8407605.833333334, + "99.99" : 8407605.833333334, + "99.999" : 8407605.833333334, + "99.9999" : 8407605.833333334, + "100.0" : 8407605.833333334 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8258673.770491803, + 8268473.770491803, + 8324696.694214876, + 8270489.344262295, + 8321732.231404958 + ], + [ + 8300337.190082645, + 8256487.7049180325, + 8326391.73553719, + 8218213.1147540985, + 8250550.819672131 + ], + [ + 8278228.099173553, + 8311033.884297521, + 8311242.148760331, + 8279843.8016528925, + 8271466.115702479 + ], + [ + 8364899.166666667, + 8378825.0, + 8407605.833333334, + 8379052.5, + 8382602.5 + ], + [ + 8263930.327868853, + 8295405.785123967, + 8352692.5, + 8376871.666666667, + 8293103.305785124 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 2663.026212440345, + "scoreError" : 12.103352766625957, + "scoreConfidence" : [ + 2650.922859673719, + 2675.1295652069707 + ], + "scorePercentiles" : { + "0.0" : 2631.959713839734, + "50.0" : 2666.0777842988505, + "90.0" : 2680.922633840119, + "95.0" : 2689.4298319216973, + "99.0" : 2692.6269711163754, + "99.9" : 2692.6269711163754, + "99.99" : 2692.6269711163754, + "99.999" : 2692.6269711163754, + "99.9999" : 2692.6269711163754, + "100.0" : 2692.6269711163754 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 2679.5339657017935, + 2676.2104255128165, + 2658.021511142723, + 2675.423673425538, + 2659.0758773799453 + ], + [ + 2666.0777842988505, + 2680.2244960885664, + 2657.503221169204, + 2692.6269711163754, + 2681.969840467448 + ], + [ + 2673.2048657296473, + 2662.5626033979847, + 2662.4249613139596, + 2672.4822976324103, + 2675.187943918881 + ], + [ + 2645.3859330521746, + 2640.921398162181, + 2631.959713839734, + 2640.9818171711318, + 2639.69774832928 + ], + [ + 2677.6436711591446, + 2667.5796131663406, + 2649.055439197698, + 2641.5769976726006, + 2668.3225409621896 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 2.3207933688992824E7, + "scoreError" : 2.7910834678248255, + "scoreConfidence" : [ + 2.320793089790936E7, + 2.320793648007629E7 + ], + "scorePercentiles" : { + "0.0" : 2.3207929573770493E7, + "50.0" : 2.3207932165289257E7, + "90.0" : 2.3207939489807162E7, + "95.0" : 2.3207939853333335E7, + "99.0" : 2.3207939933333334E7, + "99.9" : 2.3207939933333334E7, + "99.99" : 2.3207939933333334E7, + "99.999" : 2.3207939933333334E7, + "99.9999" : 2.3207939933333334E7, + "100.0" : 2.3207939933333334E7 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 2.3207935672131147E7, + 2.320793193442623E7, + 2.3207939371900827E7, + 2.3207929573770493E7, + 2.3207930314049587E7 + ], + [ + 2.3207936198347107E7, + 2.3207931672131147E7, + 2.3207939371900827E7, + 2.3207929836065575E7, + 2.3207929836065575E7 + ], + [ + 2.3207936462809917E7, + 2.3207932429752067E7, + 2.3207939371900827E7, + 2.3207930314049587E7, + 2.3207930314049587E7 + ], + [ + 2.3207936733333334E7, + 2.3207932933333334E7, + 2.3207939666666668E7, + 2.32079308E7, + 2.32079308E7 + ], + [ + 2.3207935672131147E7, + 2.3207932165289257E7, + 2.3207939933333334E7, + 2.3207930533333335E7, + 2.3207930314049587E7 + ] + ] + }, + "gc.count" : { + "score" : 75.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 75.0, + 75.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 3.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ] + ] + }, + "gc.time" : { + "score" : 118.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 118.0, + 118.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 5.0, + "90.0" : 6.0, + "95.0" : 6.699999999999999, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 6.0, + 5.0, + 7.0, + 3.0, + 3.0 + ], + [ + 6.0, + 5.0, + 6.0, + 4.0, + 2.0 + ], + [ + 6.0, + 5.0, + 6.0, + 4.0, + 2.0 + ], + [ + 6.0, + 6.0, + 6.0, + 3.0, + 3.0 + ], + [ + 6.0, + 6.0, + 6.0, + 4.0, + 2.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.EncodedLoopBench.thymeleafIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 8849899.729657264, + "scoreError" : 55208.000309277755, + "scoreConfidence" : [ + 8794691.729347987, + 8905107.729966542 + ], + "scorePercentiles" : { + "0.0" : 8755156.52173913, + "50.0" : 8840071.05263158, + "90.0" : 8945190.535714285, + "95.0" : 9015072.052767053, + "99.0" : 9043985.585585585, + "99.9" : 9043985.585585585, + "99.99" : 9043985.585585585, + "99.999" : 9043985.585585585, + "99.9999" : 9043985.585585585, + "100.0" : 9043985.585585585 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8840071.05263158, + 8892180.530973451, + 9043985.585585585, + 8772786.086956521, + 8760409.56521739 + ], + [ + 8801164.03508772, + 8756199.130434783, + 8799143.859649124, + 8812400.0, + 8755156.52173913 + ], + [ + 8866761.061946902, + 8792135.087719299, + 8829144.736842105, + 8766060.0, + 8797293.859649124 + ], + [ + 8943579.464285715, + 8941063.392857144, + 8947607.142857144, + 8919646.902654868, + 8878361.946902655 + ], + [ + 8905469.911504425, + 8876136.283185842, + 8886727.433628319, + 8852161.403508771, + 8811848.245614035 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 2581.019537990305, + "scoreError" : 16.01197317439999, + "scoreConfidence" : [ + 2565.007564815905, + 2597.0315111647046 + ], + "scorePercentiles" : { + "0.0" : 2525.3100199431924, + "50.0" : 2583.835009903909, + "90.0" : 2607.7433571165716, + "95.0" : 2608.57968942118, + "99.0" : 2608.6124163275313, + "99.9" : 2608.6124163275313, + "99.99" : 2608.6124163275313, + "99.999" : 2608.6124163275313, + "99.9999" : 2608.6124163275313, + "100.0" : 2608.6124163275313 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 2583.835009903909, + 2568.570378840906, + 2525.3100199431924, + 2603.5562948813968, + 2607.2367107678238 + ], + [ + 2595.258337933851, + 2608.5033266396936, + 2595.5752966919968, + 2591.905809204293, + 2608.6124163275313 + ], + [ + 2576.064853041506, + 2597.80422070486, + 2586.8718055068125, + 2605.477386074657, + 2596.24597900203 + ], + [ + 2553.9254483423974, + 2554.626981217383, + 2552.6512917979785, + 2560.658536067778, + 2572.456925542343 + ], + [ + 2564.8632559892244, + 2573.263635353161, + 2570.063345772315, + 2580.237863893517, + 2591.9133203170563 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 2.39545617597298E7, + "scoreError" : 3.1850495615205854, + "scoreConfidence" : [ + 2.395455857468024E7, + 2.395456494477936E7 + ], + "scorePercentiles" : { + "0.0" : 2.395455707826087E7, + "50.0" : 2.395456042477876E7, + "90.0" : 2.3954568399241466E7, + "95.0" : 2.3954569244723298E7, + "99.0" : 2.3954569441441443E7, + "99.9" : 2.3954569441441443E7, + "99.99" : 2.3954569441441443E7, + "99.999" : 2.3954569441441443E7, + "99.9999" : 2.3954569441441443E7, + "100.0" : 2.3954569441441443E7 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 2.395456414035088E7, + 2.395456042477876E7, + 2.3954569441441443E7, + 2.395455707826087E7, + 2.395455735652174E7 + ], + [ + 2.395456414035088E7, + 2.3954559304347824E7, + 2.395456750877193E7, + 2.395455761403509E7, + 2.395455735652174E7 + ], + [ + 2.3954564743362833E7, + 2.395456014035088E7, + 2.3954567228070177E7, + 2.395455735652174E7, + 2.395455789473684E7 + ], + [ + 2.395456564285714E7, + 2.3954561285714287E7, + 2.3954568785714287E7, + 2.3954558442477874E7, + 2.3954558442477874E7 + ], + [ + 2.3954565026548672E7, + 2.3954560707964603E7, + 2.395456814159292E7, + 2.395455789473684E7, + 2.395455789473684E7 + ] + ] + }, + "gc.count" : { + "score" : 74.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 74.0, + 74.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 3.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 2.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ] + ] + }, + "gc.time" : { + "score" : 116.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 116.0, + 116.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 5.0, + "90.0" : 6.0, + "95.0" : 6.699999999999999, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 6.0, + 5.0, + 6.0, + 4.0, + 2.0 + ], + [ + 5.0, + 6.0, + 6.0, + 4.0, + 2.0 + ], + [ + 6.0, + 5.0, + 7.0, + 3.0, + 3.0 + ], + [ + 5.0, + 4.0, + 6.0, + 5.0, + 2.0 + ], + [ + 6.0, + 6.0, + 6.0, + 4.0, + 2.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.FortunesEncodedBench.jteControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1672.5222531550926, + "scoreError" : 26.40325753260735, + "scoreConfidence" : [ + 1646.1189956224853, + 1698.9255106877 + ], + "scorePercentiles" : { + "0.0" : 1627.8486387640687, + "50.0" : 1659.068538912511, + "90.0" : 1724.5501515852775, + "95.0" : 1734.0941930252077, + "99.0" : 1737.7491760624457, + "99.9" : 1737.7491760624457, + "99.99" : 1737.7491760624457, + "99.999" : 1737.7491760624457, + "99.9999" : 1737.7491760624457, + "100.0" : 1737.7491760624457 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1650.235411260835, + 1640.5636670322158, + 1653.6967251742412, + 1652.9589616414682, + 1659.068538912511 + ], + [ + 1678.6496907112803, + 1637.014605816464, + 1655.611022926084, + 1643.6066193076829, + 1638.0078162733698 + ], + [ + 1737.7491760624457, + 1723.8729864610277, + 1721.9773183774844, + 1720.8464041395946, + 1725.5658992716524 + ], + [ + 1674.1776423042904, + 1711.3080723297724, + 1679.7489881125255, + 1696.4042010324572, + 1702.410271314865 + ], + [ + 1641.7557976850264, + 1676.1882830542907, + 1633.232944510282, + 1630.5566464013766, + 1627.8486387640687 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 15795.796576626291, + "scoreError" : 247.10201736855294, + "scoreConfidence" : [ + 15548.694559257738, + 16042.898593994845 + ], + "scorePercentiles" : { + "0.0" : 15196.92512477569, + "50.0" : 15915.417103272122, + "90.0" : 16179.805520706463, + "95.0" : 16214.579894201293, + "99.0" : 16222.699931413823, + "99.9" : 16222.699931413823, + "99.99" : 16222.699931413823, + "99.999" : 16222.699931413823, + "99.9999" : 16222.699931413823, + "100.0" : 16222.699931413823 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 16002.715287807017, + 16097.084042344644, + 15969.137897947036, + 15975.996674002281, + 15915.417103272122 + ], + [ + 15731.974030239711, + 16131.909579592333, + 15949.108547304288, + 16066.491881568883, + 16121.69242251797 + ], + [ + 15196.92512477569, + 15319.125643576575, + 15335.09644895502, + 15346.422598037947, + 15303.731540026707 + ], + [ + 15773.87243386774, + 15431.65580433795, + 15721.871087983522, + 15566.474135622158, + 15511.550103683338 + ], + [ + 16085.133936029271, + 15753.941246005379, + 16169.253774040511, + 16195.633140705391, + 16222.699931413823 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 27696.011749678277, + "scoreError" : 1.830419578905241E-4, + "scoreConfidence" : [ + 27696.01156663632, + 27696.011932720234 + ], + "scorePercentiles" : { + "0.0" : 27696.011427418645, + "50.0" : 27696.011639120967, + "90.0" : 27696.012097555144, + "95.0" : 27696.012178159486, + "99.0" : 27696.012211621855, + "99.9" : 27696.012211621855, + "99.99" : 27696.012211621855, + "99.999" : 27696.012211621855, + "99.9999" : 27696.012211621855, + "100.0" : 27696.012211621855 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 27696.011605709216, + 27696.0115664357, + 27696.011614428746, + 27696.011604872594, + 27696.011639120967 + ], + [ + 27696.01180158584, + 27696.011497394917, + 27696.011626078565, + 27696.011536976963, + 27696.011500105604 + ], + [ + 27696.012211621855, + 27696.01209587149, + 27696.012089521668, + 27696.012066945434, + 27696.01210008062 + ], + [ + 27696.0117712564, + 27696.01201959687, + 27696.011845504803, + 27696.011908011293, + 27696.01193832996 + ], + [ + 27696.011546984253, + 27696.01181709627, + 27696.01146554623, + 27696.011445462143, + 27696.011427418645 + ] + ] + }, + "gc.count" : { + "score" : 246.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 246.0, + 246.0 + ], + "scorePercentiles" : { + "0.0" : 9.0, + "50.0" : 10.0, + "90.0" : 10.0, + "95.0" : 10.0, + "99.0" : 10.0, + "99.9" : 10.0, + "99.99" : 10.0, + "99.999" : 10.0, + "99.9999" : 10.0, + "100.0" : 10.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 10.0, + 10.0, + 9.0, + 10.0, + 10.0 + ], + [ + 10.0, + 9.0, + 10.0, + 10.0, + 10.0 + ], + [ + 10.0, + 10.0, + 10.0, + 10.0, + 9.0 + ], + [ + 10.0, + 9.0, + 10.0, + 10.0, + 10.0 + ], + [ + 10.0, + 10.0, + 10.0, + 10.0, + 10.0 + ] + ] + }, + "gc.time" : { + "score" : 202.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 202.0, + 202.0 + ], + "scorePercentiles" : { + "0.0" : 7.0, + "50.0" : 8.0, + "90.0" : 9.0, + "95.0" : 9.0, + "99.0" : 9.0, + "99.9" : 9.0, + "99.99" : 9.0, + "99.999" : 9.0, + "99.9999" : 9.0, + "100.0" : 9.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 9.0, + 8.0, + 8.0, + 8.0, + 8.0 + ], + [ + 9.0, + 7.0, + 8.0, + 8.0, + 8.0 + ], + [ + 9.0, + 8.0, + 8.0, + 7.0, + 7.0 + ], + [ + 9.0, + 7.0, + 8.0, + 8.0, + 8.0 + ], + [ + 8.0, + 9.0, + 8.0, + 8.0, + 9.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.FortunesEncodedBench.jteIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1460.378919204331, + "scoreError" : 40.72374798027083, + "scoreConfidence" : [ + 1419.65517122406, + 1501.1026671846018 + ], + "scorePercentiles" : { + "0.0" : 1393.693702467978, + "50.0" : 1438.8108091025836, + "90.0" : 1535.4523905597764, + "95.0" : 1541.8898686403131, + "99.0" : 1544.294505603032, + "99.9" : 1544.294505603032, + "99.99" : 1544.294505603032, + "99.999" : 1544.294505603032, + "99.9999" : 1544.294505603032, + "100.0" : 1544.294505603032 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1544.294505603032, + 1534.9012848925368, + 1533.8259305891254, + 1532.443884965903, + 1536.2790490606358 + ], + [ + 1513.3905646931732, + 1511.229998188515, + 1511.1761465258965, + 1504.4710894503517, + 1504.2270206397434 + ], + [ + 1422.85376812068, + 1420.4355192063204, + 1418.740392850863, + 1423.4046514801132, + 1416.0510162825744 + ], + [ + 1399.4884953354183, + 1397.7045037245964, + 1398.0260191968691, + 1399.0397619124205, + 1393.693702467978 + ], + [ + 1439.5296957074556, + 1436.7003923247432, + 1438.8108091025836, + 1440.0782034787164, + 1438.6765743080284 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 18446.505611086952, + "scoreError" : 508.9587623135687, + "scoreConfidence" : [ + 17937.54684877338, + 18955.464373400522 + ], + "scorePercentiles" : { + "0.0" : 17421.477933128983, + "50.0" : 18698.328011396887, + "90.0" : 19245.16318996414, + "95.0" : 19286.896282984984, + "99.0" : 19303.57663107068, + "99.9" : 19303.57663107068, + "99.99" : 19303.57663107068, + "99.999" : 19303.57663107068, + "99.9999" : 19303.57663107068, + "100.0" : 19303.57663107068 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 17421.477933128983, + 17527.372474954656, + 17539.256114267184, + 17556.393428005904, + 17511.412951171795 + ], + [ + 17777.39909674687, + 17802.62379542569, + 17803.13594116881, + 17882.785875584505, + 17885.345424251493 + ], + [ + 18908.44319088066, + 18940.62676981328, + 18961.851113849538, + 18900.74924797523, + 18998.849748643453 + ], + [ + 19224.068405095422, + 19247.975470785037, + 19243.288336083544, + 19230.10958932304, + 19303.57663107068 + ], + [ + 18689.61453547546, + 18726.196832305737, + 18698.328011396887, + 18681.571284156395, + 18700.188075613507 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 28216.010254153356, + "scoreError" : 2.876870956152258E-4, + "scoreConfidence" : [ + 28216.00996646626, + 28216.010541840453 + ], + "scorePercentiles" : { + "0.0" : 28216.00977284807, + "50.0" : 28216.01010859835, + "90.0" : 28216.010800884498, + "95.0" : 28216.01085407158, + "99.0" : 28216.010863493415, + "99.9" : 28216.010863493415, + "99.99" : 28216.010863493415, + "99.999" : 28216.010863493415, + "99.9999" : 28216.010863493415, + "100.0" : 28216.010863493415 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 28216.010863493415, + 28216.01078008263, + 28216.010758716184, + 28216.010756689622, + 28216.010832087297 + ], + [ + 28216.010603032333, + 28216.010603224444, + 28216.010601544047, + 28216.010559119193, + 28216.010559658916 + ], + [ + 28216.010006438803, + 28216.009966400292, + 28216.009960238454, + 28216.009938015326, + 28216.009929571293 + ], + [ + 28216.0098334048, + 28216.00985220299, + 28216.009803606845, + 28216.009823350316, + 28216.00977284807 + ], + [ + 28216.01012582488, + 28216.01013637271, + 28216.010089721527, + 28216.01010859835, + 28216.010089591087 + ] + ] + }, + "gc.count" : { + "score" : 275.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 275.0, + 275.0 + ], + "scorePercentiles" : { + "0.0" : 10.0, + "50.0" : 11.0, + "90.0" : 12.0, + "95.0" : 12.0, + "99.0" : 12.0, + "99.9" : 12.0, + "99.99" : 12.0, + "99.999" : 12.0, + "99.9999" : 12.0, + "100.0" : 12.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 10.0, + 11.0, + 10.0, + 11.0, + 10.0 + ], + [ + 11.0, + 11.0, + 11.0, + 11.0, + 10.0 + ], + [ + 12.0, + 11.0, + 11.0, + 11.0, + 12.0 + ], + [ + 11.0, + 11.0, + 11.0, + 11.0, + 11.0 + ], + [ + 11.0, + 12.0, + 11.0, + 12.0, + 11.0 + ] + ] + }, + "gc.time" : { + "score" : 221.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 221.0, + 221.0 + ], + "scorePercentiles" : { + "0.0" : 8.0, + "50.0" : 9.0, + "90.0" : 10.0, + "95.0" : 10.0, + "99.0" : 10.0, + "99.9" : 10.0, + "99.99" : 10.0, + "99.999" : 10.0, + "99.9999" : 10.0, + "100.0" : 10.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 8.0, + 9.0, + 8.0, + 9.0, + 8.0 + ], + [ + 9.0, + 9.0, + 9.0, + 8.0, + 8.0 + ], + [ + 10.0, + 9.0, + 9.0, + 9.0, + 9.0 + ], + [ + 10.0, + 8.0, + 9.0, + 9.0, + 9.0 + ], + [ + 9.0, + 9.0, + 8.0, + 10.0, + 9.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.FortunesEncodedBench.thymeleafControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 10135.884733535237, + "scoreError" : 233.35251537535459, + "scoreConfidence" : [ + 9902.532218159882, + 10369.237248910591 + ], + "scorePercentiles" : { + "0.0" : 9816.211311129642, + "50.0" : 10066.692495018819, + "90.0" : 10696.060120512284, + "95.0" : 10729.478435599385, + "99.0" : 10738.313428675572, + "99.9" : 10738.313428675572, + "99.99" : 10738.313428675572, + "99.999" : 10738.313428675572, + "99.9999" : 10738.313428675572, + "100.0" : 10738.313428675572 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 9855.01063997478, + 9818.425413010442, + 9886.283063560995, + 9816.211311129642, + 9826.400117883983 + ], + [ + 10023.750112737876, + 10038.677674343953, + 10140.99746578814, + 10067.992763091768, + 10066.692495018819 + ], + [ + 10667.877166428618, + 10708.863451754949, + 10738.313428675572, + 10675.594419754665, + 10687.524566350508 + ], + [ + 9911.8207382763, + 9975.027179062647, + 9921.647615840251, + 9857.458471106913, + 9862.119001616655 + ], + [ + 10116.145838592098, + 10140.512887980327, + 10228.775751883537, + 10183.378294463164, + 10181.618470054336 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 2673.184156509667, + "scoreError" : 59.85980824153986, + "scoreConfidence" : [ + 2613.3243482681273, + 2733.0439647512067 + ], + "scorePercentiles" : { + "0.0" : 2520.8975430309415, + "50.0" : 2689.088177586058, + "90.0" : 2755.7350005997096, + "95.0" : 2757.614598078119, + "99.0" : 2757.8100416772068, + "99.9" : 2757.8100416772068, + "99.99" : 2757.8100416772068, + "99.999" : 2757.8100416772068, + "99.9999" : 2757.8100416772068, + "100.0" : 2757.8100416772068 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 2747.0347782846356, + 2757.1585630135805, + 2738.2079109631613, + 2757.8100416772068, + 2754.785958990462 + ], + [ + 2700.801059419604, + 2696.663418014591, + 2669.329083118173, + 2688.9612600572977, + 2689.088177586058 + ], + [ + 2537.6582602068047, + 2528.0546061355462, + 2520.8975430309415, + 2535.8517935109376, + 2533.0046538973993 + ], + [ + 2731.33102266115, + 2714.041517688562, + 2728.3991618936043, + 2746.184369298674, + 2744.980738757823 + ], + [ + 2676.128782293876, + 2669.5214119976185, + 2646.4827257805837, + 2658.397152420788, + 2658.8299220425943 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 28392.071230741265, + "scoreError" : 0.0016709133197424237, + "scoreConfidence" : [ + 28392.069559827945, + 28392.072901654585 + ], + "scorePercentiles" : { + "0.0" : 28392.06855238002, + "50.0" : 28392.070682472277, + "90.0" : 28392.075333068053, + "95.0" : 28392.07540353175, + "99.0" : 28392.075413620623, + "99.9" : 28392.075413620623, + "99.99" : 28392.075413620623, + "99.999" : 28392.075413620623, + "99.9999" : 28392.075413620623, + "100.0" : 28392.075413620623 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 28392.069672131147, + 28392.06855238002, + 28392.069324911172, + 28392.0689066562, + 28392.069001424432 + ], + [ + 28392.07054885809, + 28392.07078083621, + 28392.07152559554, + 28392.070600060306, + 28392.070682472277 + ], + [ + 28392.075379991045, + 28392.075413620623, + 28392.07530178606, + 28392.074857989362, + 28392.075023498248 + ], + [ + 28392.07002534854, + 28392.069737983864, + 28392.069573486006, + 28392.06912297276, + 28392.069240171917 + ], + [ + 28392.071081673246, + 28392.07140760831, + 28392.071707127834, + 28392.071829222357, + 28392.0714707259 + ] + ] + }, + "gc.count" : { + "score" : 75.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 75.0, + 75.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 3.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ], + [ + 3.0, + 3.0, + 3.0, + 3.0, + 3.0 + ] + ] + }, + "gc.time" : { + "score" : 113.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 113.0, + 113.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 5.0, + "90.0" : 7.0, + "95.0" : 7.0, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 6.0, + 5.0, + 7.0, + 2.0, + 3.0 + ], + [ + 6.0, + 5.0, + 7.0, + 3.0, + 2.0 + ], + [ + 6.0, + 6.0, + 5.0, + 4.0, + 2.0 + ], + [ + 6.0, + 5.0, + 6.0, + 3.0, + 2.0 + ], + [ + 5.0, + 6.0, + 7.0, + 2.0, + 2.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.FortunesEncodedBench.thymeleafIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 9122.215371817925, + "scoreError" : 81.83895520782899, + "scoreConfidence" : [ + 9040.376416610095, + 9204.054327025755 + ], + "scorePercentiles" : { + "0.0" : 8944.74133538346, + "50.0" : 9093.840141773073, + "90.0" : 9252.328903314467, + "95.0" : 9276.221726290903, + "99.0" : 9285.230951917101, + "99.9" : 9285.230951917101, + "99.99" : 9285.230951917101, + "99.999" : 9285.230951917101, + "99.9999" : 9285.230951917101, + "100.0" : 9285.230951917101 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 8944.74133538346, + 8956.76303885283, + 9023.94550222118, + 9000.14572669947, + 9038.391213313598 + ], + [ + 9250.041145414367, + 9208.532658693652, + 9234.638298657223, + 9232.613911085684, + 9248.102576428499 + ], + [ + 9250.414705637593, + 9285.230951917101, + 9255.200199829775, + 9234.540962600367, + 9234.868329964278 + ], + [ + 9093.840141773073, + 9089.088088260645, + 9041.935338250829, + 9008.378208014408, + 9018.123304095412 + ], + [ + 9087.286072453762, + 9121.829671380312, + 9106.844407263601, + 9043.272829172165, + 9046.615678084854 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 3417.9403293656305, + "scoreError" : 30.651245624882172, + "scoreConfidence" : [ + 3387.2890837407485, + 3448.5915749905125 + ], + "scorePercentiles" : { + "0.0" : 3357.4797594799857, + "50.0" : 3428.235178469699, + "90.0" : 3470.541626075574, + "95.0" : 3483.878948859712, + "99.0" : 3485.3899682233455, + "99.9" : 3485.3899682233455, + "99.99" : 3485.3899682233455, + "99.999" : 3485.3899682233455, + "99.9999" : 3485.3899682233455, + "100.0" : 3485.3899682233455 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 3485.3899682233455, + 3480.3532370112343, + 3454.7219626565156, + 3464.000552118467, + 3449.0406857501307 + ], + [ + 3370.3664297801133, + 3385.526537736003, + 3375.6143726863193, + 3376.678366995034, + 3370.8714246863174 + ], + [ + 3370.198665212026, + 3357.4797594799857, + 3368.4398934252536, + 3375.872051708303, + 3375.6084271878262 + ], + [ + 3428.235178469699, + 3429.7359484972303, + 3447.740757877191, + 3460.8130788533617, + 3456.8922391172255 + ], + [ + 3430.7120577564356, + 3417.7718666535166, + 3423.1612512798106, + 3447.2217639971836, + 3446.0617569822166 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 32696.06412592698, + "scoreError" : 5.584494755879381E-4, + "scoreConfidence" : [ + 32696.063567477504, + 32696.064684376455 + ], + "scorePercentiles" : { + "0.0" : 32696.062934124777, + "50.0" : 32696.064018000525, + "90.0" : 32696.065093933157, + "95.0" : 32696.06514196482, + "99.0" : 32696.06516193074, + "99.9" : 32696.06516193074, + "99.99" : 32696.06516193074, + "99.999" : 32696.06516193074, + "99.9999" : 32696.06516193074, + "100.0" : 32696.06516193074 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 32696.062934124777, + 32696.0630799764, + 32696.06329239392, + 32696.06318421834, + 32696.063391213313 + ], + [ + 32696.065092970144, + 32696.06461821527, + 32696.064777925334, + 32696.064812593428, + 32696.064933023954 + ], + [ + 32696.065095377675, + 32696.06516193074, + 32696.06498168227, + 32696.065046046628, + 32696.064833531786 + ], + [ + 32696.06397964284, + 32696.064018000525, + 32696.06341582326, + 32696.063538946422, + 32696.063608253928 + ], + [ + 32696.064241851676, + 32696.063666080874, + 32696.064161203205, + 32696.063782474284, + 32696.06350067352 + ] + ] + }, + "gc.count" : { + "score" : 98.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 98.0, + 98.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 4.0, + "90.0" : 4.0, + "95.0" : 4.0, + "99.0" : 4.0, + "99.9" : 4.0, + "99.99" : 4.0, + "99.999" : 4.0, + "99.9999" : 4.0, + "100.0" : 4.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 4.0, + 4.0, + 4.0, + 4.0, + 4.0 + ], + [ + 4.0, + 4.0, + 4.0, + 3.0, + 4.0 + ], + [ + 4.0, + 4.0, + 4.0, + 3.0, + 4.0 + ], + [ + 4.0, + 4.0, + 4.0, + 4.0, + 4.0 + ], + [ + 4.0, + 4.0, + 4.0, + 4.0, + 4.0 + ] + ] + }, + "gc.time" : { + "score" : 127.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 127.0, + 127.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 4.0, + "90.0" : 8.400000000000002, + "95.0" : 9.0, + "99.0" : 9.0, + "99.9" : 9.0, + "99.99" : 9.0, + "99.999" : 9.0, + "99.9999" : 9.0, + "100.0" : 9.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 7.0, + 9.0, + 3.0, + 3.0, + 4.0 + ], + [ + 7.0, + 8.0, + 3.0, + 3.0, + 3.0 + ], + [ + 7.0, + 9.0, + 3.0, + 3.0, + 3.0 + ], + [ + 8.0, + 8.0, + 3.0, + 4.0, + 3.0 + ], + [ + 8.0, + 8.0, + 4.0, + 3.0, + 3.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.FragmentHeavyBench.jteControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 1698.6257691583173, + "scoreError" : 9.480620472365711, + "scoreConfidence" : [ + 1689.1451486859517, + 1708.106389630683 + ], + "scorePercentiles" : { + "0.0" : 1680.3916824603143, + "50.0" : 1694.280528399259, + "90.0" : 1719.6799612328582, + "95.0" : 1724.5055526862934, + "99.0" : 1726.534136289851, + "99.9" : 1726.534136289851, + "99.99" : 1726.534136289851, + "99.999" : 1726.534136289851, + "99.9999" : 1726.534136289851, + "100.0" : 1726.534136289851 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 1693.0026067260637, + 1692.550548820598, + 1703.0919198712763, + 1702.0432395834928, + 1696.6954961250697 + ], + [ + 1719.6184747583243, + 1688.521758802793, + 1715.6635080029769, + 1713.2196749830061, + 1719.7721909446589 + ], + [ + 1726.534136289851, + 1683.2771800227526, + 1690.6653803525087, + 1695.3473410838146, + 1688.2178381515373 + ], + [ + 1716.0675104906613, + 1692.2342997210717, + 1698.691137226161, + 1689.0813563213733, + 1688.8681188787573 + ], + [ + 1698.856274874197, + 1680.3916824603143, + 1689.7695514806828, + 1689.182474586734, + 1694.280528399259 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 7378.330559116993, + "scoreError" : 40.9371110076264, + "scoreConfidence" : [ + 7337.393448109367, + 7419.267670124619 + ], + "scorePercentiles" : { + "0.0" : 7258.680431514995, + "50.0" : 7396.733871509088, + "90.0" : 7432.025563905347, + "95.0" : 7454.406973190853, + "99.0" : 7458.329546108298, + "99.9" : 7458.329546108298, + "99.99" : 7458.329546108298, + "99.999" : 7458.329546108298, + "99.9999" : 7458.329546108298, + "100.0" : 7458.329546108298 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 7402.710090955716, + 7404.4713516862685, + 7358.607616045223, + 7363.226588414996, + 7385.571132090248 + ], + [ + 7287.9467004889275, + 7422.13857319218, + 7304.765753081015, + 7314.987696957364, + 7286.986416986774 + ], + [ + 7258.680431514995, + 7445.254303050149, + 7412.3251377860015, + 7392.470369755661, + 7423.206404475479 + ], + [ + 7303.322672581497, + 7405.854590707013, + 7377.8256632187395, + 7419.600772477018, + 7420.348658630586 + ], + [ + 7377.300417795869, + 7458.329546108298, + 7416.613419810204, + 7418.985798605539, + 7396.733871509088 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 13144.011882770721, + "scoreError" : 1.981339019080936E-4, + "scoreConfidence" : [ + 13144.011684636818, + 13144.012080904624 + ], + "scorePercentiles" : { + "0.0" : 13144.010685914755, + "50.0" : 13144.011892708266, + "90.0" : 13144.012080140648, + "95.0" : 13144.01213072629, + "99.0" : 13144.01214440107, + "99.9" : 13144.01214440107, + "99.99" : 13144.01214440107, + "99.999" : 13144.01214440107, + "99.9999" : 13144.01214440107, + "100.0" : 13144.01214440107 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 13144.011908729064, + 13144.011877725714, + 13144.011905228119, + 13144.011948809286, + 13144.011913989949 + ], + [ + 13144.012098818475, + 13144.011858615055, + 13144.012044763169, + 13144.012026758854, + 13144.01206371234 + ], + [ + 13144.01214440107, + 13144.011856890558, + 13144.011867430796, + 13144.011891520351, + 13144.011849812401 + ], + [ + 13144.012067688764, + 13144.011873890626, + 13144.011916334573, + 13144.011858695138, + 13144.011860857818 + ], + [ + 13144.011948100439, + 13144.010685914755, + 13144.01186099802, + 13144.011846874426, + 13144.011892708266 + ] + ] + }, + "gc.count" : { + "score" : 154.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 154.0, + 154.0 + ], + "scorePercentiles" : { + "0.0" : 5.0, + "50.0" : 6.0, + "90.0" : 7.0, + "95.0" : 7.0, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 6.0, + 6.0, + 5.0, + 6.0, + 6.0 + ], + [ + 7.0, + 6.0, + 7.0, + 7.0, + 7.0 + ], + [ + 5.0, + 6.0, + 6.0, + 6.0, + 5.0 + ], + [ + 6.0, + 6.0, + 5.0, + 6.0, + 6.0 + ], + [ + 7.0, + 7.0, + 6.0, + 7.0, + 7.0 + ] + ] + }, + "gc.time" : { + "score" : 135.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 135.0, + 135.0 + ], + "scorePercentiles" : { + "0.0" : 4.0, + "50.0" : 5.0, + "90.0" : 7.0, + "95.0" : 7.699999999999999, + "99.0" : 8.0, + "99.9" : 8.0, + "99.99" : 8.0, + "99.999" : 8.0, + "99.9999" : 8.0, + "100.0" : 8.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 7.0, + 5.0, + 4.0, + 5.0, + 5.0 + ], + [ + 7.0, + 5.0, + 6.0, + 5.0, + 6.0 + ], + [ + 7.0, + 5.0, + 5.0, + 4.0, + 4.0 + ], + [ + 7.0, + 5.0, + 4.0, + 5.0, + 5.0 + ], + [ + 8.0, + 5.0, + 5.0, + 5.0, + 6.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.FragmentHeavyBench.jteIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2034.7232443760709, + "scoreError" : 10.903169897972539, + "scoreConfidence" : [ + 2023.8200744780984, + 2045.6264142740433 + ], + "scorePercentiles" : { + "0.0" : 2013.3614737540327, + "50.0" : 2031.7852725725577, + "90.0" : 2061.363492739644, + "95.0" : 2064.753216713575, + "99.0" : 2065.702262619088, + "99.9" : 2065.702262619088, + "99.99" : 2065.702262619088, + "99.999" : 2065.702262619088, + "99.9999" : 2065.702262619088, + "100.0" : 2065.702262619088 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 2032.744105009219, + 2058.8202270296947, + 2065.702262619088, + 2062.5387762673786, + 2060.5799703878206 + ], + [ + 2031.9948438959036, + 2020.7569548841795, + 2018.5881983020647, + 2013.3614737540327, + 2015.0743758371689 + ], + [ + 2028.4508120212759, + 2021.6008231118155, + 2028.4957996127705, + 2028.1060145192034, + 2028.875430423334 + ], + [ + 2050.555459869101, + 2038.3027513593875, + 2031.7852725725577, + 2034.3167856381303, + 2031.5092892760492 + ], + [ + 2031.744704344508, + 2024.4710330770056, + 2033.0673946272927, + 2042.7552833602967, + 2033.883067602494 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 6860.633506816254, + "scoreError" : 36.58627882338999, + "scoreConfidence" : [ + 6824.0472279928645, + 6897.219785639644 + ], + "scorePercentiles" : { + "0.0" : 6757.137420631363, + "50.0" : 6870.34200208636, + "90.0" : 6919.804310850886, + "95.0" : 6931.417375384442, + "99.0" : 6933.343981324691, + "99.9" : 6933.343981324691, + "99.99" : 6933.343981324691, + "99.999" : 6933.343981324691, + "99.9999" : 6933.343981324691, + "100.0" : 6933.343981324691 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 6867.297575346701, + 6780.113103051868, + 6757.137420631363, + 6767.578848960996, + 6774.307921902658 + ], + [ + 6869.854434787631, + 6907.6051680202845, + 6915.059210402237, + 6933.343981324691, + 6926.92196152386 + ], + [ + 6881.85604518875, + 6904.712129088381, + 6880.998393037138, + 6882.876884562822, + 6879.713029025249 + ], + [ + 6807.160500265019, + 6847.966282558325, + 6870.34200208636, + 6861.80861683296, + 6870.985066665567 + ], + [ + 6870.688524778921, + 6895.315853480391, + 6865.535466305281, + 6833.383898413486, + 6863.275352165417 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 14640.014300977038, + "scoreError" : 7.728525186575514E-5, + "scoreConfidence" : [ + 14640.014223691785, + 14640.01437826229 + ], + "scorePercentiles" : { + "0.0" : 14640.014148026548, + "50.0" : 14640.014264796375, + "90.0" : 14640.014487999291, + "95.0" : 14640.014508079319, + "99.0" : 14640.014510158757, + "99.9" : 14640.014510158757, + "99.99" : 14640.014510158757, + "99.999" : 14640.014510158757, + "99.9999" : 14640.014510158757, + "100.0" : 14640.014510158757 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 14640.01429580954, + 14640.014510158757, + 14640.014503227298, + 14640.014477847286, + 14640.014464252252 + ], + [ + 14640.014290934188, + 14640.01425731051, + 14640.014157522595, + 14640.014182772033, + 14640.014148026548 + ], + [ + 14640.014254157293, + 14640.01426295916, + 14640.01422541943, + 14640.014308310014, + 14640.01422726352 + ], + [ + 14640.014434985154, + 14640.014369794106, + 14640.014264796375, + 14640.01426439081, + 14640.014249372127 + ], + [ + 14640.014289541841, + 14640.014217788834, + 14640.014277351373, + 14640.014329693107, + 14640.014260741746 + ] + ] + }, + "gc.count" : { + "score" : 160.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 160.0, + 160.0 + ], + "scorePercentiles" : { + "0.0" : 6.0, + "50.0" : 6.0, + "90.0" : 7.0, + "95.0" : 7.0, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 6.0, + 7.0, + 6.0, + 6.0, + 7.0 + ], + [ + 6.0, + 7.0, + 6.0, + 7.0, + 6.0 + ], + [ + 6.0, + 7.0, + 6.0, + 7.0, + 6.0 + ], + [ + 6.0, + 7.0, + 6.0, + 6.0, + 7.0 + ], + [ + 6.0, + 7.0, + 6.0, + 7.0, + 6.0 + ] + ] + }, + "gc.time" : { + "score" : 139.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 139.0, + 139.0 + ], + "scorePercentiles" : { + "0.0" : 4.0, + "50.0" : 5.0, + "90.0" : 7.0, + "95.0" : 7.699999999999999, + "99.0" : 8.0, + "99.9" : 8.0, + "99.99" : 8.0, + "99.999" : 8.0, + "99.9999" : 8.0, + "100.0" : 8.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 7.0, + 5.0, + 5.0, + 5.0, + 5.0 + ], + [ + 8.0, + 6.0, + 5.0, + 5.0, + 5.0 + ], + [ + 7.0, + 6.0, + 5.0, + 5.0, + 5.0 + ], + [ + 7.0, + 6.0, + 4.0, + 5.0, + 6.0 + ], + [ + 7.0, + 6.0, + 4.0, + 6.0, + 4.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.FragmentHeavyBench.thymeleafControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 144991.04916806734, + "scoreError" : 2315.8396164672204, + "scoreConfidence" : [ + 142675.20955160013, + 147306.88878453456 + ], + "scorePercentiles" : { + "0.0" : 140845.06685432795, + "50.0" : 145677.65647743814, + "90.0" : 148704.1715801793, + "95.0" : 150161.53276213558, + "99.0" : 150569.57763415002, + "99.9" : 150569.57763415002, + "99.99" : 150569.57763415002, + "99.999" : 150569.57763415002, + "99.9999" : 150569.57763415002, + "100.0" : 150569.57763415002 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 146484.9758383365, + 146296.33576642335, + 145262.01190303382, + 145503.44727272727, + 145677.65647743814 + ], + [ + 142478.64976499075, + 141974.0525195174, + 141495.3458763616, + 141248.96259703598, + 140845.06685432795 + ], + [ + 141477.64739148875, + 141342.2425952045, + 141996.0970763554, + 141399.435267542, + 141300.0 + ], + [ + 147396.80694526192, + 146554.75841874085, + 147759.13248745943, + 146403.68744512732, + 147144.58645511972 + ], + [ + 150569.57763415002, + 149209.42806076855, + 148367.33392645314, + 148290.11705437844, + 148298.87357344004 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 1920.6001022399585, + "scoreError" : 31.35443996046219, + "scoreConfidence" : [ + 1889.2456622794962, + 1951.9545422004207 + ], + "scorePercentiles" : { + "0.0" : 1850.263526384868, + "50.0" : 1903.3579078776402, + "90.0" : 1972.3989344795816, + "95.0" : 1976.6993974363463, + "99.0" : 1978.3529153772424, + "99.9" : 1978.3529153772424, + "99.99" : 1978.3529153772424, + "99.999" : 1978.3529153772424, + "99.9999" : 1978.3529153772424, + "100.0" : 1978.3529153772424 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 1891.8899722240342, + 1894.7258036689584, + 1908.0845563643975, + 1905.0532645042324, + 1902.7940956427522 + ], + [ + 1955.2401130861965, + 1962.7111657988423, + 1969.2795738994146, + 1972.8411889075885, + 1978.3529153772424 + ], + [ + 1969.2180299289055, + 1971.5360890569634, + 1962.3291496296645, + 1970.690285373631, + 1972.1040981942435 + ], + [ + 1890.0748743748018, + 1901.3709885287683, + 1885.753605622016, + 1903.3579078776402, + 1893.7475721833644 + ], + [ + 1850.263526384868, + 1867.4554710089894, + 1878.0345594682346, + 1879.162003175804, + 1878.9317457174025 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 291928.1276886484, + "scoreError" : 470.23107015218585, + "scoreConfidence" : [ + 291457.8966184962, + 292398.3587588006 + ], + "scorePercentiles" : { + "0.0" : 290644.03338702593, + "50.0" : 292248.9961880559, + "90.0" : 292249.04598421755, + "95.0" : 292249.04953584, + "99.0" : 292249.0509383378, + "99.9" : 292249.0509383378, + "99.99" : 292249.0509383378, + "99.999" : 292249.0509383378, + "99.9999" : 292249.0509383378, + "100.0" : 292249.0509383378 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 290644.03338702593, + 290713.02540145983, + 290713.0242415445, + 290713.0263272727, + 290713.0270742358 + ], + [ + 292180.01880074065, + 292248.9970191625, + 292248.9981609846, + 292248.99590684543, + 292248.9931034483 + ], + [ + 292186.93171214475, + 292248.9906911142, + 292249.001419245, + 292248.9961880559, + 292248.9964694252 + ], + [ + 292176.6804002354, + 292249.0284040996, + 292249.0410150487, + 292249.02780216566, + 292249.03657999117 + ], + [ + 292179.13362392905, + 292249.0509383378, + 292249.04626334517, + 292249.04548822046, + 292249.0457981325 + ] + ] + }, + "gc.count" : { + "score" : 54.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 54.0, + 54.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 2.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 2.0, + 2.0, + 2.0, + 3.0, + 2.0 + ], + [ + 2.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 2.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 2.0, + 2.0, + 2.0, + 3.0, + 2.0 + ], + [ + 2.0, + 2.0, + 2.0, + 2.0, + 2.0 + ] + ] + }, + "gc.time" : { + "score" : 107.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 107.0, + 107.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 4.0, + "90.0" : 6.0, + "95.0" : 6.0, + "99.0" : 6.0, + "99.9" : 6.0, + "99.99" : 6.0, + "99.999" : 6.0, + "99.9999" : 6.0, + "100.0" : 6.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 4.0, + 4.0, + 4.0, + 6.0, + 5.0 + ], + [ + 3.0, + 4.0, + 6.0, + 4.0, + 5.0 + ], + [ + 4.0, + 4.0, + 6.0, + 4.0, + 4.0 + ], + [ + 3.0, + 4.0, + 4.0, + 6.0, + 4.0 + ], + [ + 4.0, + 4.0, + 4.0, + 3.0, + 4.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.FragmentHeavyBench.thymeleafIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 138347.0898796586, + "scoreError" : 1031.2263982609968, + "scoreConfidence" : [ + 137315.8634813976, + 139378.3162779196 + ], + "scorePercentiles" : { + "0.0" : 136252.8330155271, + "50.0" : 138707.9855815888, + "90.0" : 140358.14543082519, + "95.0" : 140715.41431255406, + "99.0" : 140721.27300829, + "99.9" : 140721.27300829, + "99.99" : 140721.27300829, + "99.999" : 140721.27300829, + "99.9999" : 140721.27300829, + "100.0" : 140721.27300829 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 139199.08244126235, + 139155.25730180807, + 138739.77823977824, + 137375.78961823674, + 137651.01816180517 + ], + [ + 138707.9855815888, + 139965.27447967592, + 139242.08843159064, + 139267.16771050802, + 140721.27300829 + ], + [ + 139240.31450041747, + 139255.673117082, + 140129.07970303964, + 139374.25907889244, + 140701.74402250352 + ], + [ + 136545.81058951965, + 136500.2865329513, + 137522.21305841923, + 136962.86105407256, + 137934.07244181243 + ], + [ + 136252.8330155271, + 136374.99318615426, + 137202.72826981082, + 137268.27160493826, + 137387.39184178 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 2001.9454833971797, + "scoreError" : 16.91753205899494, + "scoreConfidence" : [ + 1985.0279513381847, + 2018.8630154561747 + ], + "scorePercentiles" : { + "0.0" : 1963.9210209371902, + "50.0" : 2002.4528981562366, + "90.0" : 2029.8975113228043, + "95.0" : 2038.2153294957766, + "99.0" : 2038.6404299177273, + "99.9" : 2038.6404299177273, + "99.99" : 2038.6404299177273, + "99.999" : 2038.6404299177273, + "99.9999" : 2038.6404299177273, + "100.0" : 2038.6404299177273 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 1995.360393557403, + 1996.5579126230778, + 2002.4528981562366, + 2022.269981889941, + 2018.2610642339498 + ], + [ + 1992.0348719292138, + 1974.584130626593, + 1984.6429949865976, + 1984.494318458398, + 1963.9210209371902 + ], + [ + 1984.3997256844189, + 1984.695103161625, + 1972.1746566650656, + 1982.846562861289, + 1964.1138631414283 + ], + [ + 2023.5084330026639, + 2024.6489079223043, + 2009.3879699158147, + 2017.748474619884, + 2003.5227424138204 + ], + [ + 2038.6404299177273, + 2037.2234285112252, + 2025.0135665305236, + 2023.964532158227, + 2022.1691010248724 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 290449.4088374535, + "scoreError" : 575.6456471363027, + "scoreConfidence" : [ + 289873.7631903172, + 291025.05448458984 + ], + "scorePercentiles" : { + "0.0" : 289775.6048034934, + "50.0" : 289848.98837372183, + "90.0" : 291384.97368365526, + "95.0" : 291384.98034287634, + "99.0" : 291384.9813630042, + "99.9" : 291384.9813630042, + "99.99" : 291384.9813630042, + "99.999" : 291384.9813630042, + "99.9999" : 291384.9813630042, + "100.0" : 291384.9813630042 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 291315.9894341721, + 291384.9813630042, + 291384.97796257795, + 291384.9689645702, + 291384.9708310402 + ], + [ + 289781.01649798977, + 289848.9856125157, + 289848.98109010013, + 289848.977592206, + 289848.99142897286 + ], + [ + 289781.4795435569, + 289848.97786440206, + 289848.98837372183, + 289848.981772645, + 289848.9924050633 + ], + [ + 289775.6048034934, + 289848.9627507163, + 289848.9698969072, + 289848.9659137577, + 289848.96735986776 + ], + [ + 291313.62353582133, + 291384.96156991005, + 291384.9673704415, + 291384.9679012346, + 291384.9690976514 + ] + ] + }, + "gc.count" : { + "score" : 57.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 57.0, + 57.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 2.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 2.0, + 3.0, + 2.0, + 2.0, + 2.0 + ], + [ + 2.0, + 3.0, + 2.0, + 2.0, + 2.0 + ], + [ + 2.0, + 3.0, + 2.0, + 2.0, + 2.0 + ], + [ + 2.0, + 3.0, + 2.0, + 2.0, + 3.0 + ], + [ + 2.0, + 3.0, + 2.0, + 2.0, + 3.0 + ] + ] + }, + "gc.time" : { + "score" : 112.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 112.0, + 112.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 4.0, + "90.0" : 6.0, + "95.0" : 6.0, + "99.0" : 6.0, + "99.9" : 6.0, + "99.99" : 6.0, + "99.999" : 6.0, + "99.9999" : 6.0, + "100.0" : 6.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 4.0, + 5.0, + 4.0, + 4.0, + 5.0 + ], + [ + 4.0, + 5.0, + 4.0, + 4.0, + 4.0 + ], + [ + 3.0, + 6.0, + 4.0, + 4.0, + 5.0 + ], + [ + 4.0, + 6.0, + 4.0, + 4.0, + 5.0 + ], + [ + 4.0, + 6.0, + 4.0, + 4.0, + 6.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.LargeLoopBench.jteControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 112227.55981753339, + "scoreError" : 761.480849447361, + "scoreConfidence" : [ + 111466.07896808603, + 112989.04066698074 + ], + "scorePercentiles" : { + "0.0" : 110788.16823464306, + "50.0" : 112187.7466367713, + "90.0" : 113645.69244907104, + "95.0" : 113817.98550171647, + "99.0" : 113880.99295614634, + "99.9" : 113880.99295614634, + "99.99" : 113880.99295614634, + "99.999" : 113880.99295614634, + "99.9999" : 113880.99295614634, + "100.0" : 113880.99295614634 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 113880.99295614634, + 112898.17444219066, + 113368.31918505942, + 113386.66288951841, + 113422.99852791303 + ], + [ + 111506.3898474897, + 110802.2692052247, + 111129.20786579269, + 110929.3759006762, + 110788.16823464306 + ], + [ + 112933.5027100271, + 112074.95517705065, + 112400.48254965773, + 112187.7466367713, + 111146.12308375916 + ], + [ + 111898.52464513245, + 111275.10272071071, + 111426.0579064588, + 111423.69299221358, + 111207.56162558295 + ], + [ + 113628.84200975389, + 112759.81961668546, + 113670.96810804676, + 112631.01778878631, + 112912.038813043 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 6026.040685813226, + "scoreError" : 40.81960810864261, + "scoreConfidence" : [ + 5985.221077704584, + 6066.860293921869 + ], + "scorePercentiles" : { + "0.0" : 5938.298336878426, + "50.0" : 6027.911601328357, + "90.0" : 6098.848862426945, + "95.0" : 6103.355419829247, + "99.0" : 6103.5535117110685, + "99.9" : 6103.5535117110685, + "99.99" : 6103.5535117110685, + "99.999" : 6103.5535117110685, + "99.9999" : 6103.5535117110685, + "100.0" : 6103.5535117110685 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 5938.298336878426, + 5989.98496847609, + 5964.828958386678, + 5963.940712673651, + 5962.058788223505 + ], + [ + 6064.79564253359, + 6102.89320543833, + 6084.77041943123, + 6096.152633752688, + 6103.5535117110685 + ], + [ + 5988.126143004482, + 6033.820053726818, + 6016.278578843052, + 6027.911601328357, + 6084.346367479499 + ], + [ + 6043.549662620098, + 6077.228338388845, + 6068.547811929071, + 6069.015775170236, + 6080.720209046608 + ], + [ + 5951.550784557552, + 5997.349024790421, + 5948.8281890153885, + 6003.761212380211, + 5988.706215544737 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 709232.7910744208, + "scoreError" : 0.00531588717533134, + "scoreConfidence" : [ + 709232.7857585336, + 709232.796390308 + ], + "scorePercentiles" : { + "0.0" : 709232.780962922, + "50.0" : 709232.7906768265, + "90.0" : 709232.800217798, + "95.0" : 709232.8017059625, + "99.0" : 709232.8020868776, + "99.9" : 709232.8020868776, + "99.99" : 709232.8020868776, + "99.999" : 709232.8020868776, + "99.9999" : 709232.8020868776, + "100.0" : 709232.8020868776 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 709232.7998182231, + 709232.7951318459, + 709232.7986417657, + 709232.7995467422, + 709232.7990035104 + ], + [ + 709232.7872648336, + 709232.781049369, + 709232.7839128986, + 709232.7821749252, + 709232.780962922 + ], + [ + 709232.7985546523, + 709232.7906768265, + 709232.7918303221, + 709232.7874439462, + 709232.7838258165 + ], + [ + 709232.7904325472, + 709232.7835646863, + 709232.7857461025, + 709232.7848720801, + 709232.7834776816 + ], + [ + 709232.8020868776, + 709232.7954904172, + 709232.8008171604, + 709232.7944156722, + 709232.7961186958 + ] + ] + }, + "gc.count" : { + "score" : 141.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 141.0, + 141.0 + ], + "scorePercentiles" : { + "0.0" : 5.0, + "50.0" : 6.0, + "90.0" : 6.0, + "95.0" : 6.0, + "99.0" : 6.0, + "99.9" : 6.0, + "99.99" : 6.0, + "99.999" : 6.0, + "99.9999" : 6.0, + "100.0" : 6.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 6.0, + 5.0, + 6.0, + 5.0, + 6.0 + ], + [ + 6.0, + 5.0, + 6.0, + 6.0, + 6.0 + ], + [ + 6.0, + 5.0, + 6.0, + 5.0, + 6.0 + ], + [ + 6.0, + 5.0, + 6.0, + 6.0, + 5.0 + ], + [ + 6.0, + 5.0, + 6.0, + 5.0, + 6.0 + ] + ] + }, + "gc.time" : { + "score" : 140.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 140.0, + 140.0 + ], + "scorePercentiles" : { + "0.0" : 4.0, + "50.0" : 5.0, + "90.0" : 10.0, + "95.0" : 10.0, + "99.0" : 10.0, + "99.9" : 10.0, + "99.99" : 10.0, + "99.999" : 10.0, + "99.9999" : 10.0, + "100.0" : 10.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 10.0, + 4.0, + 5.0, + 4.0, + 5.0 + ], + [ + 9.0, + 5.0, + 4.0, + 5.0, + 5.0 + ], + [ + 9.0, + 4.0, + 5.0, + 4.0, + 5.0 + ], + [ + 10.0, + 4.0, + 5.0, + 5.0, + 4.0 + ], + [ + 10.0, + 5.0, + 5.0, + 4.0, + 5.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.LargeLoopBench.jteIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 132278.06395884088, + "scoreError" : 1188.112695533258, + "scoreConfidence" : [ + 131089.95126330762, + 133466.17665437414 + ], + "scorePercentiles" : { + "0.0" : 131085.10610427038, + "50.0" : 131637.5, + "90.0" : 135381.56720749935, + "95.0" : 135481.68003668473, + "99.0" : 135513.83094012464, + "99.9" : 135513.83094012464, + "99.99" : 135513.83094012464, + "99.999" : 135513.83094012464, + "99.9999" : 135513.83094012464, + "100.0" : 135513.83094012464 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 131199.03090623362, + 131100.3273965427, + 131382.39233193276, + 131085.10610427038, + 131771.2141164077 + ], + [ + 131800.92238766636, + 131389.32790758729, + 131539.81615233092, + 131335.3720960756, + 131446.24671916012 + ], + [ + 131475.11829652998, + 131755.0821827745, + 131968.70218939593, + 131245.39016393444, + 131722.42990654206 + ], + [ + 131637.5, + 131680.42620363063, + 131722.51184834124, + 131368.07868852458, + 131553.079448457 + ], + [ + 135513.83094012464, + 135406.66126199163, + 135364.83783783784, + 135246.55312246553, + 135241.64076226516 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 9938.990429246967, + "scoreError" : 87.75865662446009, + "scoreConfidence" : [ + 9851.231772622506, + 10026.749085871428 + ], + "scorePercentiles" : { + "0.0" : 9700.738323862577, + "50.0" : 9986.274078245802, + "90.0" : 10022.396708838121, + "95.0" : 10027.680372451017, + "99.0" : 10028.147506670799, + "99.9" : 10028.147506670799, + "99.99" : 10028.147506670799, + "99.999" : 10028.147506670799, + "99.9999" : 10028.147506670799, + "100.0" : 10028.147506670799 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 10019.600919660294, + 10026.590392604861, + 10005.081201421212, + 10028.147506670799, + 9975.795246290978 + ], + [ + 9973.891732552042, + 10005.007503276844, + 9992.87743813698, + 10009.039276993879, + 10000.084503234753 + ], + [ + 9998.547762382972, + 9977.010461401935, + 9961.337335000846, + 10016.045770424906, + 9978.975442189669 + ], + [ + 9986.274078245802, + 9983.103610756098, + 9979.100510380373, + 10006.713154097628, + 9992.24315677694 + ], + [ + 9700.738323862577, + 9708.281347117842, + 9710.852692080281, + 9719.684115174616, + 9719.737250439048 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 1378664.9327979782, + "scoreError" : 0.008423906244595757, + "scoreConfidence" : [ + 1378664.9243740719, + 1378664.9412218845 + ], + "scorePercentiles" : { + "0.0" : 1378664.924044002, + "50.0" : 1378664.9281767956, + "90.0" : 1378664.9536939464, + "95.0" : 1378664.956735559, + "99.0" : 1378664.9580059603, + "99.9" : 1378664.9580059603, + "99.99" : 1378664.9580059603, + "99.999" : 1378664.9580059603, + "99.9999" : 1378664.9580059603, + "100.0" : 1378664.9580059603 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 1378664.92613934, + 1378664.924044002, + 1378664.9264705882, + 1378664.9242860884, + 1378664.9291545958 + ], + [ + 1378664.9318750824, + 1378664.9262273563, + 1378664.9265922522, + 1378664.9261057882, + 1378664.925984252 + ], + [ + 1378664.9295478445, + 1378664.9278106508, + 1378664.9306251649, + 1378664.9253770493, + 1378664.9287876794 + ], + [ + 1378664.9295478445, + 1378664.9281767956, + 1378664.9289099525, + 1378664.9253770493, + 1378664.9265922522 + ], + [ + 1378664.9580059603, + 1378664.9533846776, + 1378664.9535135136, + 1378664.9537712894, + 1378664.9536423841 + ] + ] + }, + "gc.count" : { + "score" : 194.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 194.0, + 194.0 + ], + "scorePercentiles" : { + "0.0" : 7.0, + "50.0" : 8.0, + "90.0" : 8.0, + "95.0" : 8.0, + "99.0" : 8.0, + "99.9" : 8.0, + "99.99" : 8.0, + "99.999" : 8.0, + "99.9999" : 8.0, + "100.0" : 8.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 8.0, + 8.0, + 8.0, + 8.0, + 7.0 + ], + [ + 8.0, + 8.0, + 8.0, + 7.0, + 8.0 + ], + [ + 8.0, + 8.0, + 8.0, + 7.0, + 8.0 + ], + [ + 8.0, + 8.0, + 8.0, + 7.0, + 8.0 + ], + [ + 7.0, + 8.0, + 8.0, + 7.0, + 8.0 + ] + ] + }, + "gc.time" : { + "score" : 157.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 157.0, + 157.0 + ], + "scorePercentiles" : { + "0.0" : 5.0, + "50.0" : 6.0, + "90.0" : 7.0, + "95.0" : 7.0, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 7.0, + 6.0, + 6.0, + 6.0, + 6.0 + ], + [ + 7.0, + 7.0, + 6.0, + 6.0, + 6.0 + ], + [ + 7.0, + 7.0, + 6.0, + 5.0, + 7.0 + ], + [ + 6.0, + 7.0, + 7.0, + 5.0, + 7.0 + ], + [ + 6.0, + 6.0, + 6.0, + 6.0, + 6.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.LargeLoopBench.thymeleafControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6648936.880952587, + "scoreError" : 59320.755718191656, + "scoreConfidence" : [ + 6589616.125234395, + 6708257.636670779 + ], + "scorePercentiles" : { + "0.0" : 6521764.285714285, + "50.0" : 6642962.913907285, + "90.0" : 6755171.409395973, + "95.0" : 6765187.422002539, + "99.0" : 6766265.540540541, + "99.9" : 6766265.540540541, + "99.99" : 6766265.540540541, + "99.999" : 6766265.540540541, + "99.9999" : 6766265.540540541, + "100.0" : 6766265.540540541 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6642962.913907285, + 6612567.763157895, + 6655173.509933775, + 6623575.657894737, + 6611317.105263158 + ], + [ + 6540281.045751634, + 6543749.019607843, + 6561469.934640523, + 6521764.285714285, + 6548744.444444444 + ], + [ + 6742165.77181208, + 6703911.333333333, + 6744165.77181208, + 6762671.812080537, + 6766265.540540541 + ], + [ + 6632462.913907285, + 6586411.184210527, + 6606838.157894737, + 6645852.317880794, + 6563384.9673202615 + ], + [ + 6739810.067114094, + 6686202.0, + 6734904.697986578, + 6750171.140939597, + 6696598.666666667 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 2074.381245044477, + "scoreError" : 18.515684860143416, + "scoreConfidence" : [ + 2055.865560184334, + 2092.8969299046203 + ], + "scorePercentiles" : { + "0.0" : 2038.2071456437886, + "50.0" : 2075.511829439908, + "90.0" : 2107.7816758088275, + "95.0" : 2112.7259861161315, + "99.0" : 2114.7116765149, + "99.9" : 2114.7116765149, + "99.99" : 2114.7116765149, + "99.999" : 2114.7116765149, + "99.9999" : 2114.7116765149, + "100.0" : 2114.7116765149 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 2075.511829439908, + 2085.6303426224486, + 2072.354858613006, + 2082.1721529196357, + 2085.9551183017184 + ], + [ + 2108.092708519005, + 2107.5743206687093, + 2101.800642952408, + 2114.7116765149, + 2105.8904118820424 + ], + [ + 2044.9699019544846, + 2057.24542846913, + 2044.9254599808216, + 2039.3079966622377, + 2038.2071456437886 + ], + [ + 2078.811552129156, + 2093.9682843545256, + 2087.407773056366, + 2075.16091491983, + 2101.177700770872 + ], + [ + 2045.7279434733766, + 2062.6758540699175, + 2047.7157921730065, + 2043.1067405682484, + 2059.4285754523853 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 1.446329789687503E7, + "scoreError" : 1355.936880552446, + "scoreConfidence" : [ + 1.4461941959994476E7, + 1.4464653833755583E7 + ], + "scorePercentiles" : { + "0.0" : 1.4459492402684564E7, + "50.0" : 1.446418272847682E7, + "90.0" : 1.4464188890127279E7, + "95.0" : 1.4464190168156862E7, + "99.0" : 1.4464190346666666E7, + "99.9" : 1.4464190346666666E7, + "99.99" : 1.4464190346666666E7, + "99.999" : 1.4464190346666666E7, + "99.9999" : 1.4464190346666666E7, + "100.0" : 1.4464190346666666E7 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 1.4459795549668875E7, + 1.4464187842105264E7, + 1.446418272847682E7, + 1.4464182421052631E7, + 1.4464182421052631E7 + ], + [ + 1.445975785620915E7, + 1.4464189751633987E7, + 1.446418211764706E7, + 1.4464181818181818E7, + 1.446418211764706E7 + ], + [ + 1.4459492402684564E7, + 1.4464190346666666E7, + 1.4464183355704699E7, + 1.4464183355704699E7, + 1.4464183675675675E7 + ], + [ + 1.4459854569536423E7, + 1.4464188315789474E7, + 1.4464182421052631E7, + 1.446418272847682E7, + 1.446418211764706E7 + ], + [ + 1.445986389261745E7, + 1.446418608E7, + 1.4464183140939597E7, + 1.4464183355704699E7, + 1.446418304E7 + ] + ] + }, + "gc.count" : { + "score" : 60.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 60.0, + 60.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 2.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 3.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 2.0, + 2.0, + 3.0, + 2.0, + 3.0 + ], + [ + 3.0, + 2.0, + 2.0, + 3.0, + 2.0 + ], + [ + 3.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 3.0, + 2.0, + 2.0, + 3.0, + 2.0 + ] + ] + }, + "gc.time" : { + "score" : 110.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 110.0, + 110.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 4.0, + "90.0" : 6.0, + "95.0" : 6.0, + "99.0" : 6.0, + "99.9" : 6.0, + "99.99" : 6.0, + "99.999" : 6.0, + "99.9999" : 6.0, + "100.0" : 6.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 5.0, + 4.0, + 6.0, + 4.0, + 3.0 + ], + [ + 4.0, + 3.0, + 6.0, + 4.0, + 4.0 + ], + [ + 6.0, + 3.0, + 4.0, + 6.0, + 3.0 + ], + [ + 6.0, + 3.0, + 6.0, + 4.0, + 3.0 + ], + [ + 6.0, + 4.0, + 3.0, + 6.0, + 4.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.LargeLoopBench.thymeleafIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6276527.86243181, + "scoreError" : 225835.96656177528, + "scoreConfidence" : [ + 6050691.895870035, + 6502363.828993586 + ], + "scorePercentiles" : { + "0.0" : 5897735.294117647, + "50.0" : 6200361.728395062, + "90.0" : 6836600.136054422, + "95.0" : 6847945.306122449, + "99.0" : 6849395.918367347, + "99.9" : 6849395.918367347, + "99.99" : 6849395.918367347, + "99.999" : 6849395.918367347, + "99.9999" : 6849395.918367347, + "100.0" : 6849395.918367347 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6276173.125, + 6231131.677018633, + 6276538.125, + 6195879.012345679, + 6206888.271604938 + ], + [ + 6179412.962962963, + 6155315.3374233125, + 6167569.938650306, + 6149491.4110429445, + 6149860.736196319 + ], + [ + 6232024.844720497, + 6206709.87654321, + 6229899.378881987, + 6170899.386503068, + 6200361.728395062 + ], + [ + 5967045.833333333, + 5951585.207100592, + 5967726.785714285, + 5954020.238095238, + 5897735.294117647 + ], + [ + 6815804.081632653, + 6831293.197278911, + 6849395.918367347, + 6844560.544217687, + 6805873.6486486485 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 2077.012348908499, + "scoreError" : 71.51084651519571, + "scoreConfidence" : [ + 2005.5015023933033, + 2148.5231954236947 + ], + "scorePercentiles" : { + "0.0" : 1899.106915714782, + "50.0" : 2098.145810302674, + "90.0" : 2185.3759334575775, + "95.0" : 2199.852510896283, + "99.0" : 2205.792257712932, + "99.9" : 2205.792257712932, + "99.99" : 2205.792257712932, + "99.999" : 2205.792257712932, + "99.9999" : 2205.792257712932, + "100.0" : 2205.792257712932 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 2072.299019379098, + 2087.937758229123, + 2072.8421742808487, + 2099.765910974568, + 2096.0132790426214 + ], + [ + 2104.756385064571, + 2113.604696481789, + 2109.268280062668, + 2115.637040813988, + 2115.3235304771392 + ], + [ + 2086.930234416778, + 2096.0748874747014, + 2088.2784097010854, + 2108.167409681085, + 2098.145810302674 + ], + [ + 2179.4372441625624, + 2185.9931016574355, + 2179.9950911799156, + 2184.964487991005, + 2205.792257712932 + ], + [ + 1908.2833530065068, + 1904.4649586002934, + 1899.106915714782, + 1900.8042183988398, + 1911.4222679054717 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 1.3643556754772399E7, + "scoreError" : 1323.3745796578337, + "scoreConfidence" : [ + 1.364223338019274E7, + 1.3644880129352057E7 + ], + "scorePercentiles" : { + "0.0" : 1.3639879047619049E7, + "50.0" : 1.3644419358024692E7, + "90.0" : 1.3644424954154875E7, + "95.0" : 1.3644428531677019E7, + "99.0" : 1.3644429877551021E7, + "99.9" : 1.3644429877551021E7, + "99.99" : 1.3644429877551021E7, + "99.999" : 1.3644429877551021E7, + "99.9999" : 1.3644429877551021E7, + "100.0" : 1.3644429877551021E7 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 1.36401574E7, + 1.3644425391304348E7, + 1.36444199E7, + 1.3644419358024692E7, + 1.3644419555555556E7 + ], + [ + 1.3640075407407407E7, + 1.3644424588957055E7, + 1.3644419288343558E7, + 1.364441909202454E7, + 1.3644419288343558E7 + ], + [ + 1.3640007900621118E7, + 1.3644424444444444E7, + 1.3644419627329193E7, + 1.3644419288343558E7, + 1.3644419555555556E7 + ], + [ + 1.3639879047619049E7, + 1.3644424662721893E7, + 1.3644418E7, + 1.3644418E7, + 1.3644417505882353E7 + ], + [ + 1.3640369795918368E7, + 1.3644429877551021E7, + 1.3644424217687074E7, + 1.3644424E7, + 1.3644423675675675E7 + ] + ] + }, + "gc.count" : { + "score" : 59.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 59.0, + 59.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 2.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 3.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 2.0, + 2.0, + 3.0, + 2.0, + 3.0 + ], + [ + 3.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 2.0, + 3.0, + 2.0, + 3.0, + 2.0 + ], + [ + 2.0, + 2.0, + 3.0, + 2.0, + 2.0 + ] + ] + }, + "gc.time" : { + "score" : 110.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 110.0, + 110.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 4.0, + "90.0" : 6.0, + "95.0" : 6.699999999999999, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 6.0, + 4.0, + 5.0, + 4.0, + 4.0 + ], + [ + 4.0, + 4.0, + 6.0, + 3.0, + 5.0 + ], + [ + 5.0, + 4.0, + 6.0, + 3.0, + 4.0 + ], + [ + 4.0, + 5.0, + 4.0, + 7.0, + 2.0 + ], + [ + 4.0, + 3.0, + 6.0, + 4.0, + 4.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.MixedPageBench.jteControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 2834.6582337524383, + "scoreError" : 44.26125798967055, + "scoreConfidence" : [ + 2790.396975762768, + 2878.9194917421087 + ], + "scorePercentiles" : { + "0.0" : 2773.4422116814394, + "50.0" : 2811.6160565723794, + "90.0" : 2946.1246063928006, + "95.0" : 2952.8314684453103, + "99.0" : 2953.226444154633, + "99.9" : 2953.226444154633, + "99.99" : 2953.226444154633, + "99.999" : 2953.226444154633, + "99.9999" : 2953.226444154633, + "100.0" : 2953.226444154633 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 2809.35515744915, + 2807.9535549831985, + 2811.6160565723794, + 2804.3414598638237, + 2804.557034396361 + ], + [ + 2829.9226586854807, + 2831.7596129072444, + 2832.727473542014, + 2831.0116690830064, + 2834.417281999428 + ], + [ + 2777.1047219377347, + 2779.2736086893747, + 2779.5182028616605, + 2773.4422116814394, + 2794.7554312166876 + ], + [ + 2801.151782940964, + 2800.7740288959594, + 2816.068790260623, + 2801.1227526053403, + 2819.499144317593 + ], + [ + 2953.226444154633, + 2938.5281932242237, + 2942.2677716834073, + 2940.1509414023285, + 2951.909858456891 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 11613.238821349249, + "scoreError" : 177.0725216852646, + "scoreConfidence" : [ + 11436.166299663984, + 11790.311343034513 + ], + "scorePercentiles" : { + "0.0" : 11142.953470882363, + "50.0" : 11703.645560923876, + "90.0" : 11843.410818762532, + "95.0" : 11860.283771993389, + "99.0" : 11864.904193255177, + "99.9" : 11864.904193255177, + "99.99" : 11864.904193255177, + "99.999" : 11864.904193255177, + "99.9999" : 11864.904193255177, + "100.0" : 11864.904193255177 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 11713.290191054128, + 11718.578121673938, + 11703.645560923876, + 11734.271018410285, + 11732.551017912907 + ], + [ + 11628.45148328321, + 11620.187552558975, + 11616.681918450813, + 11623.90675332637, + 11609.64603522433 + ], + [ + 11849.502789049215, + 11839.349505238077, + 11838.387019706857, + 11864.904193255177, + 11773.540812959956 + ], + [ + 11747.792154031695, + 11749.400969581198, + 11684.802134093463, + 11747.899128206205, + 11670.26487858603 + ], + [ + 11142.953470882363, + 11197.882957037362, + 11183.942531896151, + 11192.092073238076, + 11147.046263150587 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 34512.01991600082, + "scoreError" : 3.065639936832937E-4, + "scoreConfidence" : [ + 34512.01960943683, + 34512.02022256481 + ], + "scorePercentiles" : { + "0.0" : 34512.01944968253, + "50.0" : 34512.019766928104, + "90.0" : 34512.02067171856, + "95.0" : 34512.02075672292, + "99.0" : 34512.02077198614, + "99.9" : 34512.02077198614, + "99.99" : 34512.02077198614, + "99.999" : 34512.02077198614, + "99.9999" : 34512.02077198614, + "100.0" : 34512.02077198614 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 34512.01976184728, + 34512.01977528594, + 34512.019741871656, + 34512.019664934596, + 34512.01968549176 + ], + [ + 34512.019915247045, + 34512.01997751963, + 34512.01989198742, + 34512.01985072391, + 34512.01989457913 + ], + [ + 34512.01962825114, + 34512.019502226765, + 34512.01951864748, + 34512.01944968253, + 34512.019611292126 + ], + [ + 34512.019700077515, + 34512.01974529244, + 34512.019766928104, + 34512.019661466715, + 34512.01977076718 + ], + [ + 34512.02077198614, + 34512.020638791764, + 34512.02063533566, + 34512.02061867775, + 34512.02072110875 + ] + ] + }, + "gc.count" : { + "score" : 184.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 184.0, + 184.0 + ], + "scorePercentiles" : { + "0.0" : 7.0, + "50.0" : 7.0, + "90.0" : 8.0, + "95.0" : 8.0, + "99.0" : 8.0, + "99.9" : 8.0, + "99.99" : 8.0, + "99.999" : 8.0, + "99.9999" : 8.0, + "100.0" : 8.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 7.0, + 8.0, + 7.0, + 8.0, + 7.0 + ], + [ + 8.0, + 7.0, + 7.0, + 8.0, + 7.0 + ], + [ + 7.0, + 8.0, + 8.0, + 7.0, + 8.0 + ], + [ + 7.0, + 8.0, + 7.0, + 8.0, + 7.0 + ], + [ + 7.0, + 7.0, + 7.0, + 7.0, + 7.0 + ] + ] + }, + "gc.time" : { + "score" : 150.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 150.0, + 150.0 + ], + "scorePercentiles" : { + "0.0" : 5.0, + "50.0" : 6.0, + "90.0" : 7.0, + "95.0" : 7.0, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 6.0, + 7.0, + 6.0, + 6.0, + 6.0 + ], + [ + 6.0, + 6.0, + 6.0, + 6.0, + 6.0 + ], + [ + 5.0, + 7.0, + 6.0, + 5.0, + 7.0 + ], + [ + 6.0, + 7.0, + 5.0, + 6.0, + 6.0 + ], + [ + 6.0, + 6.0, + 6.0, + 5.0, + 6.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.MixedPageBench.jteIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 3022.797075996953, + "scoreError" : 7.675318057924113, + "scoreConfidence" : [ + 3015.121757939029, + 3030.472394054877 + ], + "scorePercentiles" : { + "0.0" : 3002.6442134575223, + "50.0" : 3023.816685995941, + "90.0" : 3036.0326634650846, + "95.0" : 3038.3222921758847, + "99.0" : 3038.8159352920993, + "99.9" : 3038.8159352920993, + "99.99" : 3038.8159352920993, + "99.999" : 3038.8159352920993, + "99.9999" : 3038.8159352920993, + "100.0" : 3038.8159352920993 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 3023.816685995941, + 3030.95222955972, + 3029.875977254422, + 3026.513624204688, + 3022.115213341827 + ], + [ + 3016.3298419371667, + 3015.5016150026513, + 3014.86380619501, + 3013.398898292082, + 3010.3911340541126 + ], + [ + 3027.0309799228826, + 3022.9562407513667, + 3024.6744527843134, + 3028.9855862238087, + 3028.6432373578514 + ], + [ + 3038.8159352920993, + 3037.1704582380507, + 3035.2122504831805, + 3034.9091537174854, + 3035.2741336164404 + ], + [ + 3018.6806426710414, + 3018.0321096214275, + 3007.4068396722632, + 3002.6442134575223, + 3005.7316402764886 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 12417.857963878032, + "scoreError" : 31.58535600034471, + "scoreConfidence" : [ + 12386.272607877687, + 12449.443319878377 + ], + "scorePercentiles" : { + "0.0" : 12352.521743896257, + "50.0" : 12414.024974389282, + "90.0" : 12483.548013723226, + "95.0" : 12496.87320178288, + "99.0" : 12500.897652628291, + "99.9" : 12500.897652628291, + "99.99" : 12500.897652628291, + "99.999" : 12500.897652628291, + "99.9999" : 12500.897652628291, + "100.0" : 12500.897652628291 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 12414.024974389282, + 12385.056463164437, + 12388.194994674977, + 12402.148128249406, + 12420.068423193343 + ], + [ + 12444.803208985122, + 12448.268735282616, + 12450.652860437513, + 12457.025153590721, + 12469.392106644604 + ], + [ + 12400.821786562672, + 12416.8994041093, + 12409.421774492921, + 12392.658359608124, + 12393.410394948116 + ], + [ + 12352.521743896257, + 12358.886067009687, + 12366.357298078035, + 12368.294881610016, + 12366.001078937308 + ], + [ + 12434.535032077942, + 12437.700946015751, + 12480.92481188743, + 12500.897652628291, + 12487.48281647692 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 39368.02123939249, + "scoreError" : 5.721741253508891E-5, + "scoreConfidence" : [ + 39368.02118217508, + 39368.0212966099 + ], + "scorePercentiles" : { + "0.0" : 39368.02107688984, + "50.0" : 39368.02124364868, + "90.0" : 39368.021342256405, + "95.0" : 39368.021370141905, + "99.0" : 39368.02137498216, + "99.9" : 39368.02137498216, + "99.99" : 39368.02137498216, + "99.999" : 39368.02137498216, + "99.9999" : 39368.02137498216, + "100.0" : 39368.02137498216 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 39368.021358847975, + 39368.02126764103, + 39368.02126796301, + 39368.021230485574, + 39368.021205872676 + ], + [ + 39368.02123187073, + 39368.021260184156, + 39368.021164276244, + 39368.02122788386, + 39368.021130023044 + ], + [ + 39368.02127376679, + 39368.02121221273, + 39368.021241464405, + 39368.02126493677, + 39368.02124364868 + ], + [ + 39368.02137498216, + 39368.021331195356, + 39368.02131152018, + 39368.0212843325, + 39368.0213058315 + ], + [ + 39368.021229373735, + 39368.02127775064, + 39368.02111173228, + 39368.02107688984, + 39368.02110012647 + ] + ] + }, + "gc.count" : { + "score" : 198.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 198.0, + 198.0 + ], + "scorePercentiles" : { + "0.0" : 7.0, + "50.0" : 8.0, + "90.0" : 8.0, + "95.0" : 8.0, + "99.0" : 8.0, + "99.9" : 8.0, + "99.99" : 8.0, + "99.999" : 8.0, + "99.9999" : 8.0, + "100.0" : 8.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 8.0, + 8.0, + 8.0, + 8.0, + 8.0 + ], + [ + 8.0, + 8.0, + 8.0, + 8.0, + 7.0 + ], + [ + 8.0, + 8.0, + 8.0, + 8.0, + 8.0 + ], + [ + 8.0, + 7.0, + 8.0, + 8.0, + 8.0 + ], + [ + 8.0, + 8.0, + 8.0, + 8.0, + 8.0 + ] + ] + }, + "gc.time" : { + "score" : 161.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 161.0, + 161.0 + ], + "scorePercentiles" : { + "0.0" : 6.0, + "50.0" : 6.0, + "90.0" : 7.0, + "95.0" : 7.0, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 7.0, + 7.0, + 6.0, + 6.0, + 6.0 + ], + [ + 7.0, + 7.0, + 6.0, + 6.0, + 6.0 + ], + [ + 7.0, + 7.0, + 6.0, + 7.0, + 6.0 + ], + [ + 6.0, + 6.0, + 6.0, + 6.0, + 7.0 + ], + [ + 7.0, + 7.0, + 6.0, + 7.0, + 6.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.MixedPageBench.thymeleafControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 118601.23574911029, + "scoreError" : 848.7299670213249, + "scoreConfidence" : [ + 117752.50578208896, + 119449.96571613161 + ], + "scorePercentiles" : { + "0.0" : 116362.52180993369, + "50.0" : 119016.09564596717, + "90.0" : 119826.46249551381, + "95.0" : 120440.72058686205, + "99.0" : 120647.98649626235, + "99.9" : 120647.98649626235, + "99.99" : 120647.98649626235, + "99.999" : 120647.98649626235, + "99.9999" : 120647.98649626235, + "100.0" : 120647.98649626235 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 119739.37073812657, + 119141.93049273982, + 119542.34858439853, + 118805.89981006648, + 119225.2770825885 + ], + [ + 119083.42455973347, + 119492.96446458383, + 119957.10013159469, + 118758.31948730121, + 119437.95820895523 + ], + [ + 116598.11452513967, + 117923.48779625044, + 116514.00814426993, + 116362.52180993369, + 117249.4669009959 + ], + [ + 119016.09564596717, + 118184.707132735, + 117928.82914750619, + 117320.37709333646, + 117764.00188102516 + ], + [ + 120647.98649626235, + 119448.43022561776, + 119251.01919179878, + 119023.81178707225, + 118613.44238975817 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 1902.0678497490444, + "scoreError" : 57.242127314172045, + "scoreConfidence" : [ + 1844.8257224348724, + 1959.3099770632164 + ], + "scorePercentiles" : { + "0.0" : 1739.4064918795755, + "50.0" : 1935.3225388266685, + "90.0" : 1958.0252901338035, + "95.0" : 1964.912800807822, + "99.0" : 1967.198816841515, + "99.9" : 1967.198816841515, + "99.99" : 1967.198816841515, + "99.999" : 1967.198816841515, + "99.9999" : 1967.198816841515, + "100.0" : 1967.198816841515 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 1926.9148080380994, + 1937.0485568209174, + 1930.552781348842, + 1942.621867184635, + 1935.505193095108 + ], + [ + 1937.4771375396438, + 1931.4156003455491, + 1923.8968326795289, + 1943.3997598658157, + 1932.214825938249 + ], + [ + 1759.1848178437015, + 1739.4064918795755, + 1760.4686198896077, + 1762.7682553250802, + 1749.2707156488714 + ], + [ + 1938.6075041766655, + 1952.840693722129, + 1956.989641292425, + 1967.198816841515, + 1959.5787633958714 + ], + [ + 1912.3805193113483, + 1932.029720915723, + 1935.3225388266685, + 1939.000961335212, + 1945.6008204653328 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 236651.78755380996, + "scoreError" : 8230.516862755529, + "scoreConfidence" : [ + 228421.27069105444, + 244882.3044165655 + ], + "scorePercentiles" : { + "0.0" : 215120.8207514249, + "50.0" : 242048.83325460556, + "90.0" : 242048.84266849625, + "95.0" : 242048.84375709103, + "99.0" : 242048.84412011006, + "99.9" : 242048.84412011006, + "99.99" : 242048.84412011006, + "99.999" : 242048.84412011006, + "99.9999" : 242048.84412011006, + "100.0" : 242048.84412011006 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 241977.7619332456, + 242048.8398000476, + 242048.8429100466, + 242048.83380816714, + 242048.84090096533 + ], + [ + 241977.9609709662, + 242048.84140233722, + 242048.84412011006, + 242048.83740802278, + 242048.8425074627 + ], + [ + 215120.82309124767, + 215120.83197736117, + 215120.82094240838, + 215120.8207514249, + 215120.8267135325 + ], + [ + 241976.91553652153, + 242048.83325460556, + 242048.83197736117, + 242048.8263262677, + 242048.829532095 + ], + [ + 241976.5285748734, + 242048.83848633163, + 242048.84110144238, + 242048.83840304182, + 242048.83641536272 + ] + ] + }, + "gc.count" : { + "score" : 54.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 54.0, + 54.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 2.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 2.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 2.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 2.0, + 2.0, + 2.0, + 2.0, + 2.0 + ], + [ + 2.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 2.0, + 2.0, + 2.0, + 3.0, + 2.0 + ] + ] + }, + "gc.time" : { + "score" : 105.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 105.0, + 105.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 4.0, + "90.0" : 6.0, + "95.0" : 6.0, + "99.0" : 6.0, + "99.9" : 6.0, + "99.99" : 6.0, + "99.999" : 6.0, + "99.9999" : 6.0, + "100.0" : 6.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 4.0, + 4.0, + 6.0, + 3.0, + 5.0 + ], + [ + 4.0, + 3.0, + 6.0, + 4.0, + 5.0 + ], + [ + 4.0, + 3.0, + 4.0, + 4.0, + 4.0 + ], + [ + 3.0, + 4.0, + 6.0, + 3.0, + 5.0 + ], + [ + 3.0, + 4.0, + 4.0, + 6.0, + 4.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.MixedPageBench.thymeleafIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 114269.55328333209, + "scoreError" : 1179.4893260549466, + "scoreConfidence" : [ + 113090.06395727715, + 115449.04260938703 + ], + "scorePercentiles" : { + "0.0" : 112553.29583802025, + "50.0" : 113458.74419131814, + "90.0" : 116649.90545316787, + "95.0" : 117047.39086831252, + "99.0" : 117173.15302657768, + "99.9" : 117173.15302657768, + "99.99" : 117173.15302657768, + "99.999" : 117173.15302657768, + "99.9999" : 117173.15302657768, + "100.0" : 117173.15302657768 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 112901.80281690141, + 113202.01084500678, + 112859.22625761335, + 113207.03540323493, + 112765.46827454075 + ], + [ + 114016.5375854214, + 113458.74419131814, + 113065.89085978986, + 113666.75365936685, + 112553.29583802025 + ], + [ + 117173.15302657768, + 116753.94583236049, + 116372.67340536772, + 116194.32780419904, + 116191.7663453722 + ], + [ + 116580.54520037278, + 115603.45026540503, + 115295.01037105324, + 114653.46012832264, + 115536.85486664358 + ], + [ + 113277.44964924191, + 113281.18419563002, + 112667.07906872118, + 112822.95636486639, + 112638.20982795458 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 2224.218354263754, + "scoreError" : 22.833864693550808, + "scoreConfidence" : [ + 2201.384489570203, + 2247.052218957305 + ], + "scorePercentiles" : { + "0.0" : 2168.18216167107, + "50.0" : 2239.9106233042808, + "90.0" : 2255.7487982544803, + "95.0" : 2257.270694523661, + "99.0" : 2257.7854623982766, + "99.9" : 2257.7854623982766, + "99.99" : 2257.7854623982766, + "99.999" : 2257.7854623982766, + "99.9999" : 2257.7854623982766, + "100.0" : 2257.7854623982766 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 2250.338771364046, + 2244.985116893082, + 2251.7477877570973, + 2244.814819470742, + 2253.4416570221556 + ], + [ + 2228.393318896321, + 2239.9106233042808, + 2247.599532121981, + 2235.711241956418, + 2257.7854623982766 + ], + [ + 2168.18216167107, + 2176.7017701508685, + 2183.657057139189, + 2187.132102384393, + 2187.029464168714 + ], + [ + 2179.228428552479, + 2198.3053465348576, + 2204.0589050839853, + 2216.558207491297, + 2199.5311078858595 + ], + [ + 2242.901806619652, + 2243.3256283429064, + 2255.534950768873, + 2252.5140191324062, + 2256.0695694828914 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 266514.8631349702, + "scoreError" : 21.336070467504737, + "scoreConfidence" : [ + 266493.5270645027, + 266536.1992054377 + ], + "scorePercentiles" : { + "0.0" : 266455.1932394366, + "50.0" : 266528.7971980567, + "90.0" : 266528.81956935045, + "95.0" : 266528.822544535, + "99.0" : 266528.8237216904, + "99.9" : 266528.8237216904, + "99.99" : 266528.8237216904, + "99.999" : 266528.8237216904, + "99.9999" : 266528.8237216904, + "100.0" : 266528.8237216904 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 266455.1932394366, + 266528.79710799817, + 266528.792240018, + 266528.79809976247, + 266528.79522145836 + ], + [ + 266462.57312072895, + 266528.79972798366, + 266528.7971980567, + 266528.80063542497, + 266528.7937007874 + ], + [ + 266461.37735628145, + 266528.8237216904, + 266528.819797839, + 266528.8184665352, + 266528.81941702473 + ], + [ + 266458.9897483691, + 266528.81052388647, + 266528.8130905739, + 266528.8084326306, + 266528.8146865258 + ], + [ + 266457.36139398057, + 266528.7988225971, + 266528.7936115173, + 266528.7955801105, + 266528.79343303724 + ] + ] + }, + "gc.count" : { + "score" : 62.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 62.0, + 62.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 2.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 2.0, + 3.0, + 2.0, + 3.0, + 2.0 + ], + [ + 2.0, + 3.0, + 2.0, + 3.0, + 2.0 + ], + [ + 3.0, + 2.0, + 3.0, + 2.0, + 3.0 + ], + [ + 3.0, + 2.0, + 3.0, + 2.0, + 3.0 + ], + [ + 2.0, + 3.0, + 2.0, + 3.0, + 2.0 + ] + ] + }, + "gc.time" : { + "score" : 112.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 112.0, + 112.0 + ], + "scorePercentiles" : { + "0.0" : 1.0, + "50.0" : 4.0, + "90.0" : 6.400000000000002, + "95.0" : 7.0, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 4.0, + 6.0, + 4.0, + 7.0, + 1.0 + ], + [ + 4.0, + 5.0, + 4.0, + 7.0, + 2.0 + ], + [ + 5.0, + 4.0, + 6.0, + 3.0, + 5.0 + ], + [ + 6.0, + 4.0, + 6.0, + 3.0, + 5.0 + ], + [ + 4.0, + 5.0, + 4.0, + 6.0, + 2.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.TrivialSubstitutionBench.jteControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 350.5905162346299, + "scoreError" : 3.0519898186154073, + "scoreConfidence" : [ + 347.53852641601446, + 353.6425060532453 + ], + "scorePercentiles" : { + "0.0" : 344.46766809176455, + "50.0" : 349.5880934736874, + "90.0" : 355.67199053238477, + "95.0" : 355.89323016859487, + "99.0" : 355.96951146056506, + "99.9" : 355.96951146056506, + "99.99" : 355.96951146056506, + "99.999" : 355.96951146056506, + "99.9999" : 355.96951146056506, + "100.0" : 355.96951146056506 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 348.67257992487936, + 349.6722418170522, + 355.6431572290872, + 355.96951146056506, + 355.7152404873312 + ], + [ + 344.9295412689806, + 344.46766809176455, + 346.1245785479387, + 345.7429146967288, + 345.0423629652938 + ], + [ + 348.08893383869406, + 348.6604528205703, + 353.442975839478, + 354.74137304436465, + 353.80233823594926 + ], + [ + 354.2375034411404, + 354.08122591162254, + 347.3506073431269, + 347.32956566908405, + 347.0535463080561 + ], + [ + 349.0982261437576, + 349.5880934736874, + 354.66597580740336, + 355.3557959063655, + 355.2864955928262 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 23522.384351286233, + "scoreError" : 204.75475774187768, + "scoreConfidence" : [ + 23317.629593544356, + 23727.13910902811 + ], + "scorePercentiles" : { + "0.0" : 23164.673598990044, + "50.0" : 23586.64950706659, + "90.0" : 23900.510364884296, + "95.0" : 23928.21872340336, + "99.0" : 23937.698148132804, + "99.9" : 23937.698148132804, + "99.99" : 23937.698148132804, + "99.999" : 23937.698148132804, + "99.9999" : 23937.698148132804, + "100.0" : 23937.698148132804 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 23649.486295523733, + 23581.735023264537, + 23185.72403596305, + 23164.673598990044, + 23179.28983770604 + ], + [ + 23906.10006570132, + 23937.698148132804, + 23821.426928226676, + 23848.86103684282, + 23896.783897672944 + ], + [ + 23689.285197804962, + 23650.01899924235, + 23328.965105249474, + 23244.6479119864, + 23304.919960561 + ], + [ + 23278.24858132981, + 23287.359786308043, + 23737.337044430948, + 23740.72722334537, + 23757.625413521713 + ], + [ + 23620.648804537905, + 23586.64950706659, + 23249.65077653284, + 23204.012540633605, + 23207.733061580973 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 8648.002461210868, + "scoreError" : 2.137076950963185E-5, + "scoreConfidence" : [ + 8648.002439840098, + 8648.002482581638 + ], + "scorePercentiles" : { + "0.0" : 8648.002418626176, + "50.0" : 8648.002454342726, + "90.0" : 8648.002495847077, + "95.0" : 8648.00249655271, + "99.0" : 8648.002496766183, + "99.9" : 8648.002496766183, + "99.99" : 8648.002496766183, + "99.999" : 8648.002496766183, + "99.9999" : 8648.002496766183, + "100.0" : 8648.002496766183 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 8648.00245041819, + 8648.002454342726, + 8648.002496766183, + 8648.002496054607, + 8648.002495708724 + ], + [ + 8648.002425216186, + 8648.002418626176, + 8648.002430193354, + 8648.002424857552, + 8648.002420839346 + ], + [ + 8648.002437305804, + 8648.002445796566, + 8648.002478689936, + 8648.002490448966, + 8648.00248348293 + ], + [ + 8648.00249106719, + 8648.00248430597, + 8648.002439304757, + 8648.002435643057, + 8648.002436745737 + ], + [ + 8648.002453379688, + 8648.002462957036, + 8648.00248936156, + 8648.002494420934, + 8648.002494338554 + ] + ] + }, + "gc.count" : { + "score" : 316.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 316.0, + 316.0 + ], + "scorePercentiles" : { + "0.0" : 12.0, + "50.0" : 13.0, + "90.0" : 13.0, + "95.0" : 13.0, + "99.0" : 13.0, + "99.9" : 13.0, + "99.99" : 13.0, + "99.999" : 13.0, + "99.9999" : 13.0, + "100.0" : 13.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 13.0, + 12.0, + 13.0, + 12.0, + 13.0 + ], + [ + 12.0, + 13.0, + 12.0, + 13.0, + 12.0 + ], + [ + 13.0, + 13.0, + 12.0, + 12.0, + 13.0 + ], + [ + 13.0, + 13.0, + 13.0, + 13.0, + 13.0 + ], + [ + 13.0, + 13.0, + 12.0, + 13.0, + 12.0 + ] + ] + }, + "gc.time" : { + "score" : 247.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 247.0, + 247.0 + ], + "scorePercentiles" : { + "0.0" : 8.0, + "50.0" : 10.0, + "90.0" : 11.400000000000002, + "95.0" : 12.0, + "99.0" : 12.0, + "99.9" : 12.0, + "99.99" : 12.0, + "99.999" : 12.0, + "99.9999" : 12.0, + "100.0" : 12.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 12.0, + 9.0, + 9.0, + 9.0, + 9.0 + ], + [ + 11.0, + 11.0, + 9.0, + 11.0, + 10.0 + ], + [ + 11.0, + 11.0, + 8.0, + 8.0, + 10.0 + ], + [ + 9.0, + 10.0, + 10.0, + 10.0, + 11.0 + ], + [ + 12.0, + 11.0, + 8.0, + 10.0, + 8.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.TrivialSubstitutionBench.jteIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 368.4049490702137, + "scoreError" : 0.819377018428605, + "scoreConfidence" : [ + 367.5855720517851, + 369.22432608864233 + ], + "scorePercentiles" : { + "0.0" : 366.74164743316004, + "50.0" : 368.6274943423487, + "90.0" : 369.8034512677136, + "95.0" : 370.0509824237785, + "99.0" : 370.12362901674044, + "99.9" : 370.12362901674044, + "99.99" : 370.12362901674044, + "99.999" : 370.12362901674044, + "99.9999" : 370.12362901674044, + "100.0" : 370.12362901674044 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 370.12362901674044, + 368.6274943423487, + 367.9466061112353, + 368.6859296399155, + 369.2999228324157 + ], + [ + 368.6360711553556, + 367.81824367190444, + 366.74164743316004, + 366.9866588422993, + 367.36860892480985 + ], + [ + 366.83389246252807, + 368.28004004124796, + 366.9658878999536, + 366.798952129015, + 366.7894834072775 + ], + [ + 368.56786818290317, + 369.67869838665575, + 369.18796584062943, + 368.5547656129561, + 369.0285126764802 + ], + [ + 369.7514363082778, + 369.8814737068674, + 368.9174552681257, + 369.36047594203006, + 369.2920069202109 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 22526.405091936827, + "scoreError" : 50.32651702064793, + "scoreConfidence" : [ + 22476.07857491618, + 22576.731608957474 + ], + "scorePercentiles" : { + "0.0" : 22423.308736056948, + "50.0" : 22514.1571984579, + "90.0" : 22625.41931770329, + "95.0" : 22628.273467899267, + "99.0" : 22629.169899827983, + "99.9" : 22629.169899827983, + "99.99" : 22629.169899827983, + "99.999" : 22629.169899827983, + "99.9999" : 22629.169899827983, + "100.0" : 22629.169899827983 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 22423.308736056948, + 22514.1571984579, + 22554.9138661444, + 22510.420524644353, + 22471.38017283451 + ], + [ + 22513.845323589958, + 22562.342452396715, + 22629.169899827983, + 22613.739722822073, + 22590.003659725877 + ], + [ + 22623.720322346446, + 22533.86460586764, + 22614.086988761894, + 22626.181793398937, + 22624.91100057286 + ], + [ + 22517.821477526482, + 22450.05936141929, + 22478.328127882927, + 22518.37235969611, + 22487.673491983696 + ], + [ + 22445.964210188, + 22436.223386523176, + 22477.483978766504, + 22469.870702208496, + 22472.283934777322 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 8704.002588293868, + "scoreError" : 7.50488618959195E-6, + "scoreConfidence" : [ + 8704.002580788982, + 8704.002595798755 + ], + "scorePercentiles" : { + "0.0" : 8704.00257244336, + "50.0" : 8704.002590298109, + "90.0" : 8704.002602427308, + "95.0" : 8704.00260817223, + "99.0" : 8704.002609508952, + "99.9" : 8704.002609508952, + "99.99" : 8704.002609508952, + "99.999" : 8704.002609508952, + "99.9999" : 8704.002609508952, + "100.0" : 8704.002609508952 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 8704.00260505321, + 8704.002600676708, + 8704.002582626395, + 8704.002586101838, + 8704.00259218131 + ], + [ + 8704.002592985606, + 8704.002595047858, + 8704.00257244336, + 8704.002576172967, + 8704.002579492739 + ], + [ + 8704.002579468894, + 8704.002584065835, + 8704.002573862035, + 8704.002575313436, + 8704.002574606406 + ], + [ + 8704.00259320051, + 8704.002595540578, + 8704.002591990955, + 8704.002584330145, + 8704.00259031817 + ], + [ + 8704.00260005407, + 8704.002609508952, + 8704.002590298109, + 8704.00258987978, + 8704.002592126784 + ] + ] + }, + "gc.count" : { + "score" : 311.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 311.0, + 311.0 + ], + "scorePercentiles" : { + "0.0" : 12.0, + "50.0" : 12.0, + "90.0" : 13.0, + "95.0" : 13.0, + "99.0" : 13.0, + "99.9" : 13.0, + "99.99" : 13.0, + "99.999" : 13.0, + "99.9999" : 13.0, + "100.0" : 13.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 12.0, + 12.0, + 12.0, + 13.0, + 12.0 + ], + [ + 12.0, + 13.0, + 12.0, + 13.0, + 12.0 + ], + [ + 12.0, + 12.0, + 13.0, + 12.0, + 13.0 + ], + [ + 12.0, + 12.0, + 13.0, + 12.0, + 13.0 + ], + [ + 13.0, + 13.0, + 13.0, + 12.0, + 13.0 + ] + ] + }, + "gc.time" : { + "score" : 240.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 240.0, + 240.0 + ], + "scorePercentiles" : { + "0.0" : 8.0, + "50.0" : 10.0, + "90.0" : 10.0, + "95.0" : 10.7, + "99.0" : 11.0, + "99.9" : 11.0, + "99.99" : 11.0, + "99.999" : 11.0, + "99.9999" : 11.0, + "100.0" : 11.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 10.0, + 10.0, + 9.0, + 10.0, + 8.0 + ], + [ + 10.0, + 10.0, + 9.0, + 10.0, + 8.0 + ], + [ + 11.0, + 9.0, + 10.0, + 9.0, + 9.0 + ], + [ + 10.0, + 9.0, + 10.0, + 10.0, + 10.0 + ], + [ + 10.0, + 10.0, + 10.0, + 9.0, + 10.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.TrivialSubstitutionBench.thymeleafControlled", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 7204.868898276481, + "scoreError" : 115.99639474915747, + "scoreConfidence" : [ + 7088.872503527323, + 7320.8652930256385 + ], + "scorePercentiles" : { + "0.0" : 7010.260649065908, + "50.0" : 7171.70857908655, + "90.0" : 7473.403340479683, + "95.0" : 7513.17238627154, + "99.0" : 7529.892783567165, + "99.9" : 7529.892783567165, + "99.99" : 7529.892783567165, + "99.999" : 7529.892783567165, + "99.9999" : 7529.892783567165, + "100.0" : 7529.892783567165 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 7217.12915209002, + 7161.836899677348, + 7100.576923076923, + 7107.471031923424, + 7142.441852174037 + ], + [ + 7242.48708412324, + 7204.155730219112, + 7161.5136876006445, + 7187.524330070171, + 7150.746652199983 + ], + [ + 7529.892783567165, + 7472.900150189418, + 7471.521156416364, + 7423.037820854823, + 7474.158125915081 + ], + [ + 7039.743067170787, + 7019.2536601114525, + 7010.762780670811, + 7023.861530686731, + 7010.260649065908 + ], + [ + 7231.389292241896, + 7214.360106168138, + 7191.916109623268, + 7171.70857908655, + 7161.073301988736 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 2020.7524156806135, + "scoreError" : 77.70414014442945, + "scoreConfidence" : [ + 1943.048275536184, + 2098.456555825043 + ], + "scorePercentiles" : { + "0.0" : 1826.932509823595, + "50.0" : 2066.7963824578023, + "90.0" : 2122.327432846322, + "95.0" : 2123.9281846834956, + "99.0" : 2123.955454814916, + "99.9" : 2123.955454814916, + "99.99" : 2123.955454814916, + "99.999" : 2123.955454814916, + "99.9999" : 2123.955454814916, + "100.0" : 2123.955454814916 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 2062.520758449991, + 2079.0332708279916, + 2096.8462597320176, + 2094.9785248681515, + 2084.5540615557297 + ], + [ + 2055.2778936914556, + 2066.7963824578023, + 2079.0900116835865, + 2071.6021189734015, + 2082.218738704571 + ], + [ + 1976.8836523872192, + 1992.5674600175366, + 1992.7924612074096, + 2005.8337957380643, + 1992.0970931365662 + ], + [ + 2114.5152120970147, + 2121.3026851593045, + 2123.864554376849, + 2119.9329022803176, + 2123.955454814916 + ], + [ + 1826.932509823595, + 1831.2681963480857, + 1836.9559006211298, + 1842.1960424845067, + 1844.79445057813 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 15263.287549782022, + "scoreError" : 537.9364395388219, + "scoreConfidence" : [ + 14725.3511102432, + 15801.223989320844 + ], + "scorePercentiles" : { + "0.0" : 13856.050265856573, + "50.0" : 15616.049525520804, + "90.0" : 15616.052324963599, + "95.0" : 15616.052462192541, + "99.0" : 15616.052469596916, + "99.9" : 15616.052469596916, + "99.99" : 15616.052469596916, + "99.999" : 15616.052469596916, + "99.9999" : 15616.052469596916, + "100.0" : 15616.052469596916 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 15611.363710462725, + 15616.05002182016, + 15616.050070962248, + 15616.05006705409, + 15616.05031159534 + ], + [ + 15611.139173094456, + 15616.050510207751, + 15616.050499194847, + 15616.050448535168, + 15616.05036690175 + ], + [ + 15611.368370400445, + 15616.052244995553, + 15616.052444915666, + 15616.052048135633, + 15616.052469596916 + ], + [ + 15611.256244114298, + 15616.049297455118, + 15616.04916288706, + 15616.049525520804, + 15616.049201801638 + ], + [ + 13856.050858600089, + 13856.050660665858, + 13856.050431873173, + 13856.050337903209, + 13856.050265856573 + ] + ] + }, + "gc.count" : { + "score" : 57.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 57.0, + 57.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 2.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 3.0, + 2.0, + 2.0, + 3.0, + 2.0 + ], + [ + 2.0, + 3.0, + 2.0, + 3.0, + 2.0 + ], + [ + 2.0, + 3.0, + 2.0, + 2.0, + 2.0 + ], + [ + 3.0, + 2.0, + 3.0, + 2.0, + 2.0 + ], + [ + 2.0, + 2.0, + 2.0, + 2.0, + 2.0 + ] + ] + }, + "gc.time" : { + "score" : 109.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 109.0, + 109.0 + ], + "scorePercentiles" : { + "0.0" : 3.0, + "50.0" : 4.0, + "90.0" : 6.0, + "95.0" : 6.699999999999999, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 5.0, + 4.0, + 4.0, + 6.0, + 3.0 + ], + [ + 3.0, + 6.0, + 4.0, + 5.0, + 4.0 + ], + [ + 4.0, + 5.0, + 4.0, + 4.0, + 5.0 + ], + [ + 6.0, + 3.0, + 7.0, + 4.0, + 3.0 + ], + [ + 4.0, + 4.0, + 4.0, + 4.0, + 4.0 + ] + ] + } + } + }, + { + "jmhVersion" : "1.37", + "benchmark" : "heddle.benchmarks.jvm.bench.TrivialSubstitutionBench.thymeleafIdiomatic", + "mode" : "avgt", + "threads" : 1, + "forks" : 5, + "jvm" : "C:\\Program Files\\Java\\jdk-25.0.4\\bin\\java.exe", + "jvmArgs" : [ + ], + "jdkVersion" : "25.0.4", + "vmName" : "Java HotSpot(TM) 64-Bit Server VM", + "vmVersion" : "25.0.4+7-LTS-189", + "warmupIterations" : 1, + "warmupTime" : "2 s", + "warmupBatchSize" : 1, + "measurementIterations" : 5, + "measurementTime" : "1 s", + "measurementBatchSize" : 1, + "primaryMetric" : { + "score" : 6610.05698055574, + "scoreError" : 80.1613928905863, + "scoreConfidence" : [ + 6529.8955876651535, + 6690.218373446326 + ], + "scorePercentiles" : { + "0.0" : 6459.541069033124, + "50.0" : 6621.328442549817, + "90.0" : 6744.599404782832, + "95.0" : 6782.515511940878, + "99.0" : 6795.972589727932, + "99.9" : 6795.972589727932, + "99.99" : 6795.972589727932, + "99.999" : 6795.972589727932, + "99.9999" : 6795.972589727932, + "100.0" : 6795.972589727932 + }, + "scoreUnit" : "ns/op", + "rawData" : [ + [ + 6485.094857972216, + 6513.247849353994, + 6507.815822846552, + 6497.03134232415, + 6520.2199347618025 + ], + [ + 6795.972589727932, + 6751.115663771085, + 6696.040875287572, + 6692.636978285439, + 6698.8200905667445 + ], + [ + 6698.586865611723, + 6663.074955708596, + 6621.328442549817, + 6612.31459693837, + 6592.338502483563 + ], + [ + 6740.255232123996, + 6706.613231825006, + 6693.346267059138, + 6673.419587181967, + 6693.824008981315 + ], + [ + 6479.052120427323, + 6484.680856576544, + 6464.057759588944, + 6459.541069033124, + 6510.995012906624 + ] + ] + }, + "secondaryMetrics" : { + "gc.alloc.rate" : { + "score" : 2115.0225422874037, + "scoreError" : 72.71593991025152, + "scoreConfidence" : [ + 2042.306602377152, + 2187.7384821976552 + ], + "scorePercentiles" : { + "0.0" : 1990.9780831437881, + "50.0" : 2174.571973553956, + "90.0" : 2215.2945236828295, + "95.0" : 2221.805654318454, + "99.0" : 2223.8047357970836, + "99.9" : 2223.8047357970836, + "99.99" : 2223.8047357970836, + "99.999" : 2223.8047357970836, + "99.9999" : 2223.8047357970836, + "100.0" : 2223.8047357970836 + }, + "scoreUnit" : "MB/sec", + "rawData" : [ + [ + 2001.9868004738585, + 1993.2905053848642, + 1994.8906955425687, + 1998.3283794068125, + 1990.9780831437881 + ], + [ + 2156.6902419095177, + 2171.6755698327975, + 2189.382076789074, + 2190.580473037992, + 2188.536608025145 + ], + [ + 2188.06002865131, + 2200.380399009367, + 2214.0634522258365, + 2217.1411308683187, + 2223.8047357970836 + ], + [ + 2174.571973553956, + 2186.0696088627174, + 2190.2368341615183, + 2196.956868866082, + 2190.03572437946 + ], + [ + 2003.8330760758988, + 2002.0282990137914, + 2008.3379201756436, + 2009.8771118631776, + 1993.8269601345228 + ] + ] + }, + "gc.alloc.rate.norm" : { + "score" : 14671.514180405391, + "scoreError" : 658.8592727722233, + "scoreConfidence" : [ + 14012.654907633168, + 15330.373453177614 + ], + "scorePercentiles" : { + "0.0" : 13616.045299762667, + "50.0" : 15371.87344684458, + "90.0" : 15376.047232688075, + "95.0" : 15376.04732112439, + "99.0" : 15376.047335683044, + "99.9" : 15376.047335683044, + "99.99" : 15376.047335683044, + "99.999" : 15376.047335683044, + "99.9999" : 15376.047335683044, + "100.0" : 15376.047335683044 + }, + "scoreUnit" : "B/op", + "rawData" : [ + [ + 13616.045614762596, + 13616.04588044814, + 13616.045680096251, + 13616.045607724223, + 13616.045731846267 + ], + [ + 15371.438930728, + 15376.047335683044, + 15376.046974479696, + 15376.046973537259, + 15376.04719637733 + ], + [ + 15371.523147435682, + 15376.046995510917, + 15376.046422788408, + 15376.046638288872, + 15376.046272019394 + ], + [ + 15371.87344684458, + 15376.047287154193, + 15376.046989563822, + 15376.046843842742, + 15376.047151907193 + ], + [ + 13616.045581094206, + 13616.045497532095, + 13616.045340115415, + 13616.045299762667, + 13616.045670591755 + ] + ] + }, + "gc.count" : { + "score" : 61.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 61.0, + 61.0 + ], + "scorePercentiles" : { + "0.0" : 2.0, + "50.0" : 2.0, + "90.0" : 3.0, + "95.0" : 3.0, + "99.0" : 3.0, + "99.9" : 3.0, + "99.99" : 3.0, + "99.999" : 3.0, + "99.9999" : 3.0, + "100.0" : 3.0 + }, + "scoreUnit" : "counts", + "rawData" : [ + [ + 2.0, + 3.0, + 2.0, + 2.0, + 2.0 + ], + [ + 3.0, + 2.0, + 3.0, + 2.0, + 3.0 + ], + [ + 3.0, + 2.0, + 3.0, + 3.0, + 2.0 + ], + [ + 3.0, + 2.0, + 3.0, + 2.0, + 3.0 + ], + [ + 2.0, + 3.0, + 2.0, + 2.0, + 2.0 + ] + ] + }, + "gc.time" : { + "score" : 111.0, + "scoreError" : "NaN", + "scoreConfidence" : [ + 111.0, + 111.0 + ], + "scorePercentiles" : { + "0.0" : 1.0, + "50.0" : 4.0, + "90.0" : 6.0, + "95.0" : 6.699999999999999, + "99.0" : 7.0, + "99.9" : 7.0, + "99.99" : 7.0, + "99.999" : 7.0, + "99.9999" : 7.0, + "100.0" : 7.0 + }, + "scoreUnit" : "ms", + "rawData" : [ + [ + 3.0, + 6.0, + 4.0, + 4.0, + 4.0 + ], + [ + 6.0, + 4.0, + 5.0, + 4.0, + 4.0 + ], + [ + 6.0, + 4.0, + 5.0, + 7.0, + 1.0 + ], + [ + 5.0, + 4.0, + 6.0, + 3.0, + 4.0 + ], + [ + 4.0, + 5.0, + 4.0, + 4.0, + 5.0 + ] + ] + } + } + } +] + + diff --git a/docs/benchmarks/2026-08-08/python/bench_cold_compile.json b/docs/benchmarks/2026-08-08/python/bench_cold_compile.json new file mode 100644 index 00000000..cf651b69 --- /dev/null +++ b/docs/benchmarks/2026-08-08/python/bench_cold_compile.json @@ -0,0 +1 @@ +{"benchmarks":[{"metadata":{"loops":1024,"name":"jinja2/cold-compile/composed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.144385","calibrate_loops":1024,"date":"2026-08-08 04:24:22.159515","duration":0.6125541000001249,"mem_peak_pagefile_usage":39960576,"uptime":25480.03174471855},"warmups":[[1,0.0006007000010868069],[2,0.0001675000003160676],[4,0.00012305000018386636],[8,0.00011772499965445604],[16,0.00011525624995556427],[32,0.00011555312494238024],[64,0.00011765156250476139],[128,0.00011523906249522042],[256,0.0001153371093636224],[512,0.00011559199218424965],[1024,0.00011553681640563696],[1024,0.00011499912109513843],[1024,0.00011533935546736984],[1024,0.00011530625000233385]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145097","date":"2026-08-08 04:24:22.936475","duration":0.48052439999810304,"mem_peak_pagefile_usage":38764544,"uptime":25480.805035591125},"values":[0.00011305302734143652,0.0001126015624990373,0.00011257861328317631],"warmups":[[1024,0.00011302050781125672]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143494","date":"2026-08-08 04:24:23.704656","duration":0.47903280000173254,"mem_peak_pagefile_usage":39153664,"uptime":25481.577748537064},"values":[0.00011164033202959445,0.00011107675781119042,0.00011181230468793046],"warmups":[[1024,0.00011233535156307539]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138341","date":"2026-08-08 04:24:24.474682","duration":0.47652709999965737,"mem_peak_pagefile_usage":39325696,"uptime":25482.350017786026},"values":[0.00011191562499845986,0.00011153212890491204,0.00011155283203123645],"warmups":[[1024,0.00011232412109407619]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141028","date":"2026-08-08 04:24:25.246879","duration":0.48203690000082133,"mem_peak_pagefile_usage":39809024,"uptime":25483.122388362885},"values":[0.00011236230468725239,0.00011217763671922398,0.00011244658202969049],"warmups":[[1024,0.0001128686523408362]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153646","date":"2026-08-08 04:24:26.018985","duration":0.4793418000008387,"mem_peak_pagefile_usage":39608320,"uptime":25483.87941622734},"values":[0.00011223798828297049,0.00011210595702948467,0.00011191933593579506],"warmups":[[1024,0.00011324013671654143]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152623","date":"2026-08-08 04:24:26.789492","duration":0.4843479999981355,"mem_peak_pagefile_usage":39518208,"uptime":25484.65345954895},"values":[0.00011329121094050265,0.00011251386719024481,0.00011283476562340411],"warmups":[[1024,0.00011342001953096315]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152669","date":"2026-08-08 04:24:27.562318","duration":0.4797594999981811,"mem_peak_pagefile_usage":39530496,"uptime":25485.423697948456},"values":[0.0001125768554679496,0.00011220341797013589,0.00011230400390616069],"warmups":[[1024,0.00011322001952862593]]}]},{"metadata":{"loops":256,"name":"jinja2/cold-compile/trivial-substitution"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.152982","calibrate_loops":256,"date":"2026-08-08 04:24:28.458053","duration":0.6023344999994151,"mem_peak_pagefile_usage":40271872,"uptime":25486.321665763855},"warmups":[[1,0.0007891000022937078],[2,0.0005746499991801102],[4,0.0004901249994873069],[8,0.00046106249965305324],[16,0.00045363124991126824],[32,0.00045170937494276586],[64,0.00045489687499866704],[128,0.00045253124997657324],[256,0.0004551222656345999],[256,0.00045450390625489945],[256,0.0004528300781174721],[256,0.00045241445313592976]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145645","date":"2026-08-08 04:24:29.227023","duration":0.4706218999999692,"mem_peak_pagefile_usage":39600128,"uptime":25487.09508728981},"values":[0.00044140468750697437,0.00044144921875499676,0.000442251171875796],"warmups":[[256,0.0004409999999950287]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138721","date":"2026-08-08 04:24:29.989246","duration":0.4711170000009588,"mem_peak_pagefile_usage":39145472,"uptime":25487.867022275925},"values":[0.0004390839843750882,0.0004387640624941014,0.0004386425781319758],"warmups":[[256,0.00043989531249621905]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150433","date":"2026-08-08 04:24:30.793675","duration":0.46921780000047875,"mem_peak_pagefile_usage":39333888,"uptime":25488.6572265625},"values":[0.0004394171874935182,0.00044024179686630305,0.0004387886718717482],"warmups":[[256,0.0004403792968759035]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143225","date":"2026-08-08 04:24:31.557569","duration":0.47404659999665455,"mem_peak_pagefile_usage":39448576,"uptime":25489.43058347702},"values":[0.0004435175781338785,0.0004412054687463751,0.00044166289062275155],"warmups":[[256,0.0004426546875038184]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148889","date":"2026-08-08 04:24:32.322293","duration":0.470056600002863,"mem_peak_pagefile_usage":39837696,"uptime":25490.18763446808},"values":[0.00044021093749790907,0.0004405320312486083,0.00043995507812155665],"warmups":[[256,0.0004409113281269583]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140201","date":"2026-08-08 04:24:33.085103","duration":0.472066199999972,"mem_peak_pagefile_usage":39514112,"uptime":25490.961307764053},"values":[0.0004396039062584123,0.00044010742186628704,0.0004406941406216447],"warmups":[[256,0.00043975820312880387]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144200","date":"2026-08-08 04:24:33.848780","duration":0.4728273000000627,"mem_peak_pagefile_usage":39600128,"uptime":25491.718504428864},"values":[0.0004441453124996997,0.0004428945312469068,0.0004425050781264872],"warmups":[[256,0.0004440679687576221]]}]},{"metadata":{"loops":512,"name":"jinja2/cold-compile/large-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.151364","calibrate_loops":512,"date":"2026-08-08 04:24:34.877888","duration":0.7318761999995331,"mem_peak_pagefile_usage":39297024,"uptime":25492.74356007576},"warmups":[[1,0.0009271999988413882],[2,0.0003402500005904585],[4,0.0002938999996331404],[8,0.00027731249974749517],[16,0.0002771125000435859],[32,0.0002755531249931664],[64,0.00027803124999081774],[128,0.0002756632812577209],[256,0.0002768937499979529],[512,0.0002765953124992393],[512,0.0002770554687501203],[512,0.0002772249999978271],[512,0.000277600195317973]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140528","date":"2026-08-08 04:24:35.759570","duration":0.5862822999988566,"mem_peak_pagefile_usage":39673856,"uptime":25493.632563352585},"values":[0.0002769835937499465,0.00027735878906298694,0.0002770144531254459],"warmups":[[512,0.00027770136718174854]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145432","date":"2026-08-08 04:24:36.640067","duration":0.5865874000010081,"mem_peak_pagefile_usage":39424000,"uptime":25494.508240938187},"values":[0.0002774939453189518,0.00027738515625230775,0.0002768681640645809],"warmups":[[512,0.0002781035156260714]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146810","date":"2026-08-08 04:24:37.522626","duration":0.5902925999980653,"mem_peak_pagefile_usage":40321024,"uptime":25495.392320871353},"values":[0.00027762929687469295,0.00027792597656173257,0.00027751992188029817],"warmups":[[512,0.0002781847656265768]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139906","date":"2026-08-08 04:24:38.401353","duration":0.5838536000010208,"mem_peak_pagefile_usage":39895040,"uptime":25496.275415420532},"values":[0.00027569960937512406,0.000275305273433446,0.0002762294921936359],"warmups":[[512,0.0002762818359371977]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140634","date":"2026-08-08 04:24:39.301129","duration":0.6080072999975528,"mem_peak_pagefile_usage":39395328,"uptime":25497.174475431442},"values":[0.00028768906249609927,0.0002881322265579911,0.0002876496093762171],"warmups":[[512,0.0002875630859406897]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149934","date":"2026-08-08 04:24:40.175363","duration":0.588128899998992,"mem_peak_pagefile_usage":39436288,"uptime":25498.04231595993},"values":[0.0002761578125003439,0.0002764400390589117,0.0002765595703095869],"warmups":[[512,0.00027627187499490446]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144196","date":"2026-08-08 04:24:41.055456","duration":0.5871162000003096,"mem_peak_pagefile_usage":39366656,"uptime":25498.925067186356},"values":[0.000277798632815518,0.00027738593750115115,0.0002777882812523558],"warmups":[[512,0.0002771685546818503]]}]},{"metadata":{"loops":128,"name":"jinja2/cold-compile/mixed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.145885","calibrate_loops":128,"date":"2026-08-08 04:24:42.144856","duration":0.7870798999974795,"mem_peak_pagefile_usage":39776256,"uptime":25500.01330280304},"warmups":[[1,0.0015598999998474028],[2,0.0011948000010306714],[4,0.0011918999998670188],[8,0.001181237500077259],[16,0.0011801312500665517],[32,0.0011807937499952459],[64,0.0011953124999877218],[128,0.0011938460937699347],[128,0.00119941640625143],[128,0.0012183054687397998],[128,0.001200949999997647]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138168","date":"2026-08-08 04:24:43.022760","duration":0.5801178999972763,"mem_peak_pagefile_usage":39768064,"uptime":25500.89841556549},"values":[0.0010955890625155007,0.0010950492187475902,0.001099649218730292],"warmups":[[128,0.0010943867187620526]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146077","date":"2026-08-08 04:24:43.894168","duration":0.5860818999972253,"mem_peak_pagefile_usage":39665664,"uptime":25501.764491558075},"values":[0.0010971281250249376,0.0011047812499782594,0.0011103468749809053],"warmups":[[128,0.0010995609375186177]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145575","date":"2026-08-08 04:24:44.766711","duration":0.5813769999986107,"mem_peak_pagefile_usage":40034304,"uptime":25502.635065555573},"values":[0.0011007648437555417,0.0010992593749961088,0.0011019687499924657],"warmups":[[128,0.0010934999999960837]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139715","date":"2026-08-08 04:24:45.643281","duration":0.5808547000015096,"mem_peak_pagefile_usage":39657472,"uptime":25503.517180919647},"values":[0.0010982460937327687,0.0010956874999976662,0.001100925781230444],"warmups":[[128,0.0010985695312513144]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149631","date":"2026-08-08 04:24:46.517766","duration":0.5849812000014936,"mem_peak_pagefile_usage":39182336,"uptime":25504.38495707512},"values":[0.001098814843743412,0.0011006351562343752,0.0011034523437558619],"warmups":[[128,0.0010972789062577704]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138967","date":"2026-08-08 04:24:47.392856","duration":0.5792785000012373,"mem_peak_pagefile_usage":39493632,"uptime":25505.26773095131},"values":[0.0010934546874921125,0.001092913281240726,0.001094873437523347],"warmups":[[128,0.0010973734374886135]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147632","date":"2026-08-08 04:24:48.268954","duration":0.58207830000174,"mem_peak_pagefile_usage":39784448,"uptime":25506.135109186172},"values":[0.0011012070312688138,0.0011012898437456897,0.0011035984374814234],"warmups":[[128,0.0010958148437509863]]}]},{"metadata":{"loops":256,"name":"jinja2/cold-compile/conditional-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.139221","calibrate_loops":256,"date":"2026-08-08 04:24:49.565297","duration":0.9979707000020426,"mem_peak_pagefile_usage":40099840,"uptime":25507.442653656006},"warmups":[[1,0.0014140999992378056],[2,0.0008145499996317085],[4,0.0007817499999873689],[8,0.0007732375001978653],[16,0.0007575874999474763],[32,0.000752374999933636],[64,0.0007608859374954591],[128,0.000759864062501947],[256,0.0007635976562454516],[256,0.000762834375009902],[256,0.00076268749999997],[256,0.0007646707031341293]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139475","date":"2026-08-08 04:24:50.684204","duration":0.8055061000013666,"mem_peak_pagefile_usage":39628800,"uptime":25508.561022043228},"values":[0.000766158984376375,0.0007652027343851842,0.0007677730468742539],"warmups":[[256,0.0007646414062492113]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148512","date":"2026-08-08 04:24:51.781055","duration":0.8042925000008836,"mem_peak_pagefile_usage":40153088,"uptime":25509.648475170135},"values":[0.0007614468750034575,0.0007631093750006812,0.0007756316406215547],"warmups":[[256,0.000759951562500305]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140701","date":"2026-08-08 04:24:52.876088","duration":0.8032232000005024,"mem_peak_pagefile_usage":39448576,"uptime":25510.752321958542},"values":[0.0007596289062377082,0.0007648972656255637,0.0007640437499958352],"warmups":[[256,0.0007626386718868616]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146343","date":"2026-08-08 04:24:53.971090","duration":0.80228519999946,"mem_peak_pagefile_usage":40398848,"uptime":25511.841413974762},"values":[0.0007628738281226788,0.0007625371093809008,0.0007632933593839653],"warmups":[[256,0.0007602554687480279]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145178","date":"2026-08-08 04:24:55.059164","duration":0.7990824000007706,"mem_peak_pagefile_usage":39776256,"uptime":25512.930973768234},"values":[0.0007581921875043918,0.0007586460937574202,0.0007602472656174086],"warmups":[[256,0.0007580082031211077]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138862","date":"2026-08-08 04:24:56.155752","duration":0.8036870999967505,"mem_peak_pagefile_usage":39612416,"uptime":25514.03354048729},"values":[0.0007614589843711883,0.0007669101562584046,0.0007644679687501821],"warmups":[[256,0.0007621433593811844]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141049","date":"2026-08-08 04:24:57.243425","duration":0.7990518000005977,"mem_peak_pagefile_usage":39493632,"uptime":25515.119382619858},"values":[0.0007580187500053626,0.0007591847656271966,0.0007582335937570406],"warmups":[[256,0.000759330859366969]]}]},{"metadata":{"loops":512,"name":"jinja2/cold-compile/fragment-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.152722","calibrate_loops":512,"date":"2026-08-08 04:24:58.205452","duration":0.6618503999998211,"mem_peak_pagefile_usage":39305216,"uptime":25516.066563606262},"warmups":[[1,0.00098489999800222],[2,0.000339449999955832],[4,0.0002782000001388951],[8,0.0002575250000518281],[16,0.0002513437500510918],[32,0.00024876874999790743],[64,0.0002512625000008484],[128,0.00024939218749864267],[256,0.00025075351562975357],[512,0.00025099296875197297],[512,0.000251058398440307],[512,0.00025105527343782796],[512,0.0002503246093752409]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146738","date":"2026-08-08 04:24:59.036452","duration":0.5360142000026826,"mem_peak_pagefile_usage":39415808,"uptime":25516.90367126465},"values":[0.000252326953123827,0.00025224140625113023,0.00025252890625182545],"warmups":[[512,0.00025279511718423464]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141413","date":"2026-08-08 04:24:59.864519","duration":0.5364111999988381,"mem_peak_pagefile_usage":39337984,"uptime":25517.739312410355},"values":[0.0002520794921849756,0.00025094042968731856,0.00025091054687464975],"warmups":[[512,0.0002520974609367954]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140214","date":"2026-08-08 04:25:00.670733","duration":0.512456899999961,"mem_peak_pagefile_usage":40022016,"uptime":25518.5441300869},"values":[0.00024126523437217884,0.00024112890624650163,0.00024092109374862503],"warmups":[[512,0.00024174082030725685]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138079","date":"2026-08-08 04:25:01.471098","duration":0.5142534999977215,"mem_peak_pagefile_usage":38899712,"uptime":25519.349529981613},"values":[0.00024073671875157743,0.000240322656253511,0.0002400509765649872],"warmups":[[512,0.00024156679688047689]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139388","date":"2026-08-08 04:25:02.280051","duration":0.5142274999998335,"mem_peak_pagefile_usage":40067072,"uptime":25520.154310703278},"values":[0.00024253398437679152,0.00024187617187010346,0.00024137714843419644],"warmups":[[512,0.0002420794921889069]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138648","date":"2026-08-08 04:25:03.082720","duration":0.5153585999978532,"mem_peak_pagefile_usage":39915520,"uptime":25520.96092748642},"values":[0.00024077421875290383,0.00024084199218776803,0.00024099062499516322],"warmups":[[512,0.00024143437500612208]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152793","date":"2026-08-08 04:25:03.889237","duration":0.5117813000033493,"mem_peak_pagefile_usage":39407616,"uptime":25521.750012636185},"values":[0.000240222265624368,0.0002403443359355606,0.000240504296876054],"warmups":[[512,0.00024265000000411874]]}]},{"metadata":{"loops":512,"name":"jinja2/cold-compile/fortunes-encoded"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.145181","calibrate_loops":512,"date":"2026-08-08 04:25:04.998787","duration":0.8109581000026083,"mem_peak_pagefile_usage":39292928,"uptime":25522.870581150055},"warmups":[[1,0.0009959999988495838],[2,0.0003952000006393064],[4,0.0003218749998268322],[8,0.0003117999999631138],[16,0.0003054874998724699],[32,0.0003042781249860127],[64,0.00030846250001559383],[128,0.0003058679687342192],[256,0.0003071816406219341],[512,0.0003071828124987519],[512,0.00030830859374475494],[512,0.000308904492186457],[512,0.00030845019531255957]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141713","date":"2026-08-08 04:25:05.945717","duration":0.6500379999997676,"mem_peak_pagefile_usage":40009728,"uptime":25523.81819844246},"values":[0.00030765468750360014,0.00030800410156217595,0.00030793710937615515],"warmups":[[512,0.0003090515624961654]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142815","date":"2026-08-08 04:25:06.894743","duration":0.6504671000002418,"mem_peak_pagefile_usage":40550400,"uptime":25524.76579451561},"values":[0.00030843964843541016,0.00030794121093435933,0.00030807089844131497],"warmups":[[512,0.0003093312500013212]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142573","date":"2026-08-08 04:25:07.837200","duration":0.652044600003137,"mem_peak_pagefile_usage":39755776,"uptime":25525.711438655853},"values":[0.0003073091796892413,0.00030781738281149273,0.0003086515624985964],"warmups":[[512,0.0003075275390571619]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145978","date":"2026-08-08 04:25:08.788751","duration":0.657106599999679,"mem_peak_pagefile_usage":40357888,"uptime":25526.65708041191},"values":[0.0003115992187474603,0.0003109908203171585,0.0003111851562493939],"warmups":[[512,0.00031206464843336335]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140949","date":"2026-08-08 04:25:09.730314","duration":0.6452380000009725,"mem_peak_pagefile_usage":39489536,"uptime":25527.603189229965},"values":[0.0003059476562441432,0.0003058089843719358,0.00030604160156144644],"warmups":[[512,0.00030626992187876567]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139953","date":"2026-08-08 04:25:10.673090","duration":0.6530357000010554,"mem_peak_pagefile_usage":38879232,"uptime":25528.549255371094},"values":[0.0003084955078165308,0.00030790156250048994,0.0003087865234334686],"warmups":[[512,0.0003086451171867566]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152621","date":"2026-08-08 04:25:11.618913","duration":0.6523545999989437,"mem_peak_pagefile_usage":40153088,"uptime":25529.48017692566},"values":[0.0003085642578142256,0.0003088125000019204,0.000309127734375636],"warmups":[[512,0.0003105181640634669]]}]},{"metadata":{"loops":512,"name":"jinja2/cold-compile/encoded-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.147975","calibrate_loops":512,"date":"2026-08-08 04:25:12.842316","duration":0.9233518000000913,"mem_peak_pagefile_usage":39460864,"uptime":25530.710470199585},"warmups":[[1,0.0007208999995782506],[2,0.0004109999990760116],[4,0.0003659249996417202],[8,0.00035840000009557116],[16,0.00034978749999936554],[32,0.0003508812500285785],[64,0.0003532015625182794],[128,0.0003525656249792064],[256,0.00035312500000372893],[512,0.00035602832031145226],[512,0.00035165019531291364],[512,0.0003511093749963834],[512,0.00035015175781438757]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149748","date":"2026-08-08 04:25:13.882309","duration":0.7482273999994504,"mem_peak_pagefile_usage":38920192,"uptime":25531.74867749214},"values":[0.0003550644531244984,0.00035556738281172784,0.00035559062499856964],"warmups":[[512,0.00035391738281020935]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151181","date":"2026-08-08 04:25:14.923067","duration":0.749679800002923,"mem_peak_pagefile_usage":39542784,"uptime":25532.78825712204},"values":[0.000355184765624017,0.00035584746093775266,0.0003562800781296005],"warmups":[[512,0.0003552769531225408]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143029","date":"2026-08-08 04:25:15.986574","duration":0.7440521999997145,"mem_peak_pagefile_usage":39702528,"uptime":25533.860426664352},"values":[0.0003536035156201933,0.00035185937500159525,0.00035149804687506503],"warmups":[[512,0.00035362031250230075]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153563","date":"2026-08-08 04:25:17.024441","duration":0.7465972999998485,"mem_peak_pagefile_usage":39587840,"uptime":25534.88764023781},"values":[0.0003542541015661982,0.00035349687500030313,0.0003526267578166653],"warmups":[[512,0.0003551310546825448]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145388","date":"2026-08-08 04:25:18.058737","duration":0.7441206000003149,"mem_peak_pagefile_usage":39448576,"uptime":25535.930055379868},"values":[0.0003530808593694701,0.0003527289062503769,0.0003525410156228759],"warmups":[[512,0.0003526732421903489]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144047","date":"2026-08-08 04:25:19.098403","duration":0.746293299998797,"mem_peak_pagefile_usage":39510016,"uptime":25536.97066640854},"values":[0.00035568085937143223,0.0003532746093739547,0.0003531980468736151],"warmups":[[512,0.0003542328125050176]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139217","date":"2026-08-08 04:25:20.133663","duration":0.7471360999988974,"mem_peak_pagefile_usage":39661568,"uptime":25538.011513233185},"values":[0.0003546779296854652,0.00035435507812309197,0.0003545966796920652],"warmups":[[512,0.0003527749999960861]]}]},{"metadata":{"loops":1024,"name":"mako/cold-compile/composed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.152130","calibrate_loops":1024,"date":"2026-08-08 04:25:21.157774","duration":0.7199351000017487,"mem_peak_pagefile_usage":39841792,"uptime":25539.02259516716},"warmups":[[1,0.0006407000000763219],[2,0.0002659999991010409],[4,0.00014747499972145306],[8,0.0001515250000920787],[16,0.00013120624998919084],[32,0.00013436250003451278],[64,0.00013507031252402157],[128,0.0001349484375054999],[256,0.0001351945312535463],[512,0.0001351410156260613],[1024,0.00013583046874998672],[1024,0.0001351149414077213],[1024,0.0001389916015632764],[1024,0.0001356618164045642]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151688","date":"2026-08-08 04:25:22.074802","duration":0.6218714999995427,"mem_peak_pagefile_usage":39321600,"uptime":25539.936862945557},"values":[0.00014658925780963727,0.00014567636718609833,0.00014962070312662945],"warmups":[[1024,0.0001470988281226937]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153374","date":"2026-08-08 04:25:22.943612","duration":0.5759885999977996,"mem_peak_pagefile_usage":40357888,"uptime":25540.804279327393},"values":[0.0001352989257838999,0.00013501152343664558,0.00013836796875210666],"warmups":[[1024,0.00013503281249782617]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142805","date":"2026-08-08 04:25:23.812766","duration":0.581126499997481,"mem_peak_pagefile_usage":39804928,"uptime":25541.68704342842},"values":[0.0001354652343756868,0.00013520371093633798,0.0001391451171883773],"warmups":[[1024,0.00013587958984473403]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146447","date":"2026-08-08 04:25:24.686291","duration":0.5792818000008992,"mem_peak_pagefile_usage":39690240,"uptime":25542.553694963455},"values":[0.00013615224609253573,0.0001356400390619683,0.0001392541015619031],"warmups":[[1024,0.00013636298828245685]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140923","date":"2026-08-08 04:25:25.563206","duration":0.5799674000008963,"mem_peak_pagefile_usage":39809024,"uptime":25543.436185836792},"values":[0.00013616728515586374,0.00013573681640721702,0.000139276757810336],"warmups":[[1024,0.00013670185546743596]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138001","date":"2026-08-08 04:25:26.425178","duration":0.5761237000006076,"mem_peak_pagefile_usage":39579648,"uptime":25544.304121494293},"values":[0.00013442421874998445,0.00013397509765766813,0.00013797900390599693],"warmups":[[1024,0.00013469365234541897]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152289","date":"2026-08-08 04:25:27.294287","duration":0.5771488999998837,"mem_peak_pagefile_usage":39694336,"uptime":25545.155826330185},"values":[0.00013520419921775328,0.00013495859374756947,0.00013845839843540375],"warmups":[[1024,0.00013640048828023055]]}]},{"metadata":{"loops":256,"name":"mako/cold-compile/trivial-substitution"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.138495","calibrate_loops":256,"date":"2026-08-08 04:25:28.322493","duration":0.725107800000842,"mem_peak_pagefile_usage":39526400,"uptime":25546.197691679},"warmups":[[1,0.0012119000020902604],[2,0.0005977500004519243],[4,0.0006026499995641643],[8,0.0005520499998965533],[16,0.0005512562499916385],[32,0.0005536406250712389],[64,0.0005483093750058288],[128,0.0005504304687633521],[256,0.0005498718750089893],[256,0.0005519093749910553],[256,0.000552690624999741],[256,0.0005526121093737402]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151880","date":"2026-08-08 04:25:29.155838","duration":0.5369371000015235,"mem_peak_pagefile_usage":39763968,"uptime":25547.017512321472},"values":[0.0005049765624960401,0.0005062749999922289,0.0005067128906262042],"warmups":[[256,0.0005071031250025726]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149493","date":"2026-08-08 04:25:30.033576","duration":0.588861000000179,"mem_peak_pagefile_usage":39309312,"uptime":25547.90079164505},"values":[0.0005522226562391097,0.0005530136718761014,0.0005526250000116306],"warmups":[[256,0.0005580023437516957]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138070","date":"2026-08-08 04:25:30.861435","duration":0.5319080999979633,"mem_peak_pagefile_usage":39575552,"uptime":25548.73726773262},"values":[0.0005008769531258395,0.0005005703124965066,0.000499707812494421],"warmups":[[256,0.0005033832031244856]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147397","date":"2026-08-08 04:25:31.687655","duration":0.5372446000001219,"mem_peak_pagefile_usage":39403520,"uptime":25549.55689930916},"values":[0.0005022789062536503,0.0005030472656244456,0.0005036281250028196],"warmups":[[256,0.0005051753906286649]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139257","date":"2026-08-08 04:25:32.515988","duration":0.5339657999975316,"mem_peak_pagefile_usage":39653376,"uptime":25550.390372753143},"values":[0.0005023054687569584,0.0005031546874931792,0.0005045089843775941],"warmups":[[256,0.0005028242187421483]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145926","date":"2026-08-08 04:25:33.341938","duration":0.5382497999999032,"mem_peak_pagefile_usage":39591936,"uptime":25551.21261358261},"values":[0.0005046796874950132,0.0005035734374985168,0.0005048101562579177],"warmups":[[256,0.000504560156244338]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149827","date":"2026-08-08 04:25:34.169550","duration":0.5357054000014614,"mem_peak_pagefile_usage":39583744,"uptime":25552.033697605133},"values":[0.0005040367187518768,0.000504210156250906,0.0005040199218768748],"warmups":[[256,0.0005061976562501513]]}]},{"metadata":{"loops":512,"name":"mako/cold-compile/large-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.138413","calibrate_loops":512,"date":"2026-08-08 04:25:35.198867","duration":0.7279866999997466,"mem_peak_pagefile_usage":39497728,"uptime":25553.07733821869},"warmups":[[1,0.0008611999983259011],[2,0.0003753500004677335],[4,0.00028899999961140566],[8,0.0002927874998022162],[16,0.0002672124999207881],[32,0.000272296874982203],[64,0.0002750281249745967],[128,0.0002730492187481559],[256,0.0002737929687555152],[512,0.0002741443359397522],[512,0.000274658203125],[512,0.00027427617187214537],[512,0.00028106816406392454]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145013","date":"2026-08-08 04:25:36.029690","duration":0.5355772000002617,"mem_peak_pagefile_usage":39538688,"uptime":25553.898242235184},"values":[0.0002518855468736092,0.0002521345703101474,0.0002517994140660562],"warmups":[[512,0.0002536250000062523]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141744","date":"2026-08-08 04:25:36.859850","duration":0.5413871000018844,"mem_peak_pagefile_usage":40148992,"uptime":25554.734959840775},"values":[0.0002532908203178863,0.0002535259765608089,0.00025293789062175165],"warmups":[[512,0.00025470800780880154]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147974","date":"2026-08-08 04:25:37.689180","duration":0.5342474000026414,"mem_peak_pagefile_usage":39624704,"uptime":25555.554881811142},"values":[0.0002515519531272048,0.0002519158203142524,0.0002517732421836172],"warmups":[[512,0.0002518445312489348]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152015","date":"2026-08-08 04:25:38.510500","duration":0.5339975999995659,"mem_peak_pagefile_usage":39649280,"uptime":25556.374823331833},"values":[0.0002499017578116991,0.0002501322265615613,0.0002493421875016111],"warmups":[[512,0.0002517853515655588]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144042","date":"2026-08-08 04:25:39.340136","duration":0.5361130999990564,"mem_peak_pagefile_usage":39530496,"uptime":25557.210516929626},"values":[0.0002517791015606008,0.000252238085934664,0.00025226250000542905],"warmups":[[512,0.00025282636718770846]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152183","date":"2026-08-08 04:25:40.167315","duration":0.5391808999993373,"mem_peak_pagefile_usage":39190528,"uptime":25558.031314849854},"values":[0.00025262050781549306,0.0002532564453119335,0.000252148828124632],"warmups":[[512,0.0002538134765615041]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144083","date":"2026-08-08 04:25:40.998282","duration":0.5360782999996445,"mem_peak_pagefile_usage":39116800,"uptime":25558.867978572845},"values":[0.00025259023437484984,0.00025245585937483384,0.000251831054690399],"warmups":[[512,0.0002535361328099839]]}]},{"metadata":{"loops":128,"name":"mako/cold-compile/mixed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.148034","calibrate_loops":128,"date":"2026-08-08 04:25:41.976858","duration":0.6821256000002904,"mem_peak_pagefile_usage":39342080,"uptime":25559.84517979622},"warmups":[[1,0.0016900999980862252],[2,0.0010302999999112217],[4,0.0010860749998755637],[8,0.001043275000029098],[16,0.001015518749909461],[32,0.001043215624918048],[64,0.001024539062484564],[128,0.0010332999999889125],[128,0.001033961718746923],[128,0.001033975781240315],[128,0.0010299062500109812]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152711","date":"2026-08-08 04:25:42.772255","duration":0.4960511999997834,"mem_peak_pagefile_usage":40157184,"uptime":25560.63332438469},"values":[0.0009310101562505224,0.0009286406250055279,0.0009322031250178497],"warmups":[[128,0.0009345929687754051]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148819","date":"2026-08-08 04:25:43.555241","duration":0.49445600000035483,"mem_peak_pagefile_usage":40189952,"uptime":25561.423258304596},"values":[0.0009226960937667172,0.0009224484375067732,0.0009218335937362099],"warmups":[[128,0.0009253039062571133]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146532","date":"2026-08-08 04:25:44.345586","duration":0.4944026000011945,"mem_peak_pagefile_usage":39682048,"uptime":25562.212779521942},"values":[0.0009295820312331671,0.0009288578124824198,0.0009294374999910815],"warmups":[[128,0.0009288304687515847]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142867","date":"2026-08-08 04:25:45.129234","duration":0.49687559999802033,"mem_peak_pagefile_usage":39182336,"uptime":25563.002384901047},"values":[0.000931032812502508,0.0009263015624867421,0.0009282382812614287],"warmups":[[128,0.000932324999979528]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141135","date":"2026-08-08 04:25:45.919282","duration":0.49701660000209813,"mem_peak_pagefile_usage":39608320,"uptime":25563.79211330414},"values":[0.0009329890625053849,0.0009318234374973144,0.0009310867187650729],"warmups":[[128,0.0009375164062532804]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139120","date":"2026-08-08 04:25:46.704946","duration":0.4968040999992809,"mem_peak_pagefile_usage":40132608,"uptime":25564.582278490067},"values":[0.0009277156250107055,0.0009279437500140375,0.0009252539062458709],"warmups":[[128,0.0009318484374887248]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149874","date":"2026-08-08 04:25:47.491427","duration":0.49231139999756124,"mem_peak_pagefile_usage":39624704,"uptime":25565.355080127716},"values":[0.0009256335937379845,0.0009235750000016196,0.0009247054687477885],"warmups":[[128,0.0009274984375053918]]}]},{"metadata":{"loops":256,"name":"mako/cold-compile/conditional-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.145708","calibrate_loops":256,"date":"2026-08-08 04:25:48.570412","duration":0.7814120999973966,"mem_peak_pagefile_usage":39231488,"uptime":25566.441714525223},"warmups":[[1,0.0010131999988516327],[2,0.0006318999985523988],[4,0.0006133500000942149],[8,0.0006130249998932413],[16,0.0005945499999597814],[32,0.0005902812499698484],[64,0.0005917093750440472],[128,0.0005937539062585984],[256,0.0005940722656276876],[256,0.0005928722656278751],[256,0.0005923660156241795],[256,0.000593759765635582]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150972","date":"2026-08-08 04:25:49.446784","duration":0.5775291999998444,"mem_peak_pagefile_usage":39743488,"uptime":25567.309607744217},"values":[0.0005463945312556007,0.0005435773437483249,0.0005445257812510818],"warmups":[[256,0.0005487195312383619]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150789","date":"2026-08-08 04:25:50.313576","duration":0.5742943000004743,"mem_peak_pagefile_usage":39440384,"uptime":25568.176649808884},"values":[0.0005421671875041056,0.0005414527343674536,0.0005420132812474776],"warmups":[[256,0.0005450046874955206]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142981","date":"2026-08-08 04:25:51.202290","duration":0.5799480000023323,"mem_peak_pagefile_usage":39145472,"uptime":25569.075705051422},"values":[0.0005441792968667869,0.0005447683593757802,0.0005457464843772186],"warmups":[[256,0.000548452734378202]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143476","date":"2026-08-08 04:25:52.074150","duration":0.5767022999971232,"mem_peak_pagefile_usage":39768064,"uptime":25569.944233894348},"values":[0.0005442874999914693,0.000544682421875109,0.0005455140624945898],"warmups":[[256,0.0005467874999993683]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152529","date":"2026-08-08 04:25:52.996988","duration":0.6280268999980763,"mem_peak_pagefile_usage":39813120,"uptime":25570.858200073242},"values":[0.0005944320312494256,0.0005935097656220023,0.0005928210937469203],"warmups":[[256,0.0005999281249984278]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145435","date":"2026-08-08 04:25:53.872665","duration":0.5854808000003686,"mem_peak_pagefile_usage":39514112,"uptime":25571.743480443954},"values":[0.0005502933593675152,0.0005506429687471837,0.0005507874999892692],"warmups":[[256,0.0005523816406309834]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140840","date":"2026-08-08 04:25:54.737699","duration":0.5704135999985738,"mem_peak_pagefile_usage":39534592,"uptime":25572.61032986641},"values":[0.0005386554687447642,0.0005379925781312522,0.0005390429687537335],"warmups":[[256,0.0005411929687539896]]}]},{"metadata":{"loops":512,"name":"mako/cold-compile/fragment-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.138207","calibrate_loops":512,"date":"2026-08-08 04:25:55.651124","duration":0.6084106000016618,"mem_peak_pagefile_usage":39501824,"uptime":25573.52669453621},"warmups":[[1,0.0006826999997429084],[2,0.0002965000003314344],[4,0.00024694999956409447],[8,0.0002514375000828295],[16,0.00022400625016416598],[32,0.00023052812491641816],[64,0.00022881562500742803],[128,0.0002308562499990785],[256,0.00022980937499994525],[512,0.00022967519531391645],[512,0.00023000605468581625],[512,0.0002307371093763777],[512,0.00022974707031409025]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139036","date":"2026-08-08 04:25:56.391015","duration":0.4536078000019188,"mem_peak_pagefile_usage":39628800,"uptime":25574.268807411194},"values":[0.00021037792969025304,0.00021050332031080643,0.00021045664062313563],"warmups":[[512,0.00021195000000062691]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143607","date":"2026-08-08 04:25:57.138122","duration":0.4531661000000895,"mem_peak_pagefile_usage":39321600,"uptime":25575.00834298134},"values":[0.00021219941406513954,0.00021176015625457012,0.00021224472656200533],"warmups":[[512,0.00021199667968829772]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148160","date":"2026-08-08 04:25:57.882475","duration":0.45711990000199876,"mem_peak_pagefile_usage":39616512,"uptime":25575.75084376335},"values":[0.00021210605468979793,0.00021280722656058515,0.00021276542968706735],"warmups":[[512,0.00021306054687642018]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152755","date":"2026-08-08 04:25:58.632137","duration":0.45361399999819696,"mem_peak_pagefile_usage":39624704,"uptime":25576.49319601059},"values":[0.00021195585937761052,0.0002120138671841687,0.00021195859375211512],"warmups":[[512,0.00021292890625090877]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142619","date":"2026-08-08 04:25:59.376416","duration":0.45695789999808767,"mem_peak_pagefile_usage":39981056,"uptime":25577.250426054},"values":[0.00021219550781381713,0.00021212851562779633,0.00021214921875412074],"warmups":[[512,0.00021392910156237122]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144070","date":"2026-08-08 04:26:00.123608","duration":0.4528648000014073,"mem_peak_pagefile_usage":39653376,"uptime":25577.993360996246},"values":[0.00021133417968854928,0.00021134628906338548,0.00021252187499953834],"warmups":[[512,0.00021220253906051312]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143339","date":"2026-08-08 04:26:00.878221","duration":0.4571027999991202,"mem_peak_pagefile_usage":39264256,"uptime":25578.751495599747},"values":[0.00021208066406330772,0.00021231816405986592,0.00021242910156615835],"warmups":[[512,0.0002138255859378546]]}]},{"metadata":{"loops":512,"name":"mako/cold-compile/fortunes-encoded"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.140316","calibrate_loops":512,"date":"2026-08-08 04:26:01.979501","duration":0.8026231000003463,"mem_peak_pagefile_usage":39313408,"uptime":25579.855825424194},"warmups":[[1,0.0008808999991742894],[2,0.00036639999962062575],[4,0.00032660000033502],[8,0.0003245249999963562],[16,0.00029451250020429143],[32,0.00031041875001847075],[64,0.00030198906250689106],[128,0.00030443593752238485],[256,0.0003035152343784375],[512,0.0003035189453157727],[512,0.0003037300781230101],[512,0.0003027253906253691],[512,0.00031014628905978725]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147220","date":"2026-08-08 04:26:02.856684","duration":0.5832911000034073,"mem_peak_pagefile_usage":38797312,"uptime":25580.723154067993},"values":[0.00027575742187480046,0.00027536230469138445,0.0002745767578176128],"warmups":[[512,0.0002769890624989557]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138998","date":"2026-08-08 04:26:03.778123","duration":0.5879528000004939,"mem_peak_pagefile_usage":39006208,"uptime":25581.653215646744},"values":[0.0002768099609369301,0.000278123046875578,0.0002768322265609413],"warmups":[[512,0.000278941210936523]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147011","date":"2026-08-08 04:26:04.699579","duration":0.5919212000007974,"mem_peak_pagefile_usage":38793216,"uptime":25582.56930232048},"values":[0.00027753671875530017,0.0002784388671912552,0.00027771816405675054],"warmups":[[512,0.00027960898437839887]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147146","date":"2026-08-08 04:26:05.585063","duration":0.5886040999976103,"mem_peak_pagefile_usage":39940096,"uptime":25583.451979875565},"values":[0.00027766582031318876,0.00027794570311812095,0.00027785371093358435],"warmups":[[512,0.0002787800781263172]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148079","date":"2026-08-08 04:26:06.468935","duration":0.5904387000009592,"mem_peak_pagefile_usage":39346176,"uptime":25584.335198402405},"values":[0.00027931328124708443,0.0002784466796939,0.0002784951171861394],"warmups":[[512,0.00027947773437375645]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138028","date":"2026-08-08 04:26:07.354775","duration":0.594986299998709,"mem_peak_pagefile_usage":40103936,"uptime":25585.233501434326},"values":[0.00027924707030990703,0.00027918847656138723,0.0002789988281222122],"warmups":[[512,0.0002823880859352812]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150673","date":"2026-08-08 04:26:08.238466","duration":0.5873011000003316,"mem_peak_pagefile_usage":39288832,"uptime":25586.101392269135},"values":[0.0002768783203137559,0.00027733769531579355,0.00027719843750162454],"warmups":[[512,0.00027936523437688265]]}]},{"metadata":{"loops":512,"name":"mako/cold-compile/encoded-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.152018","calibrate_loops":512,"date":"2026-08-08 04:26:09.449892","duration":0.9115278000026592,"mem_peak_pagefile_usage":39260160,"uptime":25587.314673423767},"warmups":[[1,0.0005866999999852851],[2,0.00042609999945852906],[4,0.0003718250000019907],[8,0.0003718875000231492],[16,0.00033540000003995374],[32,0.0003487187499331412],[64,0.00034286249996284823],[128,0.0003472484374924534],[256,0.0003451730468810865],[512,0.00034601406250089894],[512,0.0003457876953092409],[512,0.00034576855468770873],[512,0.00035386562499439833]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149260","date":"2026-08-08 04:26:10.411395","duration":0.6636801999993622,"mem_peak_pagefile_usage":39821312,"uptime":25588.27565574646},"values":[0.00031418437500008167,0.0003146023437494705,0.0003151808593742089],"warmups":[[512,0.0003164757812541552]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148316","date":"2026-08-08 04:26:11.372286","duration":0.6643791000024066,"mem_peak_pagefile_usage":39043072,"uptime":25589.237517118454},"values":[0.0003145203125001217,0.0003151070312483739,0.0003153291015607351],"warmups":[[512,0.0003168757812517242]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143726","date":"2026-08-08 04:26:12.389632","duration":0.7300168999972811,"mem_peak_pagefile_usage":39305216,"uptime":25590.26228070259},"values":[0.0003452839843802735,0.00034568378906385533,0.00034592128906041353],"warmups":[[512,0.00034767773437494043]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139214","date":"2026-08-08 04:26:13.351849","duration":0.669591699999728,"mem_peak_pagefile_usage":38899712,"uptime":25591.226218938828},"values":[0.000317415234370344,0.00031772851562550386,0.00031724218749928923],"warmups":[[512,0.0003190054687465249]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150253","date":"2026-08-08 04:26:14.309924","duration":0.664640099999815,"mem_peak_pagefile_usage":39845888,"uptime":25592.173590660095},"values":[0.0003147394531239911,0.0003150099609356971,0.0003150771484357051],"warmups":[[512,0.0003167367187515424]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149474","date":"2026-08-08 04:26:15.269303","duration":0.6699899000013829,"mem_peak_pagefile_usage":39526400,"uptime":25593.136585474014},"values":[0.0003150382812435737,0.0003143009765622651,0.0003144898437525967],"warmups":[[512,0.00031590410156212556]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139981","date":"2026-08-08 04:26:16.225452","duration":0.658173200001329,"mem_peak_pagefile_usage":39706624,"uptime":25594.099388599396},"values":[0.00031142363281588814,0.00031223320312534497,0.00031148339844122575],"warmups":[[512,0.0003135810546837092]]}]}],"metadata":{"cpu_affinity":"4","cpu_count":32,"hostname":"DESKTOP-F5QFSMS","perf_version":"2.10.0","platform":"Windows-11-10.0.26200-SP0","python_compiler":"MSC v.1944 64 bit (AMD64)","python_executable":"E:\\Work\\Heddle\\benchmarks\\python\\.venv\\Scripts\\python.exe","python_implementation":"cpython","python_version":"3.14.7 (64-bit) revision 823f032","timer":"QueryPerformanceCounter(), resolution: 100 ns","unit":"second"},"version":"1.0"} diff --git a/docs/benchmarks/2026-08-08/python/bench_jinja2_controlled.json b/docs/benchmarks/2026-08-08/python/bench_jinja2_controlled.json new file mode 100644 index 00000000..8f890893 --- /dev/null +++ b/docs/benchmarks/2026-08-08/python/bench_jinja2_controlled.json @@ -0,0 +1 @@ +{"benchmarks":[{"metadata":{"loops":8192,"name":"jinja2/controlled/composed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.141765","calibrate_loops":8192,"date":"2026-08-08 04:09:42.228452","duration":1.3068468000019493,"mem_peak_pagefile_usage":39010304,"uptime":24600.10351252556},"warmups":[[1,0.00010320000001229346],[2,2.8450000172597356e-05],[4,2.764999953797087e-05],[8,2.006249997066334e-05],[16,1.9481250092212576e-05],[32,1.9709375010279473e-05],[64,1.952031249174979e-05],[128,1.945390624769061e-05],[256,1.94460937450458e-05],[512,1.9510937498523617e-05],[1024,1.947763671594771e-05],[2048,1.951596679639067e-05],[4096,1.946774902350512e-05],[8192,1.9573693847529938e-05],[8192,1.9611364746374704e-05],[8192,1.9603723144800966e-05],[8192,1.9616967773750105e-05],[8192,1.961359863278389e-05],[8192,1.9623937987933715e-05],[8192,1.9641125488245592e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144872","date":"2026-08-08 04:09:43.588020","duration":1.1282833000004757,"mem_peak_pagefile_usage":39677952,"uptime":24601.459538459778},"values":[1.923891601540717e-05,1.9248852539455186e-05,1.927109375010616e-05,1.9325512695456126e-05,1.9358044433648303e-05,1.9359106445460128e-05],"warmups":[[8192,1.9303759765776363e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151966","date":"2026-08-08 04:09:44.936212","duration":1.1189669000013964,"mem_peak_pagefile_usage":39448576,"uptime":24602.80141735077},"values":[1.906207275403915e-05,1.911260986320329e-05,1.910590820308755e-05,1.9095690917847463e-05,1.907719726590429e-05,1.9153088378853766e-05],"warmups":[[8192,1.9270019531170135e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146472","date":"2026-08-08 04:09:46.287154","duration":1.1225562999970862,"mem_peak_pagefile_usage":39481344,"uptime":24604.15771317482},"values":[1.9204125976557407e-05,1.9199853515949883e-05,1.918764648412008e-05,1.9199609375242233e-05,1.9194555664459045e-05,1.9133862304343552e-05],"warmups":[[8192,1.9214819336088595e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147728","date":"2026-08-08 04:09:47.676720","duration":1.1619081999997434,"mem_peak_pagefile_usage":38957056,"uptime":24605.54493713379},"values":[1.991441650384118e-05,1.990437011700763e-05,1.9868530273470242e-05,1.9866772460908066e-05,1.992878417933497e-05,1.9865563964938104e-05],"warmups":[[8192,1.992088623037347e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148997","date":"2026-08-08 04:09:49.034302","duration":1.1311086999994586,"mem_peak_pagefile_usage":39714816,"uptime":24606.90172290802},"values":[1.936124267576389e-05,1.9389746093612104e-05,1.9322717284886437e-05,1.9300024414192762e-05,1.9354858398212826e-05,1.9270068359222847e-05],"warmups":[[8192,1.944696044908767e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151168","date":"2026-08-08 04:09:50.393532","duration":1.1340641000024334,"mem_peak_pagefile_usage":39567360,"uptime":24608.258642435074},"values":[1.9461804199316646e-05,1.9398571777351492e-05,1.938853759764214e-05,1.93421386716075e-05,1.9359240722938154e-05,1.931090087925469e-05],"warmups":[[8192,1.956394042945675e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139476","date":"2026-08-08 04:09:51.783173","duration":1.1448420000015176,"mem_peak_pagefile_usage":38776832,"uptime":24609.659925937653},"values":[1.964571533186188e-05,1.948450927713452e-05,1.95240844726996e-05,1.9540283203056674e-05,1.966904296857308e-05,1.967019042936613e-05],"warmups":[[8192,1.9612036132876653e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147175","date":"2026-08-08 04:09:53.131224","duration":1.1222676999968826,"mem_peak_pagefile_usage":39657472,"uptime":24611.00074338913},"values":[1.9156347656146266e-05,1.9211950683217793e-05,1.9189172363542895e-05,1.9200512695327632e-05,1.918111572241088e-05,1.9202490234793146e-05],"warmups":[[8192,1.919537353511913e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138926","date":"2026-08-08 04:09:54.511091","duration":1.1550318000008701,"mem_peak_pagefile_usage":39473152,"uptime":24612.389043331146},"values":[1.976247558577171e-05,1.9749572753635647e-05,1.977319335910721e-05,1.9741845703080685e-05,1.9732995605536985e-05,1.971142578094387e-05],"warmups":[[8192,1.9832763671789877e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151774","date":"2026-08-08 04:09:55.866078","duration":1.130055400000856,"mem_peak_pagefile_usage":39325696,"uptime":24613.730424404144},"values":[1.9382299804693304e-05,1.929666748035075e-05,1.93081298829334e-05,1.9366223144245964e-05,1.9306396484619626e-05,1.925360107390972e-05],"warmups":[[8192,1.9433776855759533e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148380","date":"2026-08-08 04:09:57.233169","duration":1.139282700001786,"mem_peak_pagefile_usage":39571456,"uptime":24615.101952314377},"values":[1.9444702148430082e-05,1.9520336913991798e-05,1.9525415039023386e-05,1.95250244141576e-05,1.9440173339546618e-05,1.9473217773402496e-05],"warmups":[[8192,1.9410595703206468e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150988","date":"2026-08-08 04:09:58.625690","duration":1.1442739999984042,"mem_peak_pagefile_usage":38862848,"uptime":24616.491351127625},"values":[1.9608544922000704e-05,1.9656591796923806e-05,1.9584313964760014e-05,1.9574108887088215e-05,1.9512512206887322e-05,1.9476489257819196e-05],"warmups":[[8192,1.9631896972516216e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144574","date":"2026-08-08 04:09:59.975498","duration":1.1251406999981555,"mem_peak_pagefile_usage":39473152,"uptime":24617.847705841064},"values":[1.9291931152576325e-05,1.920141601585712e-05,1.9201513671962545e-05,1.918854980464957e-05,1.919747314449438e-05,1.923375244139436e-05],"warmups":[[8192,1.9360009765545527e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151678","date":"2026-08-08 04:10:01.309535","duration":1.0841701999997895,"mem_peak_pagefile_usage":38940672,"uptime":24619.17387509346},"values":[1.8489257812337456e-05,1.8496069336126908e-05,1.8537939453278085e-05,1.856347656259416e-05,1.8550073241918597e-05,1.853015136754621e-05],"warmups":[[8192,1.8610815429642713e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139271","date":"2026-08-08 04:10:02.669955","duration":1.1349699999991572,"mem_peak_pagefile_usage":39456768,"uptime":24620.547261476517},"values":[1.9593591308542102e-05,1.942159423817813e-05,1.9287072754003987e-05,1.931771240260005e-05,1.9307995605455375e-05,1.9303820800509186e-05],"warmups":[[8192,1.9657775879089456e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145813","date":"2026-08-08 04:10:04.048625","duration":1.1532535000005737,"mem_peak_pagefile_usage":39116800,"uptime":24621.919795513153},"values":[1.9709448241922445e-05,1.9737451171675247e-05,1.9717431640309258e-05,1.9722985840076035e-05,1.9700183105264557e-05,1.964849853486328e-05],"warmups":[[8192,1.9835278320279315e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151700","date":"2026-08-08 04:10:05.396772","duration":1.1209677000006195,"mem_peak_pagefile_usage":39731200,"uptime":24623.26112294197},"values":[1.9177258300917543e-05,1.9155310058582842e-05,1.9139355468489327e-05,1.9159509277333342e-05,1.9177832031314068e-05,1.919840087882818e-05],"warmups":[[8192,1.9262487792826022e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139713","date":"2026-08-08 04:10:06.708958","duration":1.085678100000223,"mem_peak_pagefile_usage":39825408,"uptime":24624.585831165314},"values":[1.8540710449599374e-05,1.8539953613228022e-05,1.8509033202995795e-05,1.8515783691164245e-05,1.8549426269665048e-05,1.85888305663795e-05],"warmups":[[8192,1.8635058593563514e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142154","date":"2026-08-08 04:10:08.116184","duration":1.1829933999979403,"mem_peak_pagefile_usage":39542784,"uptime":24625.99068260193},"values":[2.030231933591864e-05,2.0276831054655275e-05,2.0242395019298698e-05,2.0229992675702135e-05,2.0240991211117887e-05,2.0147570800599368e-05],"warmups":[[8192,2.0305053710867327e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139670","date":"2026-08-08 04:10:09.485769","duration":1.1426585000008345,"mem_peak_pagefile_usage":39460864,"uptime":24627.362960100174},"values":[1.9450122070274745e-05,1.9424218749897193e-05,1.9412145996433594e-05,1.940621337892523e-05,1.9399572753986405e-05,1.931114501951825e-05],"warmups":[[8192,1.9473022460747558e-05]]}]},{"metadata":{"loops":32768,"name":"jinja2/controlled/trivial-substitution"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.150468","calibrate_loops":32768,"date":"2026-08-08 04:10:10.980189","duration":1.2413099999976112,"mem_peak_pagefile_usage":39157760,"uptime":24628.846656560898},"warmups":[[1,4.4299998990027234e-05],[2,1.4399998690350913e-05],[4,9.675000001152512e-06],[8,1.176249998025014e-05],[16,4.518750074566924e-06],[32,4.465625011107477e-06],[64,4.445312526968337e-06],[128,4.515624993928213e-06],[256,4.530468757479866e-06],[512,4.583984377859451e-06],[1024,4.636132814539451e-06],[2048,4.637353514524989e-06],[4096,4.651440430158971e-06],[8192,4.641577148412068e-06],[16384,4.626654052763968e-06],[32768,4.650576782228022e-06],[32768,4.660855102534001e-06],[32768,4.684381103570168e-06],[32768,4.678747558606311e-06],[32768,4.6436920165815465e-06],[32768,4.631521606457412e-06],[32768,4.621707153318333e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151632","date":"2026-08-08 04:10:12.305692","duration":1.0951275000006717,"mem_peak_pagefile_usage":39481344,"uptime":24630.170540094376},"values":[4.684329223625383e-06,4.679489135739345e-06,4.684567260659911e-06,4.674389648462451e-06,4.680349731445155e-06,4.663882446354073e-06],"warmups":[[32768,4.690908813498318e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152770","date":"2026-08-08 04:10:13.614057","duration":1.0794190999986313,"mem_peak_pagefile_usage":39264256,"uptime":24631.478402137756},"values":[4.625341796793414e-06,4.609677124012279e-06,4.607232665931882e-06,4.6095062254947194e-06,4.61098632809076e-06,4.600823974576507e-06],"warmups":[[32768,4.5990814208085595e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148032","date":"2026-08-08 04:10:14.938814","duration":1.0993517999995674,"mem_peak_pagefile_usage":39358464,"uptime":24632.807284355164},"values":[4.693383789056149e-06,4.690771484461287e-06,4.694509887714915e-06,4.690438842769318e-06,4.718563842764922e-06,4.713867187589038e-06],"warmups":[[32768,4.6896057128709145e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146564","date":"2026-08-08 04:10:16.271958","duration":1.106090299999778,"mem_peak_pagefile_usage":39579648,"uptime":24634.141705274582},"values":[4.741125488316733e-06,4.738116455071939e-06,4.746701049773705e-06,4.7163665771732255e-06,4.715975952085394e-06,4.709149169834781e-06],"warmups":[[32768,4.732153320308186e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146565","date":"2026-08-08 04:10:17.611728","duration":1.1139548999999533,"mem_peak_pagefile_usage":39657472,"uptime":24635.48197221756},"values":[4.768493652385075e-06,4.767758178703119e-06,4.769186401354375e-06,4.76090698242615e-06,4.748663330111924e-06,4.74082031243217e-06],"warmups":[[32768,4.771896362387729e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147271","date":"2026-08-08 04:10:18.936119","duration":1.098148900000524,"mem_peak_pagefile_usage":39333888,"uptime":24636.80530810356},"values":[4.694363403334734e-06,4.706332397463875e-06,4.68855895996434e-06,4.69182128903789e-06,4.694842529295862e-06,4.671859741289808e-06],"warmups":[[32768,4.7020111083595495e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149955","date":"2026-08-08 04:10:20.247714","duration":1.082035999999789,"mem_peak_pagefile_usage":39526400,"uptime":24638.11450123787},"values":[4.624874877845464e-06,4.636798095702943e-06,4.622451782121395e-06,4.617669677742242e-06,4.6163238525132044e-06,4.609106445285782e-06],"warmups":[[32768,4.621145629934986e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146025","date":"2026-08-08 04:10:21.568777","duration":1.0940812999979244,"mem_peak_pagefile_usage":39620608,"uptime":24639.43954730034},"values":[4.658905029319982e-06,4.664300537027266e-06,4.677877807557351e-06,4.682040405268317e-06,4.6834533691253455e-06,4.6897186278815894e-06],"warmups":[[32768,4.6585174560132e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141345","date":"2026-08-08 04:10:22.921354","duration":1.104998999999225,"mem_peak_pagefile_usage":39407616,"uptime":24640.7964823246},"values":[4.722503662013544e-06,4.720562744142676e-06,4.718539428738566e-06,4.724243164000441e-06,4.719573974631963e-06,4.721975707999704e-06],"warmups":[[32768,4.732748413172061e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138193","date":"2026-08-08 04:10:24.227259","duration":1.0813716999982717,"mem_peak_pagefile_usage":39690240,"uptime":24642.105678081512},"values":[4.622149658239927e-06,4.618695068403511e-06,4.60671997071227e-06,4.629602050720827e-06,4.626803588814177e-06,4.6117950439628075e-06],"warmups":[[32768,4.621011352456961e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143097","date":"2026-08-08 04:10:25.539901","duration":1.0844128999997338,"mem_peak_pagefile_usage":40034304,"uptime":24643.41339325905},"values":[4.629568481462343e-06,4.62304382320422e-06,4.629708862391446e-06,4.627352905295368e-06,4.639324951205559e-06,4.636224365306418e-06],"warmups":[[32768,4.640521240162343e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147840","date":"2026-08-08 04:10:26.836321","duration":1.0729930999987118,"mem_peak_pagefile_usage":39247872,"uptime":24644.70519399643},"values":[4.581893920829749e-06,4.584902954074543e-06,4.588952636663812e-06,4.594699096638344e-06,4.570019531247027e-06,4.569033813517365e-06],"warmups":[[32768,4.591845703116881e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148456","date":"2026-08-08 04:10:28.142441","duration":1.0789887000028102,"mem_peak_pagefile_usage":39583744,"uptime":24646.010635852814},"values":[4.6019287109899665e-06,4.600915527341876e-06,4.605819702074854e-06,4.609301757829698e-06,4.607431030256848e-06,4.599404907268401e-06],"warmups":[[32768,4.63760681157499e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145016","date":"2026-08-08 04:10:29.465067","duration":1.0940116999991005,"mem_peak_pagefile_usage":39555072,"uptime":24647.336310386658},"values":[4.679479980507217e-06,4.688351440407246e-06,4.690179443378462e-06,4.681500244241299e-06,4.676623535204705e-06,4.652206420874272e-06],"warmups":[[32768,4.664398193354735e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140626","date":"2026-08-08 04:10:30.770950","duration":1.0792013999998744,"mem_peak_pagefile_usage":39710720,"uptime":24648.646685361862},"values":[4.611172485291526e-06,4.6086822509394665e-06,4.6098358154056385e-06,4.6091613769005946e-06,4.616870117213345e-06,4.613702392575192e-06],"warmups":[[32768,4.611947631794067e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141908","date":"2026-08-08 04:10:32.081133","duration":1.086411299998872,"mem_peak_pagefile_usage":39665664,"uptime":24649.955504179},"values":[4.644189453117953e-06,4.643972778217709e-06,4.64320068360724e-06,4.639486694379968e-06,4.639895629821034e-06,4.643338012644271e-06],"warmups":[[32768,4.6428558350131155e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148557","date":"2026-08-08 04:10:33.412555","duration":1.1031455999982427,"mem_peak_pagefile_usage":39809024,"uptime":24651.28084421158},"values":[4.718261718772432e-06,4.726324462911435e-06,4.706011962896106e-06,4.7051025391375845e-06,4.6979370117439245e-06,4.697979736345559e-06],"warmups":[[32768,4.7428100585777955e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147348","date":"2026-08-08 04:10:34.751506","duration":1.1140787999975146,"mem_peak_pagefile_usage":40247296,"uptime":24652.620206832886},"values":[4.766366577202419e-06,4.771954345672569e-06,4.746276855427389e-06,4.774768066373447e-06,4.759851074176424e-06,4.7685485839998876e-06],"warmups":[[32768,4.765698242148453e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139354","date":"2026-08-08 04:10:36.067773","duration":1.08713920000082,"mem_peak_pagefile_usage":39571456,"uptime":24653.945120096207},"values":[4.640975952097115e-06,4.64809265132704e-06,4.650033569308931e-06,4.636865234441956e-06,4.634222412147615e-06,4.6271362303951236e-06],"warmups":[[32768,4.670449829102807e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142211","date":"2026-08-08 04:10:37.411204","duration":1.0962781999987783,"mem_peak_pagefile_usage":40226816,"uptime":24655.285514116287},"values":[4.714498901381425e-06,4.694778442337899e-06,4.695227050710571e-06,4.6645446777349164e-06,4.668783569417023e-06,4.668218994141604e-06],"warmups":[[32768,4.686862182690099e-06]]}]},{"metadata":{"loops":32,"name":"jinja2/controlled/large-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.141169","calibrate_loops":32,"date":"2026-08-08 04:10:38.546047","duration":0.8965036000008695,"mem_peak_pagefile_usage":39518208,"uptime":24656.421721935272},"warmups":[[1,0.0037698000014643185],[2,0.003472450000117533],[4,0.0034325249998801155],[8,0.0034389249999549065],[16,0.0034537750000254164],[32,0.003428953125080625],[32,0.003433884374999252],[32,0.003416134374901958],[32,0.0034189031249525215],[32,0.0034259562499983076],[32,0.0034274343749984837],[32,0.0034296000000040294]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145994","date":"2026-08-08 04:10:39.560885","duration":0.7891855999987456,"mem_peak_pagefile_usage":39354368,"uptime":24657.431607961655},"values":[0.0034279406249879685,0.003427459375075159,0.0034330343750070824,0.0034254093750405445,0.0034285937499589636,0.0034340812500204265],"warmups":[[32,0.0034023062499954904]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151706","date":"2026-08-08 04:10:40.593988","duration":0.7855133000011847,"mem_peak_pagefile_usage":39149568,"uptime":24658.459208250046},"values":[0.0033865187499486638,0.0034142343749863358,0.003418881250013328,0.0034125249999306106,0.0034204375000399523,0.003419581250000192],"warmups":[[32,0.003390053125031045]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145272","date":"2026-08-08 04:10:41.601532","duration":0.7758006999974896,"mem_peak_pagefile_usage":38858752,"uptime":24659.470175266266},"values":[0.003382434374998411,0.003374721874934039,0.0033786406249873835,0.0033757156249976106,0.003375890624965905,0.0033777874999714186],"warmups":[[32,0.0033892156250203698]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144532","date":"2026-08-08 04:10:42.626480","duration":0.7948374999978114,"mem_peak_pagefile_usage":39342080,"uptime":24660.496082782745},"values":[0.0034782312500283297,0.003465896875013641,0.0034306750000041575,0.003448396875000981,0.003456534374890907,0.003456056250001893],"warmups":[[32,0.003500528125073288]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148061","date":"2026-08-08 04:10:43.623343","duration":0.7681668999975955,"mem_peak_pagefile_usage":39669760,"uptime":24661.489866018295},"values":[0.0033403906249986903,0.0033388500000910426,0.003341903125033241,0.0033409874999961175,0.0033392874998980915,0.00334323437493822],"warmups":[[32,0.0033481843749996187]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138493","date":"2026-08-08 04:10:44.624338","duration":0.7784190000020317,"mem_peak_pagefile_usage":39481344,"uptime":24662.502856731415},"values":[0.0033707718749838023,0.0033750124999869513,0.003374943750031889,0.0033746312500397835,0.0033720374999575142,0.0033750812499420135],"warmups":[[32,0.003383865624982718]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145736","date":"2026-08-08 04:10:45.639063","duration":0.7880454000005557,"mem_peak_pagefile_usage":39739392,"uptime":24663.510461091995},"values":[0.0034179250000079264,0.0034193281250054497,0.0034189125000239073,0.003419253125002797,0.003418440625068797,0.0034221374999106047],"warmups":[[32,0.0034135125000602784]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152446","date":"2026-08-08 04:10:46.638389","duration":0.7712553999990632,"mem_peak_pagefile_usage":39264256,"uptime":24664.502764940262},"values":[0.003345615624994025,0.003343431250073081,0.0033407656250119544,0.0033427687500307,0.0033425625000518266,0.003345690624996678],"warmups":[[32,0.0033564031250534754]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144930","date":"2026-08-08 04:10:47.642978","duration":0.7768321000003198,"mem_peak_pagefile_usage":39677952,"uptime":24665.51211500168},"values":[0.0033749656249710824,0.0033777749999899243,0.0033852031250489745,0.0033850187500092943,0.0033835250000038286,0.0033787843749450985],"warmups":[[32,0.003394003124981282]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149937","date":"2026-08-08 04:10:48.654675","duration":0.7804957000007562,"mem_peak_pagefile_usage":39116800,"uptime":24666.51850128174},"values":[0.003376590624952769,0.003387087500072994,0.0034106812499885564,0.0034125156249729116,0.0034115875000679807,0.003416731250013072],"warmups":[[32,0.003389765625001928]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148272","date":"2026-08-08 04:10:49.678582","duration":0.7954050000007555,"mem_peak_pagefile_usage":39485440,"uptime":24667.545021295547},"values":[0.0034625562500423257,0.0034626812500846427,0.0034632156249472246,0.0034618906250898362,0.003463490624994847,0.003461312500007807],"warmups":[[32,0.003464065624939394]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138463","date":"2026-08-08 04:10:50.678436","duration":0.769609799997852,"mem_peak_pagefile_usage":39727104,"uptime":24668.55393052101},"values":[0.003347918750023382,0.003348656250068416,0.0033465906250285116,0.0033489593749891355,0.0033478531249784282,0.003349837500081776],"warmups":[[32,0.003366243750065223]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148130","date":"2026-08-08 04:10:51.681543","duration":0.7760942000022624,"mem_peak_pagefile_usage":39743488,"uptime":24669.549510240555},"values":[0.0033565562499688895,0.003359162500032653,0.0033636343749776643,0.003369724999970458,0.0033775062499898922,0.0033865812499698222],"warmups":[[32,0.0033778124999344072]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148689","date":"2026-08-08 04:10:52.690601","duration":0.7792007999996713,"mem_peak_pagefile_usage":39583744,"uptime":24670.5579764843},"values":[0.0033826031250328015,0.0033838812499880078,0.0033826500000486703,0.0033803093749611435,0.0033806562499876236,0.0033819406249904205],"warmups":[[32,0.0033925968749599633]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151204","date":"2026-08-08 04:10:53.688693","duration":0.7690443000028608,"mem_peak_pagefile_usage":39600128,"uptime":24671.5513818264},"values":[0.0033430499998985397,0.0033409968749538166,0.003341996874951292,0.003345234375046857,0.0033415999999988344,0.0033441812499859225],"warmups":[[32,0.0033792062500879183]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151262","date":"2026-08-08 04:10:54.683403","duration":0.7656805000005988,"mem_peak_pagefile_usage":39636992,"uptime":24672.54616189003},"values":[0.003331034374923547,0.0033315593750558037,0.003328212500036898,0.003329575000066143,0.0033275437499469263,0.0033286781249444175],"warmups":[[32,0.0033557906250507585]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151166","date":"2026-08-08 04:10:55.688877","duration":0.7792140999990806,"mem_peak_pagefile_usage":39354368,"uptime":24673.554622888565},"values":[0.003383203124940337,0.003382490624971979,0.003379375000008622,0.00337996250004835,0.003381253124985051,0.0033806374999585387],"warmups":[[32,0.003375949999963268]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140918","date":"2026-08-08 04:10:56.719629","duration":0.7868057999985467,"mem_peak_pagefile_usage":38637568,"uptime":24674.59562587738},"values":[0.003393284374965333,0.0033973406250424887,0.003425037499937389,0.003427984374980042,0.003426199999921664,0.003428953125080625],"warmups":[[32,0.0034016843750350745]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143754","date":"2026-08-08 04:10:57.733988","duration":0.7871596000004502,"mem_peak_pagefile_usage":39669760,"uptime":24675.6071228981},"values":[0.003386484375027976,0.0034181312499868,0.0034228249999159743,0.003416981249984019,0.003423937499974272,0.003421046875018874],"warmups":[[32,0.003419609374986976]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148374","date":"2026-08-08 04:10:58.734039","duration":0.7750097999996797,"mem_peak_pagefile_usage":39624704,"uptime":24676.602617025375},"values":[0.0033589249999295134,0.0033609968750170083,0.003358343749937376,0.0033611625000276035,0.003358346874961171,0.0033544562500082975],"warmups":[[32,0.0033802437500298765]]}]},{"metadata":{"loops":2048,"name":"jinja2/controlled/mixed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.145715","calibrate_loops":2048,"date":"2026-08-08 04:11:00.037860","duration":1.0631027999988873,"mem_peak_pagefile_usage":39530496,"uptime":24677.907461881638},"warmups":[[1,0.00018389999968349002],[2,0.00013084999955026433],[4,0.00012290000086068176],[8,7.061250016704435e-05],[16,6.209374987520278e-05],[32,6.210624997038394e-05],[64,6.332499998507046e-05],[128,6.397421873316489e-05],[256,6.405468749903775e-05],[512,6.31705078077971e-05],[1024,6.373378906232574e-05],[2048,6.431000976547807e-05],[2048,6.423886718742722e-05],[2048,6.362167968809729e-05],[2048,6.314228515513776e-05],[2048,6.332631835803681e-05],[2048,6.331621093735862e-05],[2048,6.322343750042592e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138399","date":"2026-08-08 04:11:01.183874","duration":0.9207166000014695,"mem_peak_pagefile_usage":39567360,"uptime":24679.06205558777},"values":[6.246035156109997e-05,6.273720703120489e-05,6.278354492117444e-05,6.277773437446399e-05,6.282387695399905e-05,6.285468749922529e-05],"warmups":[[2048,6.250825195230902e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141852","date":"2026-08-08 04:11:02.337178","duration":0.9215795999989496,"mem_peak_pagefile_usage":39673856,"uptime":24680.211296081543},"values":[6.283310546884024e-05,6.282333984408695e-05,6.269970703165484e-05,6.272094726611499e-05,6.269794921820449e-05,6.29740234359133e-05],"warmups":[[2048,6.289931640601765e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140470","date":"2026-08-08 04:11:03.470763","duration":0.9106742000003578,"mem_peak_pagefile_usage":39571456,"uptime":24681.346584558487},"values":[6.175605468783374e-05,6.175229492200174e-05,6.204101562623521e-05,6.223964843776741e-05,6.222055663940296e-05,6.220205078122376e-05],"warmups":[[2048,6.19914062500726e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151534","date":"2026-08-08 04:11:04.633596","duration":0.9179938999986916,"mem_peak_pagefile_usage":38862848,"uptime":24682.498599767685},"values":[6.198129882761805e-05,6.265722656273454e-05,6.28365722654678e-05,6.28110839855367e-05,6.282753906283745e-05,6.262343750051969e-05],"warmups":[[2048,6.198364257770095e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150898","date":"2026-08-08 04:11:05.784761","duration":0.9270620999996027,"mem_peak_pagefile_usage":39518208,"uptime":24683.650425195694},"values":[6.322534179581396e-05,6.320307617180276e-05,6.320898437373046e-05,6.321269531284202e-05,6.322021484450602e-05,6.320136718684921e-05],"warmups":[[2048,6.283334960777154e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138999","date":"2026-08-08 04:11:06.940609","duration":0.9312706000018807,"mem_peak_pagefile_usage":39493632,"uptime":24684.818455696106},"values":[6.343154296750697e-05,6.322583007722926e-05,6.325532226547637e-05,6.326171875059572e-05,6.360048828213394e-05,6.362998046860469e-05],"warmups":[[2048,6.358134765527268e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147324","date":"2026-08-08 04:11:08.084994","duration":0.9158194999981788,"mem_peak_pagefile_usage":39751680,"uptime":24685.95417547226},"values":[6.235229492190797e-05,6.238300781191697e-05,6.235947265587072e-05,6.238037109440597e-05,6.235063476545122e-05,6.235893554773497e-05],"warmups":[[2048,6.247773437628723e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151588","date":"2026-08-08 04:11:09.223743","duration":0.9144185999975889,"mem_peak_pagefile_usage":39325696,"uptime":24687.088877677917},"values":[6.259077148484948e-05,6.268720703062058e-05,6.215590820346506e-05,6.176318359329969e-05,6.180419921975044e-05,6.196972656269395e-05],"warmups":[[2048,6.282763671983105e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141743","date":"2026-08-08 04:11:10.396406","duration":0.9449906999980158,"mem_peak_pagefile_usage":39477248,"uptime":24688.271035909653},"values":[6.39482910163025e-05,6.398803710894185e-05,6.391943359318475e-05,6.414111328112426e-05,6.395122070301795e-05,6.38608398428886e-05],"warmups":[[2048,6.425590820313687e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146627","date":"2026-08-08 04:11:11.566254","duration":0.9256765000027372,"mem_peak_pagefile_usage":39940096,"uptime":24689.436129808426},"values":[6.306914062470526e-05,6.30386230469071e-05,6.304394531220225e-05,6.304077148477916e-05,6.301704101652206e-05,6.294609375068205e-05],"warmups":[[2048,6.327314453180577e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139181","date":"2026-08-08 04:11:12.709745","duration":0.9160019999981159,"mem_peak_pagefile_usage":39321600,"uptime":24690.58762359619},"values":[6.21759765611074e-05,6.21550292958517e-05,6.207182617146145e-05,6.207885742171015e-05,6.204990234515151e-05,6.194531249903434e-05],"warmups":[[2048,6.391938476468795e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153205","date":"2026-08-08 04:11:13.873098","duration":0.9141162000014447,"mem_peak_pagefile_usage":40087552,"uptime":24691.736665964127},"values":[6.21834960927714e-05,6.221928710914426e-05,6.217656249951631e-05,6.222353515639156e-05,6.226479492177361e-05,6.228583984402292e-05],"warmups":[[2048,6.233769531149846e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150979","date":"2026-08-08 04:11:15.022672","duration":0.9230519999982789,"mem_peak_pagefile_usage":39641088,"uptime":24692.888063907623},"values":[6.29546386718971e-05,6.283500976600465e-05,6.28176269543701e-05,6.281708984268164e-05,6.281728515489249e-05,6.290825195165439e-05],"warmups":[[2048,6.308632812590531e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147348","date":"2026-08-08 04:11:16.170032","duration":0.9196871999993164,"mem_peak_pagefile_usage":39612416,"uptime":24694.03870368004},"values":[6.261015625064204e-05,6.261088867098863e-05,6.262646484422874e-05,6.262690429714723e-05,6.265400390681464e-05,6.287734374943454e-05],"warmups":[[2048,6.269711914086429e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147998","date":"2026-08-08 04:11:17.309141","duration":0.9146925999993982,"mem_peak_pagefile_usage":39268352,"uptime":24695.178021669388},"values":[6.227495117272497e-05,6.222797851584971e-05,6.220708007731446e-05,6.224697265544421e-05,6.223925781334572e-05,6.219589843858842e-05],"warmups":[[2048,6.247812500070893e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145221","date":"2026-08-08 04:11:18.454164","duration":0.9166288000014902,"mem_peak_pagefile_usage":39260160,"uptime":24696.325923919678},"values":[6.237524414132167e-05,6.238691406323937e-05,6.236264648329382e-05,6.240410156266307e-05,6.238134765546022e-05,6.242275390633267e-05],"warmups":[[2048,6.239296874888112e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138914","date":"2026-08-08 04:11:19.614179","duration":0.9353436000019428,"mem_peak_pagefile_usage":39530496,"uptime":24697.492317438126},"values":[6.369155273411309e-05,6.367817382901819e-05,6.370585937354178e-05,6.371401367211149e-05,6.365312500022924e-05,6.373281249949514e-05],"warmups":[[2048,6.371372070290704e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140850","date":"2026-08-08 04:11:20.783562","duration":0.9223206999995455,"mem_peak_pagefile_usage":39137280,"uptime":24698.659341335297},"values":[6.276611328104309e-05,6.273422851599264e-05,6.274970703223914e-05,6.267685546923474e-05,6.268911132778499e-05,6.324560546921987e-05],"warmups":[[2048,6.28649902338907e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141398","date":"2026-08-08 04:11:21.934572","duration":0.9253096000029473,"mem_peak_pagefile_usage":39723008,"uptime":24699.809842586517},"values":[6.296098632851965e-05,6.29989257809882e-05,6.30120605471518e-05,6.300327148345275e-05,6.303315429789791e-05,6.29858886718182e-05],"warmups":[[2048,6.309619140587586e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153327","date":"2026-08-08 04:11:23.082492","duration":0.9189132999999856,"mem_peak_pagefile_usage":39505920,"uptime":24700.945662736893},"values":[6.349033203179033e-05,6.328281250134182e-05,6.189052734484335e-05,6.189218749952374e-05,6.207797851587316e-05,6.180375976683194e-05],"warmups":[[2048,6.362148437588644e-05]]}]},{"metadata":{"loops":512,"name":"jinja2/controlled/conditional-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.152369","calibrate_loops":512,"date":"2026-08-08 04:11:24.706718","duration":1.388587400000688,"mem_peak_pagefile_usage":40202240,"uptime":24702.57109618187},"warmups":[[1,0.0007221999985631555],[2,0.00033400000029359944],[4,0.0003283000005467329],[8,0.0003296625000075437],[16,0.000332487500145362],[32,0.0003317031249707725],[64,0.0003315765624734013],[128,0.0003318906249774045],[256,0.000331869140623553],[512,0.0003338755859374487],[512,0.0003338468750015977],[512,0.0003338603515601335],[512,0.0003338908203076585],[512,0.0003337142578132557],[512,0.0003338480468713101],[512,0.0003337298828114399]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147398","date":"2026-08-08 04:11:26.155584","duration":1.220916700000089,"mem_peak_pagefile_usage":39157760,"uptime":24704.024300336838},"values":[0.00033433593750231694,0.0003344861328073989,0.00033449785156136613,0.00033468457031204935,0.00033458789062734695,0.00033467578124657393],"warmups":[[512,0.0003354933593797682]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144380","date":"2026-08-08 04:11:27.617858","duration":1.2370480000026873,"mem_peak_pagefile_usage":39759872,"uptime":24705.490041017532},"values":[0.0003429037109441424,0.0003427931640658244,0.0003428320312508504,0.00033482539062390515,0.0003337994140650835,0.0003339556640611363],"warmups":[[512,0.0003421613281204827]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147503","date":"2026-08-08 04:11:29.070228","duration":1.2266686000002665,"mem_peak_pagefile_usage":38862848,"uptime":24706.939333200455},"values":[0.0003359232421829006,0.00033634296875106884,0.00033605292968985623,0.00033630546874974243,0.00033613691406486623,0.0003362128906232442],"warmups":[[512,0.00033632324218757503]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139439","date":"2026-08-08 04:11:30.528780","duration":1.2302757000034035,"mem_peak_pagefile_usage":38875136,"uptime":24708.40560889244},"values":[0.00033725312499655047,0.0003371847656268301,0.00033716152343288286,0.0003371533203164745,0.0003371570312538097,0.00033709609374454885],"warmups":[[512,0.0003376609374967643]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144550","date":"2026-08-08 04:11:31.985181","duration":1.2299302999999782,"mem_peak_pagefile_usage":39084032,"uptime":24709.85741519928},"values":[0.0003367130859430745,0.0003368054687555855,0.00033699218749916326,0.00033714316406019407,0.0003369609375027949,0.00033686191406445687],"warmups":[[512,0.0003373595703166643]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138889","date":"2026-08-08 04:11:33.445281","duration":1.232423999997991,"mem_peak_pagefile_usage":38670336,"uptime":24711.323252677917},"values":[0.0003382591796849965,0.0003380222656232945,0.0003376541015569501,0.0003378496093731087,0.00033696718750064747,0.00033695917968401545],"warmups":[[512,0.00033826699218764134]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146497","date":"2026-08-08 04:11:34.888095","duration":1.2152156999982253,"mem_peak_pagefile_usage":38891520,"uptime":24712.757804632187},"values":[0.00033321757812387887,0.0003330847656286551,0.0003330958984406607,0.00033300527343982367,0.0003331201171903331,0.0003332246093776803],"warmups":[[512,0.00033273222656049484]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153209","date":"2026-08-08 04:11:36.344825","duration":1.2302047999983188,"mem_peak_pagefile_usage":39698432,"uptime":24714.208052396774},"values":[0.0003377310546852641,0.00033630664062656024,0.000336313476559269,0.0003377888671849405,0.0003373287109411649,0.00033724921874522806],"warmups":[[512,0.0003379435546833065]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149380","date":"2026-08-08 04:11:37.840447","duration":1.2492908999993233,"mem_peak_pagefile_usage":38621184,"uptime":24715.70787382126},"values":[0.00034291074218373296,0.00034368144531526923,0.00034248085937349515,0.00034355390625506743,0.00034245644530983554,0.00034233476562661735],"warmups":[[512,0.0003391535156254122]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145962","date":"2026-08-08 04:11:39.303658","duration":1.2349586999989697,"mem_peak_pagefile_usage":39821312,"uptime":24717.17436861992},"values":[0.0003354066406231482,0.0003372310546865265,0.0003400136718738622,0.0003397259765662852,0.0003396726562527874,0.00034013242187569404],"warmups":[[512,0.00033658066406161424]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151960","date":"2026-08-08 04:11:40.759670","duration":1.2304573000001255,"mem_peak_pagefile_usage":39190528,"uptime":24718.62451314926},"values":[0.00033703359374470665,0.00033700996093699587,0.0003371080078125033,0.00033724570312188007,0.0003373585937538337,0.0003361775390615662],"warmups":[[512,0.0003378832031231127]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146314","date":"2026-08-08 04:11:42.220060","duration":1.2363363000004028,"mem_peak_pagefile_usage":39550976,"uptime":24720.09036064148},"values":[0.0003381396484343213,0.00033863847656334656,0.00033875058593224594,0.00033865019531020835,0.00033852539062451115,0.0003430537109352372],"warmups":[[512,0.00033637070312408923]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153242","date":"2026-08-08 04:11:43.662366","duration":1.2151551000024483,"mem_peak_pagefile_usage":39084032,"uptime":24721.525506973267},"values":[0.00033275410156363705,0.00033261992187760825,0.00033277617187366104,0.00033297050781300186,0.00033281171874932625,0.0003331302734395081],"warmups":[[512,0.0003340929687496441]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152088","date":"2026-08-08 04:11:45.110978","duration":1.2245165999993333,"mem_peak_pagefile_usage":38944768,"uptime":24722.97561979294},"values":[0.00033503769530796035,0.0003355527343771314,0.0003358171874978666,0.0003355451171884738,0.0003355062500034478,0.000335540429688308],"warmups":[[512,0.0003355291015623152]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144072","date":"2026-08-08 04:11:46.586615","duration":1.2452402999988408,"mem_peak_pagefile_usage":39522304,"uptime":24724.458877801895},"values":[0.00034000371093867443,0.0003400029296827256,0.00034018593750317905,0.00034177031250237633,0.00034386875000080863,0.00034399550781216703],"warmups":[[512,0.00034031445312621145]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151450","date":"2026-08-08 04:11:48.045297","duration":1.231392899997445,"mem_peak_pagefile_usage":39645184,"uptime":24725.910171747208},"values":[0.0003377904296897327,0.00033775722656770313,0.0003378281249979409,0.00033697636718699187,0.0003374785156253779,0.00033699277343401945],"warmups":[[512,0.0003382542968708435]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150919","date":"2026-08-08 04:11:49.512314","duration":1.2411472999992839,"mem_peak_pagefile_usage":39145472,"uptime":24727.378044605255},"values":[0.00034025058593556423,0.00034036660156289145,0.00034057792968411604,0.00034006074218950744,0.0003394537109357998,0.0003394960937512792],"warmups":[[512,0.00034076132812543847]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148997","date":"2026-08-08 04:11:50.960328","duration":1.2241620999993756,"mem_peak_pagefile_usage":39051264,"uptime":24728.82816195488},"values":[0.000335470117185821,0.0003356654296879924,0.000335799414060034,0.0003360652343715742,0.0003364318359331264,0.0003333822265645381],"warmups":[[512,0.0003350470703153974]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151336","date":"2026-08-08 04:11:52.460492","duration":1.2496554999997898,"mem_peak_pagefile_usage":38920192,"uptime":24730.32582259178},"values":[0.00034219531249846113,0.0003432113281292004,0.0003431566406248976,0.000343306445316216,0.0003434267578157346,0.0003435195312491146],"warmups":[[512,0.0003390427734402124]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146673","date":"2026-08-08 04:11:53.923512","duration":1.237105899999733,"mem_peak_pagefile_usage":39866368,"uptime":24731.79372358322},"values":[0.00033900742187142896,0.00033883593749806096,0.00033891640624972297,0.00033884999999855836,0.00033876484374673055,0.00033895449218590556],"warmups":[[512,0.0003394117187554002]]}]},{"metadata":{"loops":256,"name":"jinja2/controlled/fragment-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.142808","calibrate_loops":256,"date":"2026-08-08 04:11:55.197989","duration":1.0361960000009276,"mem_peak_pagefile_usage":38957056,"uptime":24733.07154893875},"warmups":[[1,0.0007106000011845026],[2,0.000525999999808846],[4,0.0004971750004187925],[8,0.0004972749998159998],[16,0.000496475000090868],[32,0.0004966374999639811],[64,0.0004970578124812164],[128,0.0004967015624970372],[256,0.0004963917968723308],[256,0.0004960347656322028],[256,0.0004960964843832016],[256,0.0004959417968848356],[256,0.0004948832031175243],[256,0.0004946210937504247],[256,0.0004945324218823544]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150801","date":"2026-08-08 04:11:56.339955","duration":0.9151942999997118,"mem_peak_pagefile_usage":39247872,"uptime":24734.20570731163},"values":[0.0004986578124999141,0.0004982531250021793,0.0004982988281199141,0.0004982863281242089,0.0004988250000081962,0.0004997394531329746],"warmups":[[256,0.000499243749999323]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153425","date":"2026-08-08 04:11:57.477466","duration":0.9118113000004087,"mem_peak_pagefile_usage":39587840,"uptime":24735.34098982811},"values":[0.0004970265625132697,0.0004964226562407248,0.0004961367187519272,0.0004954296874899455,0.0004954207031175883,0.0004959648437505848],"warmups":[[256,0.0004989515625055674]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145840","date":"2026-08-08 04:11:58.637113","duration":0.9131492999986222,"mem_peak_pagefile_usage":39092224,"uptime":24736.50785589218},"values":[0.0004965539062453672,0.0004964941406200296,0.0004970433593740609,0.0004973285156353313,0.0004976703125123549,0.0004986777343702897],"warmups":[[256,0.0004988464843762586]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148085","date":"2026-08-08 04:11:59.779724","duration":0.9152552000014111,"mem_peak_pagefile_usage":39243776,"uptime":24737.648519277573},"values":[0.0004989355468723033,0.0004983437500101218,0.0004982902343755313,0.0004983003906176009,0.0004986296874989193,0.0004991992187513006],"warmups":[[256,0.0004980906250011685]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145961","date":"2026-08-08 04:12:00.925038","duration":0.9179609999991953,"mem_peak_pagefile_usage":39645184,"uptime":24738.79574751854},"values":[0.0005002050781257594,0.0005000531249947926,0.000499651171864457,0.0004995136718690674,0.0004996085937563066,0.0005002960937474654],"warmups":[[256,0.0005013624999889998]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146981","date":"2026-08-08 04:12:02.062974","duration":0.9133505999998306,"mem_peak_pagefile_usage":39772160,"uptime":24739.931975841522},"values":[0.0004979546875034657,0.0004977281249978205,0.0004979867187415721,0.0004975113281346921,0.0004977191406254633,0.0004976863281171973],"warmups":[[256,0.000498840624999275]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150934","date":"2026-08-08 04:12:03.202233","duration":0.9131534000007377,"mem_peak_pagefile_usage":39190528,"uptime":24741.067945718765},"values":[0.0004979593749965261,0.000497203515621436,0.0004973070312388472,0.0004971796874997381,0.0004963527343733176,0.0004975636718853593],"warmups":[[256,0.0004985472656215961]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140098","date":"2026-08-08 04:12:04.343933","duration":0.9148591999983182,"mem_peak_pagefile_usage":39698432,"uptime":24742.219798326492},"values":[0.0004985683593758949,0.0004986679687561946,0.0004989050781176729,0.0004985578124916401,0.0004983503906288433,0.0004988210937426629],"warmups":[[256,0.0004997121093737178]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143150","date":"2026-08-08 04:12:05.482061","duration":0.9119903999999224,"mem_peak_pagefile_usage":39391232,"uptime":24743.354995250702},"values":[0.0004967281250003452,0.0004969070312483836,0.0004966316406296301,0.0004967457031312961,0.000496713671864768,0.0004988914062522554],"warmups":[[256,0.0004972972656247521]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144702","date":"2026-08-08 04:12:06.619805","duration":0.9134295000003476,"mem_peak_pagefile_usage":39018496,"uptime":24744.491540670395},"values":[0.0004980074218678965,0.0004972800781217757,0.0004977261718721593,0.0004976511718695065,0.0004975804687461505,0.0004984062500028585],"warmups":[[256,0.0004975054687577085]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144319","date":"2026-08-08 04:12:07.756587","duration":0.9114108000030683,"mem_peak_pagefile_usage":39923712,"uptime":24745.62881422043},"values":[0.00049637421874138,0.0004965820312605729,0.00049664648436476,0.0004961277343653592,0.0004957625000088228,0.0004968140625010165],"warmups":[[256,0.0004977980468652277]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147509","date":"2026-08-08 04:12:08.896363","duration":0.9125005999994755,"mem_peak_pagefile_usage":39649280,"uptime":24746.764703273773},"values":[0.0004972949218711165,0.0004978734375100657,0.0004966941406223668,0.0004972597656234257,0.0004972937500014041,0.0004983367187492149],"warmups":[[256,0.0004985003906199381]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139230","date":"2026-08-08 04:12:10.054342","duration":0.9152839000016684,"mem_peak_pagefile_usage":38678528,"uptime":24747.932168722153},"values":[0.0004984929687452677,0.000499021093759211,0.0004985023437598102,0.0004984355468735657,0.0004980199218636017,0.0004975374999958149],"warmups":[[256,0.0004985875000045326]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142576","date":"2026-08-08 04:12:11.225496","duration":0.9241323999995075,"mem_peak_pagefile_usage":39329792,"uptime":24749.09980726242},"values":[0.0005018144531305779,0.0005020519531342416,0.000501280468739651,0.0005007464843771459,0.0005007953125044651,0.000501632421887166],"warmups":[[256,0.0005019570312470023]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138181","date":"2026-08-08 04:12:12.387252","duration":0.9161438000010094,"mem_peak_pagefile_usage":39227392,"uptime":24750.266308784485},"values":[0.0004985660156222593,0.0004993066406200342,0.0004992007812489874,0.0004980644531258349,0.0004986777343702897,0.0004983273437488833],"warmups":[[256,0.0004998050781352958]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143022","date":"2026-08-08 04:12:13.527622","duration":0.9153478999978688,"mem_peak_pagefile_usage":39448576,"uptime":24751.401438951492},"values":[0.0004989367187562266,0.0004987695312479445,0.0004985402343749001,0.0004981960937442409,0.0004980148437425669,0.0004988332031246046],"warmups":[[256,0.0004988343750085278]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147270","date":"2026-08-08 04:12:14.666676","duration":0.9138668999985384,"mem_peak_pagefile_usage":39444480,"uptime":24752.535425901413},"values":[0.0004979792968669017,0.0004979343750051157,0.0004982289062525069,0.0004984042968771973,0.0004977781250090629,0.0004973917968698061],"warmups":[[256,0.0004999875000066822]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141436","date":"2026-08-08 04:12:15.810200","duration":0.9172531000003801,"mem_peak_pagefile_usage":39464960,"uptime":24753.6842918396},"values":[0.0005005613281241494,0.0004994843749983602,0.0004999851562530466,0.0005001847656274094,0.0005004785156330627,0.0005022562500016647],"warmups":[[256,0.0004996578124973894]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150225","date":"2026-08-08 04:12:16.954437","duration":0.9210639999982959,"mem_peak_pagefile_usage":39473152,"uptime":24754.82135438919},"values":[0.0005008273437567823,0.0005005214843691874,0.000500651953117881,0.0005013796875061871,0.000501985156262208,0.0005027253906320084],"warmups":[[256,0.0005029062499914971]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140443","date":"2026-08-08 04:12:18.097134","duration":0.9158989999996265,"mem_peak_pagefile_usage":38797312,"uptime":24755.97293496132},"values":[0.0004987789062482761,0.0004992558593670537,0.0004988812499959749,0.0004995144531250162,0.0004990374999920277,0.0004996906249914446],"warmups":[[256,0.000499666406255983]]}]},{"metadata":{"loops":8192,"name":"jinja2/controlled/fortunes-encoded"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.147975","calibrate_loops":8192,"date":"2026-08-08 04:12:19.639076","duration":1.3014161999999487,"mem_peak_pagefile_usage":39469056,"uptime":24757.507927179337},"warmups":[[1,9.180000051856041e-05],[2,4.5200000386103056e-05],[4,3.8950000089243986e-05],[8,2.1637499685311923e-05],[16,1.908125000227301e-05],[32,1.944062501024746e-05],[64,1.9401562497023406e-05],[128,1.9489843737119372e-05],[256,1.9566796879644244e-05],[512,1.9710351566004647e-05],[1024,1.9676171874039028e-05],[2048,1.9543017577561272e-05],[4096,1.9543603515970176e-05],[8192,1.9538256835982537e-05],[8192,1.95404296876589e-05],[8192,1.9466027831871457e-05],[8192,1.944165039091672e-05],[8192,1.9451489257971133e-05],[8192,1.950313720699981e-05],[8192,1.964411621102613e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140620","date":"2026-08-08 04:12:21.013932","duration":1.1446055000014894,"mem_peak_pagefile_usage":39718912,"uptime":24758.890293359756},"values":[1.9601843261884966e-05,1.959194335920955e-05,1.9609655761421152e-05,1.958911132815544e-05,1.9597875976273826e-05,1.941694335938493e-05],"warmups":[[8192,1.960288085944839e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148996","date":"2026-08-08 04:12:22.377212","duration":1.1366796999973303,"mem_peak_pagefile_usage":39604224,"uptime":24760.245237588882},"values":[1.9477612304807934e-05,1.9457385254106896e-05,1.9426660156085518e-05,1.942325439463488e-05,1.9389514160028654e-05,1.9389257812640892e-05],"warmups":[[8192,1.949077148433176e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138211","date":"2026-08-08 04:12:23.771433","duration":1.1460284000022511,"mem_peak_pagefile_usage":38854656,"uptime":24761.650015592575},"values":[1.9562829589592212e-05,1.959794921857494e-05,1.959912109361639e-05,1.9607897948858977e-05,1.9591149902353777e-05,1.9604370117498604e-05],"warmups":[[8192,1.9669604492289494e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149518","date":"2026-08-08 04:12:25.138927","duration":1.1397867999985465,"mem_peak_pagefile_usage":39407616,"uptime":24763.005879878998},"values":[1.9512402343657698e-05,1.9501794433551822e-05,1.9482312012097935e-05,1.9466748046870208e-05,1.9486657715006572e-05,1.950874023437521e-05],"warmups":[[8192,1.9538403320140674e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138400","date":"2026-08-08 04:12:26.529866","duration":1.1653468000004068,"mem_peak_pagefile_usage":39358464,"uptime":24764.407992839813},"values":[2.0049145507794464e-05,2.002601318329411e-05,1.9915405273351894e-05,1.987871093733773e-05,1.9872619628547028e-05,1.987989501950338e-05],"warmups":[[8192,2.000341796870586e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145974","date":"2026-08-08 04:12:27.909732","duration":1.1532273999982863,"mem_peak_pagefile_usage":39866368,"uptime":24765.780468702316},"values":[1.9652124023217254e-05,1.976855468743821e-05,1.9778417968741024e-05,1.977811279285646e-05,1.9749267578195173e-05,1.9701818847916996e-05],"warmups":[[8192,1.967531738289452e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149563","date":"2026-08-08 04:12:29.286083","duration":1.1511312000002363,"mem_peak_pagefile_usage":39354368,"uptime":24767.153029441833},"values":[1.9739282226538535e-05,1.9671496582329695e-05,1.9648120117121692e-05,1.967928466806157e-05,1.9673071288917043e-05,1.9651892090077894e-05],"warmups":[[8192,1.9814270019402613e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146374","date":"2026-08-08 04:12:30.653894","duration":1.1411037999969267,"mem_peak_pagefile_usage":39514112,"uptime":24768.524200201035},"values":[1.9484167480321446e-05,1.9526770019151485e-05,1.9572656250410603e-05,1.9571362304571238e-05,1.9546826171890075e-05,1.9515319824581212e-05],"warmups":[[8192,1.9429846191076905e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149808","date":"2026-08-08 04:12:32.031362","duration":1.1498991000007663,"mem_peak_pagefile_usage":39059456,"uptime":24769.898018836975},"values":[1.9725256347413733e-05,1.9573364257841064e-05,1.977387695317745e-05,1.9707299804938572e-05,1.959262695327979e-05,1.958029785154025e-05],"warmups":[[8192,1.9782128906076224e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147808","date":"2026-08-08 04:12:33.404170","duration":1.1473383999982616,"mem_peak_pagefile_usage":39067648,"uptime":24771.272980213165},"values":[1.9642395019392467e-05,1.9662194824299206e-05,1.9601171874938927e-05,1.9605224609087202e-05,1.9638574218383553e-05,1.9634411621005654e-05],"warmups":[[8192,1.9612512207167754e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148468","date":"2026-08-08 04:12:34.779786","duration":1.1498981000004278,"mem_peak_pagefile_usage":39624704,"uptime":24772.648302555084},"values":[1.9627148437617592e-05,1.9658398437538693e-05,1.9662609863413394e-05,1.968204345681457e-05,1.9682849121238633e-05,1.9690661621218908e-05],"warmups":[[8192,1.9662658691466106e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143921","date":"2026-08-08 04:12:36.158229","duration":1.1510540999988734,"mem_peak_pagefile_usage":39653376,"uptime":24774.03099489212},"values":[1.9692260742054657e-05,1.9705761718835646e-05,1.969445800797942e-05,1.9700549316326033e-05,1.9673828125288395e-05,1.964174804713892e-05],"warmups":[[8192,1.9749011230807412e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139272","date":"2026-08-08 04:12:37.542155","duration":1.160099699998682,"mem_peak_pagefile_usage":39747584,"uptime":24775.419724702835},"values":[1.9853405761605103e-05,1.980087890629534e-05,1.9864343261399853e-05,1.985432128925879e-05,1.9831982422058303e-05,1.987897949229378e-05],"warmups":[[8192,1.9833386230683203e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152919","date":"2026-08-08 04:12:38.912694","duration":1.1404235999980301,"mem_peak_pagefile_usage":39645184,"uptime":24776.776207447052},"values":[1.9485021972798222e-05,1.9473217773402496e-05,1.949775390608366e-05,1.9518371581650484e-05,1.9502404785320948e-05,1.95296752929508e-05],"warmups":[[8192,1.9581030273219113e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143730","date":"2026-08-08 04:12:40.276040","duration":1.1362259999987145,"mem_peak_pagefile_usage":39571456,"uptime":24778.148528814316},"values":[1.9422119140521943e-05,1.941994628928967e-05,1.941763916013528e-05,1.943322753916732e-05,1.9445898437719933e-05,1.9446179199356095e-05],"warmups":[[8192,1.9513769531354086e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139076","date":"2026-08-08 04:12:41.657026","duration":1.134191799999826,"mem_peak_pagefile_usage":38625280,"uptime":24779.53486275673},"values":[1.939317626975523e-05,1.9486511230404346e-05,1.9377624511651703e-05,1.9362353515628428e-05,1.9345739746157165e-05,1.9346166992395553e-05],"warmups":[[8192,1.9438232421897794e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146301","date":"2026-08-08 04:12:43.020737","duration":1.1361796999990474,"mem_peak_pagefile_usage":39559168,"uptime":24780.891073942184},"values":[1.9394836425767892e-05,1.9377221679661716e-05,1.9398413086069155e-05,1.943651123070822e-05,1.9444775390731195e-05,1.9526623534993348e-05],"warmups":[[8192,1.9448767089702557e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146905","date":"2026-08-08 04:12:44.377581","duration":1.1300830000000133,"mem_peak_pagefile_usage":39329792,"uptime":24782.247302770615},"values":[1.9330114746196614e-05,1.9348315429823515e-05,1.9318798828216188e-05,1.932276611293915e-05,1.9322863769488663e-05,1.9333581542824163e-05],"warmups":[[8192,1.9328002929697163e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153523","date":"2026-08-08 04:12:45.757730","duration":1.152944600002229,"mem_peak_pagefile_usage":39608320,"uptime":24783.62093114853},"values":[1.9699755859470258e-05,1.969254150369082e-05,1.9712231445367934e-05,1.9748876953329386e-05,1.9741149902330335e-05,1.972404785144377e-05],"warmups":[[8192,1.9744628906526174e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153000","date":"2026-08-08 04:12:47.131896","duration":1.147672600000078,"mem_peak_pagefile_usage":40083456,"uptime":24784.99541783333},"values":[1.9630078125221218e-05,1.9612097168053566e-05,1.9602685546793452e-05,1.9612707519822692e-05,1.9634606933660592e-05,1.967419433590578e-05],"warmups":[[8192,1.969768066434341e-05]]}]},{"metadata":{"loops":16,"name":"jinja2/controlled/encoded-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.144910","calibrate_loops":16,"date":"2026-08-08 04:12:48.701368","duration":1.3337236999977904,"mem_peak_pagefile_usage":39288832,"uptime":24786.573797941208},"warmups":[[1,0.011413599997467827],[2,0.010114900000189664],[4,0.010118975000295904],[8,0.010623962499721529],[16,0.010116943750063001],[16,0.010356924999996409],[16,0.010350918749963967],[16,0.010355124999932741],[16,0.010391350000190869],[16,0.010395318749942817],[16,0.010150093750098677]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138058","date":"2026-08-08 04:12:50.115848","duration":1.1842683000031684,"mem_peak_pagefile_usage":39903232,"uptime":24787.99481868744},"values":[0.010146050000003015,0.010373118750067079,0.010416218750151529,0.010434406249942185,0.010434237499794108,0.010434362499836425],"warmups":[[16,0.010393868750043112]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149928","date":"2026-08-08 04:12:51.529908","duration":1.1873378999989654,"mem_peak_pagefile_usage":39477248,"uptime":24789.396955490112},"values":[0.010178974999917045,0.010422062500083484,0.010419606250025026,0.010455343749981694,0.010427968749809224,0.01044166874999064],"warmups":[[16,0.0104692562499622]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143090","date":"2026-08-08 04:12:52.941805","duration":1.1849675000012212,"mem_peak_pagefile_usage":39677952,"uptime":24790.815747737885},"values":[0.010149093749987514,0.010386299999936455,0.010398181249911431,0.010410574999923483,0.010442499999953725,0.010408250000182306],"warmups":[[16,0.010465650000014648]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152978","date":"2026-08-08 04:12:54.355798","duration":1.185937999998714,"mem_peak_pagefile_usage":39534592,"uptime":24792.21917128563},"values":[0.01021691875007491,0.010461250000162181,0.01039381874988976,0.010389593750005588,0.010435737500074538,0.010419700000056764],"warmups":[[16,0.010447587500038935]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148947","date":"2026-08-08 04:12:55.769378","duration":1.187676099998498,"mem_peak_pagefile_usage":39084032,"uptime":24793.637365579605},"values":[0.010243437500093933,0.010360149999996793,0.01040499374994397,0.010411268749976443,0.010452062500007742,0.010456374999876061],"warmups":[[16,0.010509962500009351]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146420","date":"2026-08-08 04:12:57.186295","duration":1.1904935999991721,"mem_peak_pagefile_usage":39464960,"uptime":24795.05675792694},"values":[0.010147399999823392,0.01046831250005198,0.010532287499927406,0.010494137500018041,0.010456337499817892,0.010478856250074386],"warmups":[[16,0.010444962500059773]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142976","date":"2026-08-08 04:12:58.601500","duration":1.188949400002457,"mem_peak_pagefile_usage":39071744,"uptime":24796.47541451454},"values":[0.01013939999984359,0.010434318749958038,0.010440531249969354,0.010470806249941234,0.010471631250084101,0.010471281249920139],"warmups":[[16,0.010489925000001676]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141485","date":"2026-08-08 04:13:00.019565","duration":1.1920095999994373,"mem_peak_pagefile_usage":40189952,"uptime":24797.894648075104},"values":[0.01023107500009246,0.010419468750114902,0.010447612500001924,0.01051503749999938,0.010513418749951597,0.010496168750023571],"warmups":[[16,0.010508018749987968]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148635","date":"2026-08-08 04:13:01.430633","duration":1.1855181999999331,"mem_peak_pagefile_usage":39510016,"uptime":24799.298999786377},"values":[0.01011853124987283,0.010378168750094119,0.010426649999999427,0.010433956249926268,0.010477749999836306,0.010456906250055908],"warmups":[[16,0.01041673124996123]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145335","date":"2026-08-08 04:13:02.845717","duration":1.186602400000993,"mem_peak_pagefile_usage":39399424,"uptime":24800.71729183197},"values":[0.010232068750156031,0.010376199999882374,0.010389393750074305,0.010385568750052698,0.010434312499910448,0.010448518750081348],"warmups":[[16,0.010508900000104404]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140554","date":"2026-08-08 04:13:04.260712","duration":1.188293800001702,"mem_peak_pagefile_usage":39616512,"uptime":24802.136834859848},"values":[0.010113537500046732,0.01037508125000386,0.010463668749935096,0.010487712499980262,0.010523156250201282,0.010496625000087079],"warmups":[[16,0.010434649999979229]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147179","date":"2026-08-08 04:13:05.702150","duration":1.192803300000378,"mem_peak_pagefile_usage":39092224,"uptime":24803.571608781815},"values":[0.010282681249918824,0.010416924999844923,0.01047470625007918,0.010456537499976548,0.010399762499901044,0.010526893750011368],"warmups":[[16,0.01062441875001241]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140767","date":"2026-08-08 04:13:07.130935","duration":1.2000506999975187,"mem_peak_pagefile_usage":39477248,"uptime":24805.006836891174},"values":[0.010292349999872386,0.010521737500084782,0.010524656250026965,0.010556568749962025,0.010578668749985809,0.010520287499957703],"warmups":[[16,0.010625193750001927]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153466","date":"2026-08-08 04:13:08.547983","duration":1.191873100000521,"mem_peak_pagefile_usage":39686144,"uptime":24806.411459445953},"values":[0.010150124999881882,0.010483612500138406,0.010495493750113383,0.010477331250058342,0.010452843750044849,0.010494093750139655],"warmups":[[16,0.010540718750007727]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141915","date":"2026-08-08 04:13:09.955173","duration":1.182541800000763,"mem_peak_pagefile_usage":38993920,"uptime":24807.830196380615},"values":[0.010097268750087096,0.01035616874992229,0.01037536874991929,0.01038486250013193,0.01041015625014552,0.010365193749976243],"warmups":[[16,0.010529787499990562]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150996","date":"2026-08-08 04:13:11.383484","duration":1.1837930000001506,"mem_peak_pagefile_usage":39153664,"uptime":24809.24982357025},"values":[0.010037606249852615,0.010343350000084683,0.010360225000113132,0.010361131249965183,0.010328524999977162,0.010361768750044575],"warmups":[[16,0.010358500000165805]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150012","date":"2026-08-08 04:13:12.787239","duration":1.1800600000024133,"mem_peak_pagefile_usage":39604224,"uptime":24810.654203414917},"values":[0.010137800000165953,0.010357643750012357,0.0103831562501,0.010351087500112044,0.01035986874990158,0.01035823749998599],"warmups":[[16,0.010413331249992552]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138895","date":"2026-08-08 04:13:14.196250","duration":1.1841639000012947,"mem_peak_pagefile_usage":39497728,"uptime":24812.07439684868},"values":[0.010133124999811116,0.010403918749943841,0.010429556250073801,0.010435831250106276,0.010395862500217845,0.010392749999937223],"warmups":[[16,0.010416993749913672]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149133","date":"2026-08-08 04:13:15.611050","duration":1.1852677000024414,"mem_peak_pagefile_usage":39510016,"uptime":24813.478291511536},"values":[0.0101702000001751,0.010418368749924412,0.010432175000005373,0.010415393750008661,0.010409087499965608,0.010429962499983958],"warmups":[[16,0.010449712499848829]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142446","date":"2026-08-08 04:13:17.023618","duration":1.1832712000032188,"mem_peak_pagefile_usage":39231488,"uptime":24814.89807009697},"values":[0.010170543750064098,0.01037834374983504,0.010375893750051546,0.010389037500090126,0.010397312499890177,0.010376893750162708],"warmups":[[16,0.01047840625005847]]}]}],"metadata":{"cpu_affinity":"4","cpu_count":32,"hostname":"DESKTOP-F5QFSMS","perf_version":"2.10.0","platform":"Windows-11-10.0.26200-SP0","python_compiler":"MSC v.1944 64 bit (AMD64)","python_executable":"E:\\Work\\Heddle\\benchmarks\\python\\.venv\\Scripts\\python.exe","python_implementation":"cpython","python_version":"3.14.7 (64-bit) revision 823f032","timer":"QueryPerformanceCounter(), resolution: 100 ns","unit":"second"},"version":"1.0"} diff --git a/docs/benchmarks/2026-08-08/python/bench_jinja2_idiomatic.json b/docs/benchmarks/2026-08-08/python/bench_jinja2_idiomatic.json new file mode 100644 index 00000000..328b5686 --- /dev/null +++ b/docs/benchmarks/2026-08-08/python/bench_jinja2_idiomatic.json @@ -0,0 +1 @@ +{"benchmarks":[{"metadata":{"loops":8192,"name":"jinja2/idiomatic/composed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.146035","calibrate_loops":8192,"date":"2026-08-08 04:13:18.809487","duration":1.285956100000476,"mem_peak_pagefile_usage":36331520,"uptime":24816.67976951599},"warmups":[[1,0.00017920000027515925],[2,5.765000059909653e-05],[4,3.999999989900971e-05],[8,3.638750013124081e-05],[16,2.0831249912589556e-05],[32,2.0100000028833165e-05],[64,1.936718751949229e-05],[128,1.9287500009568248e-05],[256,1.9378906245037797e-05],[512,1.9432617186510015e-05],[1024,1.934999999875231e-05],[2048,1.9246289062024857e-05],[4096,1.9364575195801592e-05],[8192,1.9319665527373076e-05],[8192,1.9360974121251928e-05],[8192,1.9299133300787474e-05],[8192,1.9251672363385097e-05],[8192,1.9235473633028022e-05],[8192,1.9233630371040533e-05],[8192,1.9227783202957482e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149684","date":"2026-08-08 04:13:20.168745","duration":1.126774899999873,"mem_peak_pagefile_usage":36114432,"uptime":24818.035878419876},"values":[1.9198925781171994e-05,1.9265429687553848e-05,1.93263061523119e-05,1.93117919917718e-05,1.9255395507844497e-05,1.9286047363120673e-05],"warmups":[[8192,1.9228747558663883e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140226","date":"2026-08-08 04:13:21.531056","duration":1.1310057999980927,"mem_peak_pagefile_usage":36728832,"uptime":24819.40725493431},"values":[1.9418981933583268e-05,1.9391345214891942e-05,1.9316687011716738e-05,1.931414794942299e-05,1.9273107910500187e-05,1.9235278320373084e-05],"warmups":[[8192,1.9456225586189646e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140295","date":"2026-08-08 04:13:22.933656","duration":1.1467095000007248,"mem_peak_pagefile_usage":35901440,"uptime":24820.80940580368},"values":[1.9668859863042343e-05,1.9585070801131366e-05,1.9570886230724227e-05,1.9584399414185327e-05,1.958420410153039e-05,1.9623999023110628e-05],"warmups":[[8192,1.976782226575935e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142494","date":"2026-08-08 04:13:24.259759","duration":1.0983712999986892,"mem_peak_pagefile_usage":36376576,"uptime":24822.13341164589},"values":[1.9439233398532707e-05,1.8789575195299335e-05,1.8396667480491402e-05,1.840339355485554e-05,1.847398681631418e-05,1.8516748046870646e-05],"warmups":[[8192,1.945863037144946e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144144","date":"2026-08-08 04:13:25.601907","duration":1.110691099998803,"mem_peak_pagefile_usage":36065280,"uptime":24823.47464299202},"values":[1.8970617675417856e-05,1.891391601560599e-05,1.8921704101781955e-05,1.8975354004080458e-05,1.9001342773439234e-05,1.9032348633096774e-05],"warmups":[[8192,1.906485595704055e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148302","date":"2026-08-08 04:13:26.962387","duration":1.1317312999999558,"mem_peak_pagefile_usage":35840000,"uptime":24824.830704450607},"values":[1.936031494143009e-05,1.93099365231042e-05,1.935446777334704e-05,1.9363256836157916e-05,1.937729492196283e-05,1.9343115234438102e-05],"warmups":[[8192,1.9392993164224492e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143545","date":"2026-08-08 04:13:28.345130","duration":1.1523143000013079,"mem_peak_pagefile_usage":36372480,"uptime":24826.21848154068},"values":[1.9720703125170047e-05,1.9698962402614484e-05,1.9665124511902832e-05,1.9673303222944583e-05,1.9718359374643057e-05,1.9726867675817772e-05],"warmups":[[8192,1.9751599121153873e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144966","date":"2026-08-08 04:13:29.720431","duration":1.1467819999998028,"mem_peak_pagefile_usage":35950592,"uptime":24827.59221625328},"values":[1.9574804687394476e-05,1.9641662597713605e-05,1.963103027335933e-05,1.9634851074368243e-05,1.9596191406456853e-05,1.947496337884047e-05],"warmups":[[8192,1.9734191894382747e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150879","date":"2026-08-08 04:13:31.081591","duration":1.132702100003371,"mem_peak_pagefile_usage":36864000,"uptime":24828.947291612625},"values":[1.92927368165563e-05,1.9409094238476143e-05,1.9298461914285525e-05,1.9453601074026494e-05,1.935170898459404e-05,1.9535815429350123e-05],"warmups":[[8192,1.9282568359368923e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143030","date":"2026-08-08 04:13:32.430378","duration":1.1166317999995954,"mem_peak_pagefile_usage":37523456,"uptime":24830.304261684418},"values":[1.906905517534696e-05,1.910329589849269e-05,1.90935302732953e-05,1.9130737304529077e-05,1.9097814941471114e-05,1.907320556604475e-05],"warmups":[[8192,1.906859130818006e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138942","date":"2026-08-08 04:13:33.782801","duration":1.1223460999972303,"mem_peak_pagefile_usage":36532224,"uptime":24831.660439252853},"values":[1.9330639648096337e-05,1.93346679684403e-05,1.9393457031391392e-05,1.9303369140910576e-05,1.9237609863331784e-05,1.8445031738423268e-05],"warmups":[[8192,1.9305615234443962e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151557","date":"2026-08-08 04:13:35.152620","duration":1.1156864000004134,"mem_peak_pagefile_usage":36593664,"uptime":24833.016954898834},"values":[1.9074597167989538e-05,1.9051269531278336e-05,1.9057751464934825e-05,1.9065966796905087e-05,1.90538940429974e-05,1.9148217773157228e-05],"warmups":[[8192,1.9169177245981217e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152939","date":"2026-08-08 04:13:36.508090","duration":1.1253467999995337,"mem_peak_pagefile_usage":35921920,"uptime":24834.37158846855},"values":[1.9274157715187812e-05,1.9263281249681796e-05,1.9239477539123584e-05,1.926475830060781e-05,1.9189367675753743e-05,1.9248779296709984e-05],"warmups":[[8192,1.927645263677391e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148679","date":"2026-08-08 04:13:37.860614","duration":1.123538499999995,"mem_peak_pagefile_usage":36548608,"uptime":24835.728646039963},"values":[1.9171533203188318e-05,1.9212744140517657e-05,1.9183056640947882e-05,1.916274414082153e-05,1.9197839355555857e-05,1.922844238277932e-05],"warmups":[[8192,1.9314721679819513e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138177","date":"2026-08-08 04:13:39.237707","duration":1.1485949000016262,"mem_peak_pagefile_usage":36691968,"uptime":24837.115654706955},"values":[1.9650244140745343e-05,1.9633789062556417e-05,1.959216308611289e-05,1.9618884277594617e-05,1.9634167480742093e-05,1.9692639160240333e-05],"warmups":[[8192,1.977252197260526e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146947","date":"2026-08-08 04:13:40.617288","duration":1.1507938000031572,"mem_peak_pagefile_usage":36032512,"uptime":24838.485931158066},"values":[1.97787963869267e-05,1.9745324706832434e-05,1.9754724120968348e-05,1.9643762207088855e-05,1.95730834962049e-05,1.960377197240959e-05],"warmups":[[8192,1.9849487304490765e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143244","date":"2026-08-08 04:13:41.968800","duration":1.1219368999991275,"mem_peak_pagefile_usage":37060608,"uptime":24839.841849565506},"values":[1.920253906240177e-05,1.9160217285207892e-05,1.914569091798768e-05,1.9139282226632304e-05,1.915244140615613e-05,1.9210791015744633e-05],"warmups":[[8192,1.9348071289115865e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142301","date":"2026-08-08 04:13:43.324336","duration":1.1256051999989722,"mem_peak_pagefile_usage":36532224,"uptime":24841.198645830154},"values":[1.9283544921755436e-05,1.9218212890415032e-05,1.9222912597705033e-05,1.921884765598847e-05,1.9227673339727858e-05,1.921889648448527e-05],"warmups":[[8192,1.931558837853231e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144127","date":"2026-08-08 04:13:44.667691","duration":1.1143584999990708,"mem_peak_pagefile_usage":37265408,"uptime":24842.539944171906},"values":[1.9744458008119636e-05,1.892598876951368e-05,1.8729919433191355e-05,1.874542236324217e-05,1.875800781281356e-05,1.8721105957020256e-05],"warmups":[[8192,1.9782812500146463e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151007","date":"2026-08-08 04:13:46.032256","duration":1.134265199998481,"mem_peak_pagefile_usage":36651008,"uptime":24843.89711213112},"values":[1.9488806151990445e-05,1.943205566412587e-05,1.941573486341497e-05,1.9408740234538868e-05,1.9400512695444405e-05,1.933674316401124e-05],"warmups":[[8192,1.9397656250141893e-05]]}]},{"metadata":{"loops":32768,"name":"jinja2/idiomatic/trivial-substitution"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.151899","calibrate_loops":32768,"date":"2026-08-08 04:13:47.531666","duration":1.2642443999975512,"mem_peak_pagefile_usage":36671488,"uptime":24845.39632987976},"warmups":[[1,4.7199999244185165e-05],[2,1.5400000847876072e-05],[4,1.0100000508828089e-05],[8,9.399999726156238e-06],[16,9.587499789631693e-06],[32,4.599999897436646e-06],[64,4.870312466209725e-06],[128,4.566406261119482e-06],[256,4.624218760795884e-06],[512,4.692773437398046e-06],[1024,4.71015625080895e-06],[2048,4.734082031276898e-06],[4096,4.7498535149514964e-06],[8192,4.72712402332931e-06],[16384,4.746539306710318e-06],[32768,4.723767089820363e-06],[32768,4.734020996099986e-06],[32768,4.738839721629695e-06],[32768,4.738806152371211e-06],[32768,4.743096923776058e-06],[32768,4.750387573304593e-06],[32768,4.744784545929193e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140020","date":"2026-08-08 04:13:48.875951","duration":1.113127999997232,"mem_peak_pagefile_usage":36634624,"uptime":24846.75209093094},"values":[4.764163208048622e-06,4.757516479436674e-06,4.760620117227887e-06,4.751370239253205e-06,4.761071777381609e-06,4.758001709070925e-06],"warmups":[[32768,4.761492919946875e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141699","date":"2026-08-08 04:13:50.216045","duration":1.1093729000021995,"mem_peak_pagefile_usage":36462592,"uptime":24848.090799808502},"values":[4.762243652312037e-06,4.751983642581337e-06,4.72480468749481e-06,4.72526855466171e-06,4.726470947180594e-06,4.723190307531766e-06],"warmups":[[32768,4.778814697292688e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137928","date":"2026-08-08 04:13:51.553100","duration":1.1059329999989131,"mem_peak_pagefile_usage":35901440,"uptime":24849.431564807892},"values":[4.703182983401e-06,4.702029418934828e-06,4.712081909219457e-06,4.731924438505786e-06,4.751104736300249e-06,4.740881347720105e-06],"warmups":[[32768,4.7482604980109144e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151187","date":"2026-08-08 04:13:52.936770","duration":1.1277963999964413,"mem_peak_pagefile_usage":35971072,"uptime":24850.8022916317},"values":[4.816384887695868e-06,4.832910156293835e-06,4.810650634845537e-06,4.824731445363106e-06,4.814492797877712e-06,4.823809814480384e-06],"warmups":[[32768,4.821011352573734e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140219","date":"2026-08-08 04:13:54.283943","duration":1.1146981999991112,"mem_peak_pagefile_usage":36540416,"uptime":24852.16014814377},"values":[4.776156616204119e-06,4.772979736333838e-06,4.758395385717762e-06,4.763232421933772e-06,4.770950317367628e-06,4.757772827157503e-06],"warmups":[[32768,4.750775146500352e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147564","date":"2026-08-08 04:13:55.646278","duration":1.1337117999973998,"mem_peak_pagefile_usage":36249600,"uptime":24853.515283823013},"values":[4.84259033206591e-06,4.837149047864919e-06,4.8392608642533474e-06,4.854620361371964e-06,4.853344726551967e-06,4.858694457987589e-06],"warmups":[[32768,4.84695129399082e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145142","date":"2026-08-08 04:13:56.998180","duration":1.1226901000009093,"mem_peak_pagefile_usage":36589568,"uptime":24854.869619846344},"values":[4.798974609365736e-06,4.796768188430889e-06,4.798815917972377e-06,4.794207763669789e-06,4.7991394043211955e-06,4.798773193370742e-06],"warmups":[[32768,4.811526489234552e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147097","date":"2026-08-08 04:13:58.340606","duration":1.1113552000024356,"mem_peak_pagefile_usage":36143104,"uptime":24856.20964241028},"values":[4.755130004863162e-06,4.761010742093674e-06,4.761224365323891e-06,4.747335815458165e-06,4.749420166039187e-06,4.747833251994571e-06],"warmups":[[32768,4.742437744176264e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142209","date":"2026-08-08 04:13:59.676686","duration":1.1080235999979777,"mem_peak_pagefile_usage":36421632,"uptime":24857.550892591476},"values":[4.729940795811238e-06,4.7332061766658384e-06,4.736968994167867e-06,4.731646728539651e-06,4.734732055644564e-06,4.751672363245696e-06],"warmups":[[32768,4.728640747075907e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148196","date":"2026-08-08 04:14:01.022045","duration":1.1131612000026507,"mem_peak_pagefile_usage":36380672,"uptime":24858.889985322952},"values":[4.769152831984869e-06,4.768258666909553e-06,4.769625854494919e-06,4.7597198487014936e-06,4.761785888707237e-06,4.728710937484948e-06],"warmups":[[32768,4.755935668954159e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143592","date":"2026-08-08 04:14:02.342470","duration":1.0928631000024325,"mem_peak_pagefile_usage":36352000,"uptime":24860.21547484398},"values":[4.680718994176658e-06,4.667199707042435e-06,4.665753173815901e-06,4.658505249000022e-06,4.6671203612902445e-06,4.659179687505066e-06],"warmups":[[32768,4.689620971665143e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145375","date":"2026-08-08 04:14:03.685490","duration":1.1108505999982299,"mem_peak_pagefile_usage":37064704,"uptime":24861.55678319931},"values":[4.755944824297309e-06,4.751568603467149e-06,4.755642700193796e-06,4.751562500016071e-06,4.750381469742493e-06,4.725210571265848e-06],"warmups":[[32768,4.74636535652273e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141600","date":"2026-08-08 04:14:05.037856","duration":1.1211244000005536,"mem_peak_pagefile_usage":36380672,"uptime":24862.912761211395},"values":[4.771826171867666e-06,4.7949920654044575e-06,4.812777709917171e-06,4.787976074283051e-06,4.79591674806823e-06,4.819842529202312e-06],"warmups":[[32768,4.76954650885375e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150465","date":"2026-08-08 04:14:06.420442","duration":1.1271511999984796,"mem_peak_pagefile_usage":35913728,"uptime":24864.28680753708},"values":[4.81707458499514e-06,4.80337829589228e-06,4.833666992110075e-06,4.818298339870353e-06,4.819924926735553e-06,4.810357666085174e-06],"warmups":[[32768,4.82242736810079e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141869","date":"2026-08-08 04:14:07.766878","duration":1.1163130999993882,"mem_peak_pagefile_usage":35811328,"uptime":24865.64164185524},"values":[4.783541870057029e-06,4.7778106689877475e-06,4.780368041967797e-06,4.762094116150806e-06,4.763107299798897e-06,4.759002685483793e-06],"warmups":[[32768,4.772900390581647e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147181","date":"2026-08-08 04:14:09.097941","duration":1.1005298999989463,"mem_peak_pagefile_usage":36171776,"uptime":24866.967146635056},"values":[4.702447509719043e-06,4.697610473614056e-06,4.7037353515522184e-06,4.707531738312731e-06,4.706088256867247e-06,4.693673706146484e-06],"warmups":[[32768,4.7199645996087725e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138253","date":"2026-08-08 04:14:10.459436","duration":1.1286255000013625,"mem_peak_pagefile_usage":36433920,"uptime":24868.337512016296},"values":[4.840048217769066e-06,4.839810180734538e-06,4.839126586886344e-06,4.825952148346246e-06,4.8177093505685775e-06,4.81217956549429e-06],"warmups":[[32768,4.815380859279905e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138863","date":"2026-08-08 04:14:11.799628","duration":1.1092003999983717,"mem_peak_pagefile_usage":36913152,"uptime":24869.676974773407},"values":[4.709045410167256e-06,4.710369873039966e-06,4.711425781178669e-06,4.717935180642563e-06,4.7143005370564595e-06,4.707702636719269e-06],"warmups":[[32768,4.709555053716841e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143679","date":"2026-08-08 04:14:13.143883","duration":1.1133241999996244,"mem_peak_pagefile_usage":36446208,"uptime":24871.016194343567},"values":[4.7825653076705166e-06,4.776196289024703e-06,4.777151489276932e-06,4.74751892087788e-06,4.762338256858456e-06,4.735192871141436e-06],"warmups":[[32768,4.752957153297821e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137958","date":"2026-08-08 04:14:14.478732","duration":1.1049667999977828,"mem_peak_pagefile_usage":36462592,"uptime":24872.357657194138},"values":[4.750366210948265e-06,4.717196655290579e-06,4.714550781215188e-06,4.7059783935266e-06,4.706561279266275e-06,4.719058227520279e-06],"warmups":[[32768,4.734716796850336e-06]]}]},{"metadata":{"loops":32,"name":"jinja2/idiomatic/large-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.151454","calibrate_loops":32,"date":"2026-08-08 04:14:15.597766","duration":0.8757255000018631,"mem_peak_pagefile_usage":36564992,"uptime":24873.46250963211},"warmups":[[1,0.0039388000004692],[2,0.0033817500006989576],[4,0.0033129000003100373],[8,0.0033213125002475863],[16,0.00335054374977517],[32,0.003342471875043884],[32,0.0033435281250149274],[32,0.003332556249915797],[32,0.0033454031250812477],[32,0.0033447687500256507],[32,0.003378025000074558],[32,0.0033584749999135965]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139711","date":"2026-08-08 04:14:16.607438","duration":0.7766870000014023,"mem_peak_pagefile_usage":36110336,"uptime":24874.48417186737},"values":[0.0033663031249488995,0.0033860687500464337,0.0033644156250147716,0.0033822562500063214,0.0033628812500410277,0.00338183125006708],"warmups":[[32,0.0033605968750407555]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152539","date":"2026-08-08 04:14:17.615878","duration":0.7797208999982104,"mem_peak_pagefile_usage":35921920,"uptime":24875.48025202751},"values":[0.003377590624950244,0.0033843843749536973,0.003378518749968862,0.0033745812500001193,0.0033742093748969637,0.0033787750001010863],"warmups":[[32,0.003413240625036451]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151969","date":"2026-08-08 04:14:18.640891","duration":0.794996299999184,"mem_peak_pagefile_usage":36032512,"uptime":24876.505264043808},"values":[0.0034656531250902844,0.0034584312500101078,0.0034630406249789303,0.0034630781250371,0.0034347499999967113,0.003420453125045242],"warmups":[[32,0.003468831249961113]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152368","date":"2026-08-08 04:14:19.651471","duration":0.7818847999988066,"mem_peak_pagefile_usage":36564992,"uptime":24877.51585626602},"values":[0.0033912781250364787,0.00339155624999421,0.0033890468749859792,0.0033912468750258995,0.0033922031249176143,0.003390512500004661],"warmups":[[32,0.003410228124948844]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139084","date":"2026-08-08 04:14:20.650738","duration":0.7655673999979626,"mem_peak_pagefile_usage":36225024,"uptime":24878.525411605835},"values":[0.0033305093750186643,0.0033279218749839856,0.003331878124981813,0.0033355562499082225,0.003337615625014223,0.003336874999945394],"warmups":[[32,0.003333709374942373]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148221","date":"2026-08-08 04:14:21.653275","duration":0.7698717999992368,"mem_peak_pagefile_usage":36773888,"uptime":24879.518987178802},"values":[0.0033442093750863933,0.003346946874899004,0.0033514312499391963,0.003348265625049862,0.003348253125068368,0.003348100000039267],"warmups":[[32,0.003374618750058289]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151832","date":"2026-08-08 04:14:22.651188","duration":0.7639200000012352,"mem_peak_pagefile_usage":36401152,"uptime":24880.513234853745},"values":[0.0033339187499450418,0.0033227312499093387,0.003321615625054619,0.0033201499999222506,0.0033224249999648237,0.003322784375086485],"warmups":[[32,0.003336234374955893]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144756","date":"2026-08-08 04:14:23.683592","duration":0.8045048999993014,"mem_peak_pagefile_usage":36397056,"uptime":24881.554836511612},"values":[0.0035065875000555025,0.0035334781250639935,0.003523993750036425,0.003510178124997765,0.0035107343750269138,0.0035101156249766063],"warmups":[[32,0.003384046874998603]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141865","date":"2026-08-08 04:14:24.690313","duration":0.7768909000005806,"mem_peak_pagefile_usage":36364288,"uptime":24882.564748048782},"values":[0.0033423968750412314,0.0033736687499867912,0.003384431249969566,0.0033802250000007916,0.003377368749966081,0.0033743999999842345],"warmups":[[32,0.0033744781250106826]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150378","date":"2026-08-08 04:14:25.692996","duration":0.773232100000314,"mem_peak_pagefile_usage":36843520,"uptime":24883.558794021606},"values":[0.0033587187500643267,0.0033566124999424574,0.0033576906250800675,0.0033547437500374144,0.003358865625045837,0.003358003125072173],"warmups":[[32,0.0033570968749927488]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139402","date":"2026-08-08 04:14:26.693942","duration":0.7679968000011286,"mem_peak_pagefile_usage":37224448,"uptime":24884.56792473793},"values":[0.00334040625000398,0.003341184375017292,0.0033444499999859545,0.0033448249999992186,0.0033429312500175,0.0033448812500864733],"warmups":[[32,0.003354078125084925]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152719","date":"2026-08-08 04:14:27.730459","duration":0.7807418000011239,"mem_peak_pagefile_usage":36872192,"uptime":24885.59163737297},"values":[0.003404199999977209,0.003401390624958367,0.0033956125000713655,0.0033931281250261236,0.003401821874945199,0.003393428125036735],"warmups":[[32,0.0034082375000252796]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151380","date":"2026-08-08 04:14:28.737585","duration":0.774260599999252,"mem_peak_pagefile_usage":36634624,"uptime":24886.599757432938},"values":[0.0033652187499910724,0.00337064374991769,0.0033725593750659755,0.003371318750055252,0.0033731375000343178,0.003369971875031297],"warmups":[[32,0.0033869750000121712]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144302","date":"2026-08-08 04:14:29.756702","duration":0.7859671000005619,"mem_peak_pagefile_usage":36425728,"uptime":24887.626291036606},"values":[0.0033941843749971667,0.003396306250010639,0.0034352312500232074,0.0034490093750036976,0.003437021875015489,0.0034441531249740365],"warmups":[[32,0.0034049343749984473]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152690","date":"2026-08-08 04:14:30.759246","duration":0.7695180000009714,"mem_peak_pagefile_usage":36724736,"uptime":24888.620382785797},"values":[0.0033538906250214495,0.0033546500000056767,0.003342759375073001,0.0033455125000045882,0.0033500718750474334,0.003342668749951372],"warmups":[[32,0.0033597718750115746]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138451","date":"2026-08-08 04:14:31.767512","duration":0.7803744000011648,"mem_peak_pagefile_usage":36630528,"uptime":24889.645522594452},"values":[0.003354443750026803,0.003373243749933863,0.0033884093750202737,0.003389784375031013,0.0033888187499542255,0.0033876124999778767],"warmups":[[32,0.0034300687500490312]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143065","date":"2026-08-08 04:14:32.780949","duration":0.7830168000000413,"mem_peak_pagefile_usage":36147200,"uptime":24890.65400648117},"values":[0.0034044562499957465,0.003392046874978405,0.0033925062500657077,0.003396959374981634,0.0033919562499704625,0.0033975374999499763],"warmups":[[32,0.0034258781249718595]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141414","date":"2026-08-08 04:14:33.789621","duration":0.7776771999997436,"mem_peak_pagefile_usage":36368384,"uptime":24891.664656877518},"values":[0.003370115624989012,0.003372103125002468,0.0033716968749786247,0.003370078125044529,0.0033714718749706662,0.0033715125000526314],"warmups":[[32,0.0033989656249104883]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141829","date":"2026-08-08 04:14:34.790387","duration":0.7712816999992356,"mem_peak_pagefile_usage":36323328,"uptime":24892.662465810776},"values":[0.0033252718750418353,0.0033265968750129105,0.0033795531250007116,0.0033816812499480875,0.003380362500024603,0.003378934375064091],"warmups":[[32,0.0033317125000849046]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139364","date":"2026-08-08 04:14:35.793774","duration":0.769466800000373,"mem_peak_pagefile_usage":36716544,"uptime":24893.668110609055},"values":[0.003342487500049174,0.0033411687500120024,0.0033511249999946813,0.003354528124987155,0.00335692500004825,0.0033554531249819775],"warmups":[[32,0.0033550250000189408]]}]},{"metadata":{"loops":2048,"name":"jinja2/idiomatic/mixed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.152588","calibrate_loops":2048,"date":"2026-08-08 04:14:37.353292","duration":1.3180976000003284,"mem_peak_pagefile_usage":36163584,"uptime":24895.216831207275},"warmups":[[1,0.0002932999996119179],[2,0.00017795000167097896],[4,0.00013049999961367575],[8,7.962499967106851e-05],[16,7.649999997738632e-05],[32,7.74781250356682e-05],[64,7.861718751200897e-05],[128,7.865859376465778e-05],[256,7.855625000274813e-05],[512,7.890058594028915e-05],[1024,7.914863281399676e-05],[2048,7.915400390601235e-05],[2048,7.90722167973712e-05],[2048,7.913593750075165e-05],[2048,7.91249023439633e-05],[2048,7.918618164026725e-05],[2048,7.911220703249455e-05],[2048,7.91790527348013e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151390","date":"2026-08-08 04:14:38.740150","duration":1.1549818999992567,"mem_peak_pagefile_usage":35958784,"uptime":24896.60500717163},"values":[7.900942382832454e-05,7.90936523440422e-05,7.906879882746409e-05,7.908598632866415e-05,7.90255371097004e-05,7.895454101536359e-05],"warmups":[[2048,7.928090820286116e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145335","date":"2026-08-08 04:14:40.154355","duration":1.1829880000004778,"mem_peak_pagefile_usage":37056512,"uptime":24898.02516078949},"values":[8.09603515623536e-05,8.09800781258474e-05,8.162929687571818e-05,8.072836914152504e-05,8.09380371098456e-05,8.094975585848374e-05],"warmups":[[2048,8.100410156153259e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146962","date":"2026-08-08 04:14:41.573843","duration":1.1645798999998078,"mem_peak_pagefile_usage":36245504,"uptime":24899.44367980957},"values":[7.965776367235833e-05,7.965170898316387e-05,7.964882812494523e-05,7.978413085929503e-05,7.964516601433047e-05,7.955825195438138e-05],"warmups":[[2048,7.990605468854994e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152952","date":"2026-08-08 04:14:42.967153","duration":1.1630026000020735,"mem_peak_pagefile_usage":36114432,"uptime":24900.830572128296},"values":[7.973300781216608e-05,7.979550781200828e-05,7.965288085820532e-05,7.955253906288817e-05,7.965781250085513e-05,7.945161132738576e-05],"warmups":[[2048,7.959599609286272e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145844","date":"2026-08-08 04:14:44.362983","duration":1.1631501999981992,"mem_peak_pagefile_usage":37650432,"uptime":24902.233724355698},"values":[7.946069336028927e-05,7.956889648319532e-05,7.968452148432448e-05,7.950600585893142e-05,7.961577148307697e-05,7.989584960910179e-05],"warmups":[[2048,7.964746093769293e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139002","date":"2026-08-08 04:14:45.757985","duration":1.164200000002893,"mem_peak_pagefile_usage":36614144,"uptime":24903.635746240616},"values":[7.950805663980987e-05,7.967177734258257e-05,7.960883788982187e-05,7.966464843711663e-05,7.985625000017649e-05,7.999936523539475e-05],"warmups":[[2048,7.945234374950871e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139258","date":"2026-08-08 04:14:47.147246","duration":1.1584537999988243,"mem_peak_pagefile_usage":36478976,"uptime":24905.024641752243},"values":[7.924394531322321e-05,7.915834961025325e-05,7.936264648478186e-05,7.930454101590101e-05,7.941249999987576e-05,7.923300781342846e-05],"warmups":[[2048,7.934726562552896e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147032","date":"2026-08-08 04:14:48.528764","duration":1.1524786999980279,"mem_peak_pagefile_usage":36347904,"uptime":24906.397899866104},"values":[7.869375000169043e-05,7.900473632815874e-05,7.91198730478726e-05,7.884389648360468e-05,7.848481445194011e-05,7.903164062383894e-05],"warmups":[[2048,7.91635742185548e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149297","date":"2026-08-08 04:14:49.917501","duration":1.1585728999998537,"mem_peak_pagefile_usage":36331520,"uptime":24907.784774780273},"values":[7.932900390628106e-05,7.922709960794805e-05,7.929570312548151e-05,7.929912109361226e-05,7.920161132801695e-05,7.927099609261745e-05],"warmups":[[2048,7.942255859383351e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148455","date":"2026-08-08 04:14:51.304365","duration":1.156122199998208,"mem_peak_pagefile_usage":36360192,"uptime":24909.17259502411},"values":[7.91616699213904e-05,7.937744140562586e-05,7.939174804683091e-05,7.881879882809528e-05,7.892983398427589e-05,7.871777343737563e-05],"warmups":[[2048,7.939384765620616e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152205","date":"2026-08-08 04:14:52.677592","duration":1.1432026000002224,"mem_peak_pagefile_usage":36569088,"uptime":24910.54192852974},"values":[7.828178710944655e-05,7.827373046787045e-05,7.81575683603819e-05,7.808154296817804e-05,7.801513671878979e-05,7.81640136722217e-05],"warmups":[[2048,7.861928710894972e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153424","date":"2026-08-08 04:14:54.065568","duration":1.1587729999992007,"mem_peak_pagefile_usage":36265984,"uptime":24911.928743839264},"values":[7.951416015572477e-05,7.936708984424001e-05,7.894980468847734e-05,7.91230957037925e-05,7.9229833984229e-05,7.914082031135194e-05],"warmups":[[2048,7.977583007701128e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153276","date":"2026-08-08 04:14:55.465723","duration":1.1708066999999573,"mem_peak_pagefile_usage":36274176,"uptime":24913.3291554451},"values":[7.952558593871117e-05,8.036293945323791e-05,8.035224609415081e-05,8.079189453091828e-05,8.049731445147756e-05,8.020917968742935e-05],"warmups":[[2048,7.919125976485475e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141404","date":"2026-08-08 04:14:56.842677","duration":1.1462305999993987,"mem_peak_pagefile_usage":36352000,"uptime":24914.71765446663},"values":[7.853178710881537e-05,7.848974609281356e-05,7.842333984342531e-05,7.836269531225071e-05,7.840063476649561e-05,7.835361328112356e-05],"warmups":[[2048,7.852416992193412e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143325","date":"2026-08-08 04:14:58.231211","duration":1.1561221000010846,"mem_peak_pagefile_usage":36261888,"uptime":24916.104149341583},"values":[7.91359374989753e-05,7.897094726594389e-05,7.915346679610025e-05,7.90372070316181e-05,7.920122070359525e-05,7.941762695296006e-05],"warmups":[[2048,7.918867187584056e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141623","date":"2026-08-08 04:14:59.617852","duration":1.1574934999989637,"mem_peak_pagefile_usage":36499456,"uptime":24917.49295949936},"values":[7.950581054672057e-05,7.933549804661766e-05,7.90800781249601e-05,7.920444335951515e-05,7.898139648432334e-05,7.877070312467538e-05],"warmups":[[2048,7.955146484484032e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139119","date":"2026-08-08 04:15:00.987946","duration":1.141966200000752,"mem_peak_pagefile_usage":35889152,"uptime":24918.865557670593},"values":[7.810781249872889e-05,7.792875976520008e-05,7.784204101568548e-05,7.777343749992838e-05,7.82078613283943e-05,7.827421875106211e-05],"warmups":[[2048,7.866206054707447e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146173","date":"2026-08-08 04:15:02.383470","duration":1.1664760999992723,"mem_peak_pagefile_usage":36134912,"uptime":24920.253702878952},"values":[7.978540039133009e-05,7.993007812423514e-05,8.0028417968947e-05,8.00670898435385e-05,8.000170898370129e-05,7.958017578069132e-05],"warmups":[[2048,7.965717773394942e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147930","date":"2026-08-08 04:15:03.774287","duration":1.1610295999998925,"mem_peak_pagefile_usage":36286464,"uptime":24921.642910718918},"values":[7.954194335901832e-05,7.941552734358481e-05,7.92615722655654e-05,7.955380859314687e-05,7.950844726600792e-05,7.948979492233832e-05],"warmups":[[2048,7.946728515584311e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147782","date":"2026-08-08 04:15:05.196521","duration":1.1680120999990322,"mem_peak_pagefile_usage":36151296,"uptime":24923.06524991989},"values":[7.998354492144699e-05,8.000639648386709e-05,8.004726562482745e-05,8.00181640627784e-05,7.991025390552409e-05,7.993081054635809e-05],"warmups":[[2048,7.985581054725799e-05]]}]},{"metadata":{"loops":512,"name":"jinja2/idiomatic/conditional-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.143642","calibrate_loops":512,"date":"2026-08-08 04:15:06.865263","duration":1.426285800000187,"mem_peak_pagefile_usage":36089856,"uptime":24924.737509965897},"warmups":[[1,0.0005979000015940983],[2,0.0003835500010609394],[4,0.0003418750002310844],[8,0.00034038749981846195],[16,0.0003433874999245745],[32,0.00034276562496415863],[64,0.00034168125000633154],[128,0.00034182500002089],[256,0.00034205117188434997],[512,0.0003435984375030898],[512,0.0003432703124985892],[512,0.0003436730468706628],[512,0.00034297773436975376],[512,0.0003433556640644042],[512,0.0003435505859386012],[512,0.00034231777343762815]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150407","date":"2026-08-08 04:15:08.369055","duration":1.2742226000009396,"mem_peak_pagefile_usage":35950592,"uptime":24926.23541045189},"values":[0.0003486957031242355,0.00035021875000040836,0.00034991328124789334,0.00035019355468790536,0.00035014042968839476,0.00035009375000072396],"warmups":[[512,0.00034634726562643436]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138874","date":"2026-08-08 04:15:09.842033","duration":1.2403643999969063,"mem_peak_pagefile_usage":36106240,"uptime":24927.71943807602},"values":[0.00034052207031010084,0.00034026621094085385,0.00034020839844117745,0.0003396835937508058,0.0003397769531261474,0.0003396113281226576],"warmups":[[512,0.0003406705078177197]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143906","date":"2026-08-08 04:15:11.345368","duration":1.2746820000029402,"mem_peak_pagefile_usage":36253696,"uptime":24929.217640399933},"values":[0.0003510523437455504,0.000350515429687448,0.0003504382812522522,0.0003504638671927296,0.00034940664063043414,0.0003490013671836323],"warmups":[[512,0.000347153124998556]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142726","date":"2026-08-08 04:15:12.841942","duration":1.2681219000005512,"mem_peak_pagefile_usage":36417536,"uptime":24930.71570277214},"values":[0.0003469066406225352,0.00034661054687035175,0.0003463820312532562,0.0003466048828144608,0.00034687636718189196,0.00034646386718861777],"warmups":[[512,0.0003473687499990774]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144851","date":"2026-08-08 04:15:14.310848","duration":1.2398259000001417,"mem_peak_pagefile_usage":36368384,"uptime":24932.18261218071},"values":[0.00034006230468719423,0.0003394849609392736,0.0003395519531252944,0.0003397156249960176,0.0003398460937447112,0.000339646679691441],"warmups":[[512,0.00034088691405997906]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149489","date":"2026-08-08 04:15:15.796365","duration":1.2528129999991506,"mem_peak_pagefile_usage":36769792,"uptime":24933.663180351257},"values":[0.0003428097656268392,0.0003432781249941286,0.00034391738281414064,0.0003434060546894102,0.00034405195312814385,0.00034375527344110424],"warmups":[[512,0.00034382734375526525]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140112","date":"2026-08-08 04:15:17.285990","duration":1.25805599999876,"mem_peak_pagefile_usage":36282368,"uptime":24935.162390232086},"values":[0.00034465039062325786,0.00034464374999743086,0.0003450732421867997,0.00034495800780831587,0.0003450164062499539,0.00034490195312031346],"warmups":[[512,0.0003454796874962085]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151443","date":"2026-08-08 04:15:18.750048","duration":1.2330985000007786,"mem_peak_pagefile_usage":36257792,"uptime":24936.61442732811},"values":[0.0003378009765597767,0.0003379191406267523,0.0003381089843728091,0.00033857031250050795,0.00033792695312939713,0.0003382302734351583],"warmups":[[512,0.00033873828125052796]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153637","date":"2026-08-08 04:15:20.234075","duration":1.2557254999992438,"mem_peak_pagefile_usage":36573184,"uptime":24938.09722518921},"values":[0.00034408769531069083,0.00034425078124655784,0.00034409511718536123,0.00034417480468817985,0.00034417890625348946,0.0003440423828067196],"warmups":[[512,0.0003447779296905651]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151791","date":"2026-08-08 04:15:21.715284","duration":1.251836799998273,"mem_peak_pagefile_usage":36478976,"uptime":24939.580301761627},"values":[0.0003429412109383634,0.00034250468750229857,0.00034264140624884476,0.00034255468749933016,0.00034301328124541897,0.0003429125000025124],"warmups":[[512,0.00034563925781583293]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142003","date":"2026-08-08 04:15:23.217338","duration":1.2709814999980154,"mem_peak_pagefile_usage":36388864,"uptime":24941.092122077942},"values":[0.0003489798828155699,0.0003487031249989059,0.0003480232421821938,0.00034836992187337046,0.00034816992187103324,0.00034822480468932326],"warmups":[[512,0.0003490996093731269]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138332","date":"2026-08-08 04:15:24.727909","duration":1.2575082000003022,"mem_peak_pagefile_usage":36093952,"uptime":24942.605917453766},"values":[0.00034467617187061705,0.0003448892578177265,0.0003452607421863263,0.0003447740234392427,0.0003449621093736255,0.00034455195312688147],"warmups":[[512,0.0003451427734333379]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139122","date":"2026-08-08 04:15:26.211487","duration":1.255433099999209,"mem_peak_pagefile_usage":36306944,"uptime":24944.08921098709},"values":[0.00034414531250348546,0.00034429277343406284,0.00034429824219017746,0.00034439804687025344,0.00034470253905993786,0.00034420996093587064],"warmups":[[512,0.0003431314453123946]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144974","date":"2026-08-08 04:15:27.732233","duration":1.2630195999990974,"mem_peak_pagefile_usage":36200448,"uptime":24945.60350227356},"values":[0.00034631445312527376,0.0003470464843786658,0.00034649765624550355,0.00034674707031001617,0.00034643085937346996,0.00034667128905851996],"warmups":[[512,0.00034550312500414293]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150226","date":"2026-08-08 04:15:29.235803","duration":1.2737051000003703,"mem_peak_pagefile_usage":36384768,"uptime":24947.102164506912},"values":[0.0003491921874996251,0.0003529072265564537,0.000351448046870928,0.0003533640624979739,0.0003507527343771244,0.0003442607421817456],"warmups":[[512,0.0003430228515668432]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142072","date":"2026-08-08 04:15:30.711243","duration":1.246200500001578,"mem_peak_pagefile_usage":36700160,"uptime":24948.5854575634},"values":[0.0003418072265617411,0.0003412687500059519,0.0003415273437497035,0.0003415410156293319,0.0003416177734365533,0.0003415232421843939],"warmups":[[512,0.000342821093752832]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141154","date":"2026-08-08 04:15:32.191867","duration":1.2510419999998703,"mem_peak_pagefile_usage":36171776,"uptime":24950.06750512123},"values":[0.00034268808593651556,0.00034258964844013917,0.00034273398437534297,0.00034256542968336134,0.0003428800781293262,0.0003429519531295],"warmups":[[512,0.00034430000000185146]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149854","date":"2026-08-08 04:15:33.681939","duration":1.2576908999981242,"mem_peak_pagefile_usage":36478976,"uptime":24951.548851251602},"values":[0.0003449041015670673,0.0003448716796867757,0.0003452669921912843,0.0003454160156266539,0.00034413808593569684,0.0003436695312473148],"warmups":[[512,0.0003455435546868557]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151935","date":"2026-08-08 04:15:35.167367","duration":1.2525731999994605,"mem_peak_pagefile_usage":36052992,"uptime":24953.03173351288},"values":[0.0003434167968734414,0.0003433226562492564,0.0003436103515639388,0.0003433791015581278,0.0003435261718749416,0.0003432994140624146],"warmups":[[512,0.00034410488281366725]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146333","date":"2026-08-08 04:15:36.660408","duration":1.2624749999995402,"mem_peak_pagefile_usage":36380672,"uptime":24954.52999830246},"values":[0.00034598300781141234,0.00034605820312805236,0.00034633574218645435,0.00034632851562577116,0.00034639218750243117,0.00034642070312429496],"warmups":[[512,0.0003471556640590734]]}]},{"metadata":{"loops":1024,"name":"jinja2/idiomatic/fragment-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.150175","calibrate_loops":1024,"date":"2026-08-08 04:15:37.782468","duration":0.8790187000013248,"mem_peak_pagefile_usage":36335616,"uptime":24955.64878177643},"warmups":[[1,0.0003544999999576248],[2,0.00024340000163647346],[4,0.00014869999995426042],[8,0.00010572500013950048],[16,0.00010324375011805387],[32,0.00010355624999647262],[64,0.0001047593749490261],[128,0.00010424921873664061],[256,0.00010453906249097145],[512,0.0001048453124994353],[1024,0.0001047815429693344],[1024,0.0001046447265657946],[1024,0.0001047737304702423],[1024,0.00010450644531090347],[1024,0.00010444687499955307],[1024,0.00010439052734056986],[1024,0.00010452890624890188]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150149","date":"2026-08-08 04:15:38.790622","duration":0.7759097999987716,"mem_peak_pagefile_usage":36347904,"uptime":24956.65691757202},"values":[0.00010522099609389102,0.00010515888671847051,0.00010531806640656782,0.00010528749999849651,0.00010506572265711611,0.00010503886718638],"warmups":[[1024,0.00010563662109319694]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144044","date":"2026-08-08 04:15:39.797365","duration":0.7738146000010602,"mem_peak_pagefile_usage":36745216,"uptime":24957.66711831093},"values":[0.00010514130859462512,0.000105043261715565,0.00010527324218756462,0.00010537451171899193,0.00010537822265632713,0.00010543945312591063],"warmups":[[1024,0.00010559140624977204]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147419","date":"2026-08-08 04:15:40.810624","duration":0.7824973999995564,"mem_peak_pagefile_usage":36290560,"uptime":24958.677349090576},"values":[0.00010644765625045238,0.00010610595703042236,0.00010630078125117848,0.00010647792968754288,0.00010636171874978118,0.0001067529296889802],"warmups":[[1024,0.00010689580078349081]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151901","date":"2026-08-08 04:15:41.810804","duration":0.7673634999991918,"mem_peak_pagefile_usage":36024320,"uptime":24959.67241716385},"values":[0.00010435673828013137,0.00010433046874780416,0.00010474033203067279,0.00010431933593579856,0.00010433896484585148,0.00010442822265588347],"warmups":[[1024,0.00010472246093584658]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145894","date":"2026-08-08 04:15:42.810633","duration":0.773127199998271,"mem_peak_pagefile_usage":36147200,"uptime":24960.68136572838},"values":[0.00010494785156467401,0.00010481074218660069,0.0001048150390623448,0.00010479775390592749,0.00010479755859194029,0.0001048538085939299],"warmups":[[1024,0.00010486884765370519]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137910","date":"2026-08-08 04:15:43.812415","duration":0.7707507999984955,"mem_peak_pagefile_usage":36368384,"uptime":24961.690566778183},"values":[0.00010449687500013738,0.00010445449218821068,0.00010445273437653668,0.00010447089843879098,0.00010456728515606528,0.0001050205078101385],"warmups":[[1024,0.0001047826171891586]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140967","date":"2026-08-08 04:15:44.809054","duration":0.7653715999986161,"mem_peak_pagefile_usage":36286464,"uptime":24962.68172955513},"values":[0.00010414990234508537,0.00010396269531298685,0.00010390205078181225,0.00010420429687840738,0.00010456171874650977,0.00010410634765634086],"warmups":[[1024,0.00010433369140727677]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145323","date":"2026-08-08 04:15:45.808663","duration":0.7676810000011756,"mem_peak_pagefile_usage":36057088,"uptime":24963.676822423935},"values":[0.00010438056640893478,0.00010424531249952906,0.00010431308593794597,0.00010430449219001048,0.00010435195312652468,0.00010460009765722589],"warmups":[[1024,0.00010546669922106844]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152442","date":"2026-08-08 04:15:46.811992","duration":0.7690288000012515,"mem_peak_pagefile_usage":36630528,"uptime":24964.67317724228},"values":[0.00010473046874892589,0.00010450117187588148,0.00010455673828246859,0.00010451347656115217,0.00010464589843905969,0.0001046562500022219],"warmups":[[1024,0.00010517441406321382]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150502","date":"2026-08-08 04:15:47.815837","duration":0.7747560999996495,"mem_peak_pagefile_usage":36855808,"uptime":24965.68208026886},"values":[0.0001048088867214858,0.0001049751953132727,0.0001049427734365338,0.00010509072265563191,0.00010510664062479691,0.00010512353515679251],"warmups":[[1024,0.00010511328125062391]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145090","date":"2026-08-08 04:15:48.824159","duration":0.7736286000035761,"mem_peak_pagefile_usage":36507648,"uptime":24966.692708969116},"values":[0.00010532070312407882,0.00010524150390622822,0.00010528222656347452,0.00010526103515573482,0.00010532402344054503,0.00010525595703114732],"warmups":[[1024,0.00010563466796753573]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151739","date":"2026-08-08 04:15:49.824996","duration":0.7664111999984016,"mem_peak_pagefile_usage":35721216,"uptime":24967.687009096146},"values":[0.00010412568359186025,0.00010399667968741255,0.00010434208984477777,0.00010428056640421346,0.00010432763671985867,0.00010436376953038007],"warmups":[[1024,0.00010442402343713297]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150067","date":"2026-08-08 04:15:50.848551","duration":0.7723967000019911,"mem_peak_pagefile_usage":36003840,"uptime":24968.71480846405},"values":[0.0001048873046869403,0.00010467138671899079,0.00010462460937432638,0.00010459824218855829,0.00010459755859315578,0.00010473847656200519],"warmups":[[1024,0.00010526718750014652]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143718","date":"2026-08-08 04:15:51.853670","duration":0.7744143999989319,"mem_peak_pagefile_usage":36372480,"uptime":24969.723883628845},"values":[0.00010544658203315294,0.00010533427734316092,0.00010531250000056502,0.00010534619140756263,0.00010530966796906682,0.00010515205078220902],"warmups":[[1024,0.00010586259765688055]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141043","date":"2026-08-08 04:15:52.860210","duration":0.7701918999991904,"mem_peak_pagefile_usage":36356096,"uptime":24970.732851028442},"values":[0.0001047890625009984,0.00010476601562459109,0.0001047769531261622,0.00010492998046629509,0.00010483027343610729,0.0001048728515620212],"warmups":[[1024,0.00010477578124934439]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151864","date":"2026-08-08 04:15:53.862827","duration":0.7763613999995869,"mem_peak_pagefile_usage":36401152,"uptime":24971.72720837593},"values":[0.00010543378906291423,0.00010522890624997672,0.0001050720703119623,0.00010527646484703723,0.00010537724609349652,0.00010525498046831672],"warmups":[[1024,0.00010572099609618135]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141174","date":"2026-08-08 04:15:54.863281","duration":0.7682623000000603,"mem_peak_pagefile_usage":36171776,"uptime":24972.736000299454},"values":[0.00010453867187365518,0.00010438593749739766,0.00010439257812677738,0.00010449736328155268,0.0001048210937497629,0.00010447763671805887],"warmups":[[1024,0.0001047989257827453]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138123","date":"2026-08-08 04:15:55.870416","duration":0.7739873999998963,"mem_peak_pagefile_usage":36044800,"uptime":24973.745991706848},"values":[0.00010534775390524942,0.00010510322265844252,0.00010534658202843161,0.00010534482422031033,0.00010534541015516652,0.00010521445312505762],"warmups":[[1024,0.00010589150390671875]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149388","date":"2026-08-08 04:15:56.875504","duration":0.7714821000008669,"mem_peak_pagefile_usage":37171200,"uptime":24974.739847898483},"values":[0.00010506523437570081,0.00010512441406262951,0.00010507304687479291,0.0001048568359394153,0.00010506894531303601,0.0001048472656250965],"warmups":[[1024,0.00010515791015919262]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151881","date":"2026-08-08 04:15:57.873212","duration":0.7659609999973327,"mem_peak_pagefile_usage":36098048,"uptime":24975.73482275009},"values":[0.00010414921874968286,0.00010422216796968087,0.00010422539062204805,0.00010419345703027716,0.00010416083984665647,0.00010423212890842137],"warmups":[[1024,0.000104791796875503]]}]},{"metadata":{"loops":8192,"name":"jinja2/idiomatic/fortunes-encoded"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.140050","calibrate_loops":8192,"date":"2026-08-08 04:15:59.421091","duration":1.3067918999986432,"mem_peak_pagefile_usage":36278272,"uptime":24977.297176122665},"warmups":[[1,9.099999806494452e-05],[2,4.685000021709129e-05],[4,4.3000000005122274e-05],[8,3.852500003631576e-05],[16,3.135000019938161e-05],[32,1.8987499970535282e-05],[64,1.9192187494354584e-05],[128,1.9347656234458555e-05],[256,1.9472656248353815e-05],[512,1.964902344298025e-05],[1024,1.968212890801624e-05],[2048,1.9575048828102126e-05],[4096,1.9599438476625153e-05],[8192,1.958956298819814e-05],[8192,1.9650561523754106e-05],[8192,1.9595996093801915e-05],[8192,1.9617431640472915e-05],[8192,1.9600671386843516e-05],[8192,1.9599267578218615e-05],[8192,1.960844726545119e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139423","date":"2026-08-08 04:16:00.824147","duration":1.1492048000000068,"mem_peak_pagefile_usage":36139008,"uptime":24978.700616121292},"values":[1.9669165038926906e-05,1.9699890136948284e-05,1.9679809570405382e-05,1.9663122558633006e-05,1.9653833007726718e-05,1.9663598632924106e-05],"warmups":[[8192,1.966879882786543e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150329","date":"2026-08-08 04:16:02.206017","duration":1.150957699999708,"mem_peak_pagefile_usage":35921920,"uptime":24980.072238206863},"values":[1.975596923831091e-05,1.977618408188775e-05,1.9720825195523872e-05,1.967321777351927e-05,1.9635302734410942e-05,1.958142089852899e-05],"warmups":[[8192,1.9703210449417696e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141940","date":"2026-08-08 04:16:03.601723","duration":1.143095400002494,"mem_peak_pagefile_usage":36585472,"uptime":24981.47660446167},"values":[1.9485498047089322e-05,1.9562841796716413e-05,1.959235839876783e-05,1.9602258300999154e-05,1.9596740722604977e-05,1.9539306640670162e-05],"warmups":[[8192,1.9464062499974233e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142138","date":"2026-08-08 04:16:05.005414","duration":1.1471144999995886,"mem_peak_pagefile_usage":36438016,"uptime":24982.879497528076},"values":[1.9624145507712853e-05,1.9634033203264067e-05,1.963009033190133e-05,1.961427001972993e-05,1.9675280761521918e-05,1.964804687482058e-05],"warmups":[[8192,1.9603393554668003e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152071","date":"2026-08-08 04:16:06.371228","duration":1.1368547999991279,"mem_peak_pagefile_usage":36626432,"uptime":24984.235594272614},"values":[1.9451025390804233e-05,1.9436364746105994e-05,1.9436621093493756e-05,1.9417333984250718e-05,1.9415661621113856e-05,1.9401855468892393e-05],"warmups":[[8192,1.9572875976425763e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149927","date":"2026-08-08 04:16:07.741751","duration":1.1420779000000039,"mem_peak_pagefile_usage":36409344,"uptime":24985.60799264908},"values":[1.953576660129741e-05,1.9525170898759825e-05,1.9536791992180724e-05,1.9535681152316187e-05,1.9541894531460713e-05,1.9516271972719323e-05],"warmups":[[8192,1.9613989258093767e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145865","date":"2026-08-08 04:16:09.109809","duration":1.1382181000008131,"mem_peak_pagefile_usage":36364288,"uptime":24986.980145931244},"values":[1.949313964866306e-05,1.9503796386821648e-05,1.9496777343697147e-05,1.9476684570030045e-05,1.947661132817302e-05,1.946306152333932e-05],"warmups":[[8192,1.9422326659856992e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148580","date":"2026-08-08 04:16:10.484596","duration":1.144529799999873,"mem_peak_pagefile_usage":36478976,"uptime":24988.352432727814},"values":[1.9572204589923814e-05,1.9557519530977174e-05,1.9577783203050814e-05,1.956442871087205e-05,1.958001708990409e-05,1.958489990228074e-05],"warmups":[[8192,1.963685302719398e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141277","date":"2026-08-08 04:16:11.850934","duration":1.1364427000007709,"mem_peak_pagefile_usage":36360192,"uptime":24989.7259247303},"values":[1.9449719238284757e-05,1.9450781250096583e-05,1.9443395995910606e-05,1.9443090820470132e-05,1.9464135742275346e-05,1.941270751926183e-05],"warmups":[[8192,1.9429650878866056e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152885","date":"2026-08-08 04:16:13.233495","duration":1.1532399999996414,"mem_peak_pagefile_usage":36413440,"uptime":24991.09722304344},"values":[1.9600463867064377e-05,1.9602502441262715e-05,1.9607934570231578e-05,1.9581762695342064e-05,1.961223144553159e-05,1.964877929694353e-05],"warmups":[[8192,1.9653515625162044e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149287","date":"2026-08-08 04:16:14.601579","duration":1.1385900999994192,"mem_peak_pagefile_usage":36548608,"uptime":24992.46891617775},"values":[1.9552392578336963e-05,1.9412207031166417e-05,1.944256591812632e-05,1.942926025400027e-05,1.9449841308638582e-05,1.9477856445515584e-05],"warmups":[[8192,1.9564941406091663e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152812","date":"2026-08-08 04:16:15.993994","duration":1.1601824999997916,"mem_peak_pagefile_usage":36147200,"uptime":24993.85735464096},"values":[1.9818518066649915e-05,1.982330322292114e-05,1.9854223633153367e-05,1.9881604003568754e-05,1.9951391601491508e-05,1.9852233887007742e-05],"warmups":[[8192,1.9818090820411527e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149538","date":"2026-08-08 04:16:17.378670","duration":1.1540292000026966,"mem_peak_pagefile_usage":36139008,"uptime":24995.24551677704},"values":[1.965270996073798e-05,1.9751574706905473e-05,1.9790979004064013e-05,1.9774633789104712e-05,1.977947998055285e-05,1.9753503417874185e-05],"warmups":[[8192,1.9726049804269508e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139655","date":"2026-08-08 04:16:18.754340","duration":1.1454660000017611,"mem_peak_pagefile_usage":36847616,"uptime":24996.630763053894},"values":[1.954154052707935e-05,1.962800292965028e-05,1.9620727538693927e-05,1.9625903320719118e-05,1.9610510253897928e-05,1.9626245117088104e-05],"warmups":[[8192,1.9568518066392926e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149545","date":"2026-08-08 04:16:20.134192","duration":1.1511605999985477,"mem_peak_pagefile_usage":37560320,"uptime":24998.00111889839},"values":[1.9708776855420496e-05,1.967625732435252e-05,1.9696594238283183e-05,1.9695068359304457e-05,1.972818603501736e-05,1.969609375018777e-05],"warmups":[[8192,1.9683874512121946e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143359","date":"2026-08-08 04:16:21.517048","duration":1.1513467999975546,"mem_peak_pagefile_usage":36478976,"uptime":24999.390330076218},"values":[1.9474438476496658e-05,1.9509313964771735e-05,1.962526855470159e-05,1.9926623535226895e-05,1.9952050781313346e-05,1.9911669921768294e-05],"warmups":[[8192,1.9487194824030496e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143632","date":"2026-08-08 04:16:22.905920","duration":1.160380899997108,"mem_peak_pagefile_usage":36745216,"uptime":25000.778215408325},"values":[1.985167236329133e-05,1.9818908691515702e-05,1.9830615234361915e-05,1.9904882812671332e-05,1.9888220214703267e-05,1.9882897949408118e-05],"warmups":[[8192,1.9865515136441303e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151912","date":"2026-08-08 04:16:24.285696","duration":1.151970999999321,"mem_peak_pagefile_usage":36569088,"uptime":25002.150030851364},"values":[1.9683801269376744e-05,1.970397949202507e-05,1.9730688476382596e-05,1.9682836914114432e-05,1.9738354492204735e-05,1.970744628909671e-05],"warmups":[[8192,1.9754248047121337e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137947","date":"2026-08-08 04:16:25.674254","duration":1.160372299997107,"mem_peak_pagefile_usage":36519936,"uptime":25003.55301976204},"values":[1.9729248046829184e-05,1.9847216797153067e-05,1.989713134786797e-05,1.9855346679698016e-05,1.9912121581810993e-05,1.9973645019710773e-05],"warmups":[[8192,1.9742968750069423e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152314","date":"2026-08-08 04:16:27.061199","duration":1.1571873000029882,"mem_peak_pagefile_usage":36438016,"uptime":25004.925594568253},"values":[1.9788415527521863e-05,1.9795495605379188e-05,1.9802221679743326e-05,1.9798730468423287e-05,1.9822766113009038e-05,1.9785363769564412e-05],"warmups":[[8192,1.977252197260526e-05]]}]},{"metadata":{"loops":16,"name":"jinja2/idiomatic/encoded-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.146559","calibrate_loops":16,"date":"2026-08-08 04:16:28.648752","duration":1.344499699996959,"mem_peak_pagefile_usage":36163584,"uptime":25006.518544197083},"warmups":[[1,0.011140500002511544],[2,0.01030220000029658],[4,0.010223750000477594],[8,0.010711962499954097],[16,0.010220806249890302],[16,0.01042823750003663],[16,0.010457599999881495],[16,0.01049883749988112],[16,0.010473762499941586],[16,0.010465737499998795],[16,0.010230774999854475]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142334","date":"2026-08-08 04:16:30.063517","duration":1.183534800002235,"mem_peak_pagefile_usage":35946496,"uptime":25007.93868613243},"values":[0.010130506250106919,0.010410343749981621,0.010437781249947875,0.010391906249878957,0.010376537500178529,0.010369950000040262],"warmups":[[16,0.010433550000016112]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143611","date":"2026-08-08 04:16:31.485337","duration":1.1887993999989703,"mem_peak_pagefile_usage":36179968,"uptime":25009.358626127243},"values":[0.010220637499969598,0.010372268749961222,0.010409931250023874,0.010433456249984374,0.010478262499873381,0.01053017499998532],"warmups":[[16,0.010484375000032742]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148630","date":"2026-08-08 04:16:32.896373","duration":1.1800057999971614,"mem_peak_pagefile_usage":37453824,"uptime":25010.764867782593},"values":[0.010120056249888876,0.010385900000073889,0.01036532500006615,0.010362043749864824,0.010357400000202688,0.010350068750085484],"warmups":[[16,0.01041419375019359]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146959","date":"2026-08-08 04:16:34.313416","duration":1.1886030999994546,"mem_peak_pagefile_usage":36548608,"uptime":25012.183521032333},"values":[0.010191625000061322,0.010467737499993746,0.010465431250167967,0.010451562500065847,0.010468456250009694,0.010446587499927773],"warmups":[[16,0.01039799375007533]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150832","date":"2026-08-08 04:16:35.738386","duration":1.1936850999991293,"mem_peak_pagefile_usage":35835904,"uptime":25013.6047372818},"values":[0.010310906249969776,0.01054535000002943,0.01047030624999934,0.010436093750058717,0.010473156249872773,0.010532193749895669],"warmups":[[16,0.010441424999953597]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150455","date":"2026-08-08 04:16:37.158809","duration":1.188504699999612,"mem_peak_pagefile_usage":36982784,"uptime":25015.025258541107},"values":[0.010193537500072125,0.010463125000114815,0.010453581249976196,0.010386793750058132,0.01042885624997325,0.010448993750060254],"warmups":[[16,0.010526887499963777]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141274","date":"2026-08-08 04:16:38.570830","duration":1.180994999998802,"mem_peak_pagefile_usage":38035456,"uptime":25016.446605443954},"values":[0.01012851875020715,0.010354999999890424,0.010364731250092518,0.010373437499993088,0.010357043749991135,0.010353324999869074],"warmups":[[16,0.010479449999820645]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144339","date":"2026-08-08 04:16:39.977567","duration":1.175120000003517,"mem_peak_pagefile_usage":36093952,"uptime":25017.850110054016},"values":[0.010059556250098467,0.01032353124992369,0.010316112500049712,0.010337262499888311,0.010298581250026473,0.01036899375003486],"warmups":[[16,0.010364481250007884]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149022","date":"2026-08-08 04:16:41.386877","duration":1.1792380999977468,"mem_peak_pagefile_usage":36282368,"uptime":25019.255036592484},"values":[0.010087131249974846,0.01032895000003009,0.010306012499995632,0.01036357499992846,0.010364081249917945,0.010368762500092998],"warmups":[[16,0.01047470000003159]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147697","date":"2026-08-08 04:16:42.805559","duration":1.1889107999995758,"mem_peak_pagefile_usage":36155392,"uptime":25020.67439508438},"values":[0.010195581249945462,0.01041439999994509,0.010412656250082364,0.010425018749856463,0.010414568750093167,0.010394856250059092],"warmups":[[16,0.010693712500142283]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146448","date":"2026-08-08 04:16:44.222478","duration":1.1845350000003236,"mem_peak_pagefile_usage":35880960,"uptime":25022.09327149391},"values":[0.010151037500008897,0.01038816250002128,0.010410962500145615,0.010422524999967209,0.01039290624999012,0.01043429374999505],"warmups":[[16,0.010430175000010422]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145833","date":"2026-08-08 04:16:45.641309","duration":1.1864526999997906,"mem_peak_pagefile_usage":36548608,"uptime":25023.512335777283},"values":[0.010211262499979057,0.010410643749992232,0.010392481249937191,0.010387149999814937,0.010416387500072233,0.010466525000083493],"warmups":[[16,0.010491231249943667]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139622","date":"2026-08-08 04:16:47.054385","duration":1.1837778000008257,"mem_peak_pagefile_usage":36519936,"uptime":25024.931396007538},"values":[0.010149062499976935,0.010380543749988647,0.010390812499963431,0.010407975000134684,0.010403387499991368,0.010426349999988815],"warmups":[[16,0.010463581250178322]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148750","date":"2026-08-08 04:16:48.466413","duration":1.1810805999994045,"mem_peak_pagefile_usage":36147200,"uptime":25026.334647655487},"values":[0.010130124999932377,0.010354062500027794,0.010339874999999665,0.01040902499994445,0.010378912499845683,0.010368968750071872],"warmups":[[16,0.01043698750004296]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141373","date":"2026-08-08 04:16:49.880136","duration":1.1823540000004868,"mem_peak_pagefile_usage":36020224,"uptime":25027.75503396988},"values":[0.010152437499982625,0.010322581249965879,0.01039348749986857,0.01041741249991901,0.010422418750067663,0.010401156249827181],"warmups":[[16,0.010439124999948035]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141216","date":"2026-08-08 04:16:51.300147","duration":1.1924985000005108,"mem_peak_pagefile_usage":36343808,"uptime":25029.17610669136},"values":[0.010249174999898969,0.010451300000113406,0.010445056250091511,0.010456750000003012,0.010499368750060967,0.010497725000050195],"warmups":[[16,0.01052469374985776]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138957","date":"2026-08-08 04:16:52.716783","duration":1.1860708999993221,"mem_peak_pagefile_usage":35889152,"uptime":25030.594686985016},"values":[0.010153737500104398,0.010434031250042608,0.010433375000047818,0.010399900000038542,0.010428037500105347,0.010466531250131084],"warmups":[[16,0.010421293749914184]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139180","date":"2026-08-08 04:16:54.136821","duration":1.188659399998869,"mem_peak_pagefile_usage":36581376,"uptime":25032.014492988586},"values":[0.010181800000054864,0.01038710624993655,0.010410462499976347,0.010444787499864105,0.010452700000087134,0.010474118750153139],"warmups":[[16,0.010546281250071843]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147863","date":"2026-08-08 04:16:55.550048","duration":1.1817399000028672,"mem_peak_pagefile_usage":37126144,"uptime":25033.418973207474},"values":[0.010151868749971982,0.010366168750124416,0.010357137500022873,0.010385299999825293,0.010388262499873235,0.010415262499918754],"warmups":[[16,0.01041415000008783]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142427","date":"2026-08-08 04:16:56.964091","duration":1.1825161999986449,"mem_peak_pagefile_usage":36585472,"uptime":25034.838495254517},"values":[0.010068224999940867,0.010308068750191524,0.01040133125002285,0.010428462499930902,0.01040195625000706,0.010510156249893043],"warmups":[[16,0.01038986875005321]]}]}],"metadata":{"cpu_affinity":"4","cpu_count":32,"hostname":"DESKTOP-F5QFSMS","perf_version":"2.10.0","platform":"Windows-11-10.0.26200-SP0","python_compiler":"MSC v.1944 64 bit (AMD64)","python_executable":"E:\\Work\\Heddle\\benchmarks\\python\\.venv\\Scripts\\python.exe","python_implementation":"cpython","python_version":"3.14.7 (64-bit) revision 823f032","timer":"QueryPerformanceCounter(), resolution: 100 ns","unit":"second"},"version":"1.0"} diff --git a/docs/benchmarks/2026-08-08/python/bench_mako_controlled.json b/docs/benchmarks/2026-08-08/python/bench_mako_controlled.json new file mode 100644 index 00000000..619aabaa --- /dev/null +++ b/docs/benchmarks/2026-08-08/python/bench_mako_controlled.json @@ -0,0 +1 @@ +{"benchmarks":[{"metadata":{"loops":8192,"name":"mako/controlled/composed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.147552","calibrate_loops":8192,"date":"2026-08-08 04:16:58.546724","duration":1.1179150000025402,"mem_peak_pagefile_usage":39448576,"uptime":25036.41531777382},"warmups":[[1,0.00017380000281264074],[2,5.0349999582977034e-05],[4,3.5150000257999636e-05],[8,3.211249986634357e-05],[16,2.8975000077480217e-05],[32,1.746562509197247e-05],[64,1.869374995067119e-05],[128,2.0627343729984204e-05],[256,1.687148437667929e-05],[512,1.7042382815191104e-05],[1024,1.716064452850219e-05],[2048,1.7199267578149602e-05],[4096,1.71917968749824e-05],[8192,1.7168615722873426e-05],[8192,1.7611621093927e-05],[8192,1.6713122558797977e-05],[8192,1.624787597664934e-05],[8192,1.6260656738431578e-05],[8192,1.628258056607379e-05],[8192,1.626091308581934e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137982","date":"2026-08-08 04:16:59.735236","duration":0.9675984999994398,"mem_peak_pagefile_usage":39116800,"uptime":25037.613956689835},"values":[1.6437194824359125e-05,1.663792724615476e-05,1.6286474609383816e-05,1.6265258789172066e-05,1.6267749023413103e-05,1.6299902343419603e-05],"warmups":[[8192,1.7279724120911055e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150424","date":"2026-08-08 04:17:00.930295","duration":0.9740415000014764,"mem_peak_pagefile_usage":39018496,"uptime":25038.796602010727},"values":[1.6501538086188816e-05,1.6923779297073338e-05,1.6515698242347554e-05,1.6522937011487215e-05,1.64766845700548e-05,1.6489196777325077e-05],"warmups":[[8192,1.6823791503917107e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143050","date":"2026-08-08 04:17:02.122237","duration":0.972929399998975,"mem_peak_pagefile_usage":39432192,"uptime":25039.996036052704},"values":[1.7158520507987163e-05,1.670413818377625e-05,1.628188476576753e-05,1.620615234410039e-05,1.6212304687623913e-05,1.627044677743328e-05],"warmups":[[8192,1.726405029334188e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145665","date":"2026-08-08 04:17:03.356959","duration":1.0183718000007502,"mem_peak_pagefile_usage":38793216,"uptime":25041.227706193924},"values":[1.7367553711178374e-05,1.7731262206943654e-05,1.7304833984432832e-05,1.725050048806409e-05,1.7308593750264833e-05,1.737514648425531e-05],"warmups":[[8192,1.7355017089659697e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143278","date":"2026-08-08 04:17:04.584321","duration":0.9863843999992241,"mem_peak_pagefile_usage":38842368,"uptime":25042.457169532776},"values":[1.7081726074508197e-05,1.69105346681242e-05,1.6524035644227553e-05,1.644616699225665e-05,1.6422546386785086e-05,1.644472656225915e-05],"warmups":[[8192,1.8018310546707994e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152125","date":"2026-08-08 04:17:05.790820","duration":0.9859737000006135,"mem_peak_pagefile_usage":38940672,"uptime":25043.655203342438},"values":[1.718969726560715e-05,1.763797607434725e-05,1.6515014648721404e-05,1.635225830076692e-05,1.6366625976260707e-05,1.6369665527538046e-05],"warmups":[[8192,1.7313708496224933e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146417","date":"2026-08-08 04:17:07.031805","duration":1.023930700001074,"mem_peak_pagefile_usage":39100416,"uptime":25044.90212917328},"values":[1.7445886230316177e-05,1.777637939426313e-05,1.738236083959066e-05,1.73825561522456e-05,1.7385961914140324e-05,1.7342651366991646e-05],"warmups":[[8192,1.7629431152244024e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141311","date":"2026-08-08 04:17:08.226502","duration":0.9786256000006688,"mem_peak_pagefile_usage":39387136,"uptime":25046.102048635483},"values":[1.6537817383088793e-05,1.689143066396781e-05,1.651346435549428e-05,1.6513403320317366e-05,1.6499450683493677e-05,1.6476635742446177e-05],"warmups":[[8192,1.735603027341881e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149869","date":"2026-08-08 04:17:09.464672","duration":1.0208700999974099,"mem_peak_pagefile_usage":39493632,"uptime":25047.3316757679},"values":[1.7404223632944138e-05,1.7752539062332318e-05,1.732757568362331e-05,1.729754638679637e-05,1.730800781230002e-05,1.731872558607961e-05],"warmups":[[8192,1.753054199227222e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139247","date":"2026-08-08 04:17:10.714921","duration":1.0324694000009913,"mem_peak_pagefile_usage":39178240,"uptime":25048.592480421066},"values":[1.756618652359876e-05,1.7951892089751453e-05,1.756297607435897e-05,1.7577990722994485e-05,1.756849365230906e-05,1.7560070801003747e-05],"warmups":[[8192,1.7600366211123486e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146543","date":"2026-08-08 04:17:11.952835","duration":1.0186475999980757,"mem_peak_pagefile_usage":39432192,"uptime":25049.82242155075},"values":[1.7290869140484944e-05,1.7739147949225043e-05,1.7379479980483836e-05,1.7346765136316833e-05,1.733343505838647e-05,1.735975341787821e-05],"warmups":[[8192,1.7318017578205058e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150645","date":"2026-08-08 04:17:13.171563","duration":1.0022417000000132,"mem_peak_pagefile_usage":39661568,"uptime":25051.03733611107},"values":[1.7053198241967493e-05,1.7404785156216462e-05,1.703543701170318e-05,1.7023376464919693e-05,1.7066052246050845e-05,1.701540527321299e-05],"warmups":[[8192,1.7124999999840185e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150629","date":"2026-08-08 04:17:14.385989","duration":0.9879618000013579,"mem_peak_pagefile_usage":39325696,"uptime":25052.251351118088},"values":[1.665167236319931e-05,1.704825439441393e-05,1.6694604492162313e-05,1.6683911132631124e-05,1.6704174804704763e-05,1.673156738313253e-05],"warmups":[[8192,1.751328125010332e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139081","date":"2026-08-08 04:17:15.604837","duration":1.0005578000018431,"mem_peak_pagefile_usage":39350272,"uptime":25053.482003450394},"values":[1.7614062500115324e-05,1.7963098144502254e-05,1.709997558574372e-05,1.6374011230446683e-05,1.637440185575656e-05,1.6402209472410334e-05],"warmups":[[8192,1.7709204101823417e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150385","date":"2026-08-08 04:17:16.798394","duration":0.9782280999970681,"mem_peak_pagefile_usage":39370752,"uptime":25054.66472387314},"values":[1.735858154283676e-05,1.664442138649136e-05,1.6278479003872803e-05,1.625042724606729e-05,1.625628662083045e-05,1.6269189452966515e-05],"warmups":[[8192,1.771604003941718e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143010","date":"2026-08-08 04:17:18.037288","duration":1.0191041000034602,"mem_peak_pagefile_usage":39497728,"uptime":25055.910333395004},"values":[1.728028564462747e-05,1.775050048813398e-05,1.7385681152060073e-05,1.7361682129291012e-05,1.7320959472488795e-05,1.7316589355331757e-05],"warmups":[[8192,1.7416101074196888e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140324","date":"2026-08-08 04:17:19.280523","duration":1.022801299997809,"mem_peak_pagefile_usage":40267776,"uptime":25057.15661382675},"values":[1.742683105465659e-05,1.7801232909953058e-05,1.7406396484176412e-05,1.738214111313141e-05,1.74067993161664e-05,1.7364819335785597e-05],"warmups":[[8192,1.7459887695192577e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138413","date":"2026-08-08 04:17:20.509392","duration":1.0103192999995372,"mem_peak_pagefile_usage":39579648,"uptime":25058.386997699738},"values":[1.7535522460754294e-05,1.7817077636816947e-05,1.745880126957644e-05,1.7430017090092065e-05,1.654473876921969e-05,1.6400585937326184e-05],"warmups":[[8192,1.757575683569712e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144184","date":"2026-08-08 04:17:21.761511","duration":1.0336897000015597,"mem_peak_pagefile_usage":39763968,"uptime":25059.633178949356},"values":[1.7650427245996525e-05,1.8038610840154234e-05,1.7536291503805757e-05,1.7567944335716845e-05,1.757086181664036e-05,1.759488525365782e-05],"warmups":[[8192,1.7677722167874776e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149191","date":"2026-08-08 04:17:23.011896","duration":1.0142346000029647,"mem_peak_pagefile_usage":39264256,"uptime":25060.879244089127},"values":[1.7267358398687094e-05,1.7612426757906974e-05,1.725954589826273e-05,1.7254370117125717e-05,1.7211047363296927e-05,1.7248718261697604e-05],"warmups":[[8192,1.7335583496258522e-05]]}]},{"metadata":{"loops":32768,"name":"mako/controlled/trivial-substitution"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.145292","calibrate_loops":32768,"date":"2026-08-08 04:17:24.742067","duration":1.5076069999995525,"mem_peak_pagefile_usage":39063552,"uptime":25062.61330986023},"warmups":[[1,5.999999848427251e-05],[2,1.8549999367678538e-05],[4,1.1799999811046291e-05],[8,1.0575000032986281e-05],[16,1.0349999911341001e-05],[32,8.531249932275387e-06],[64,6.940625041806925e-06],[128,5.173437500616274e-06],[256,7.021484378810783e-06],[512,5.704101560866093e-06],[1024,5.557910156994694e-06],[2048,5.607031249965644e-06],[4096,5.620727539401571e-06],[8192,5.617309570382645e-06],[16384,5.823382568381774e-06],[32768,5.645556640621052e-06],[32768,5.648840332050931e-06],[32768,5.659246826161812e-06],[32768,5.665115356490169e-06],[32768,5.65786132811219e-06],[32768,5.6574340819848246e-06],[32768,5.66984863281661e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149785","date":"2026-08-08 04:17:26.274983","duration":1.3117077999995672,"mem_peak_pagefile_usage":38952960,"uptime":25064.141920804977},"values":[5.60652770997816e-06,5.610046386661516e-06,5.6082702636350845e-06,5.614782714769007e-06,5.6234497070040135e-06,5.620147705109879e-06],"warmups":[[32768,5.67871704104661e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147299","date":"2026-08-08 04:17:27.819853","duration":1.3268602999996801,"mem_peak_pagefile_usage":39436288,"uptime":25065.688603162766},"values":[5.6717895507985006e-06,5.6825653076408855e-06,5.688699340811176e-06,5.68773193354577e-06,5.681710815386154e-06,5.685925293041905e-06],"warmups":[[32768,5.7396240233931195e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151281","date":"2026-08-08 04:17:29.353074","duration":1.312827700003254,"mem_peak_pagefile_usage":39006208,"uptime":25067.218466043472},"values":[5.605859375035216e-06,5.608178710980738e-06,5.618228149373294e-06,5.603768920892094e-06,5.610241699316454e-06,5.617694091797354e-06],"warmups":[[32768,5.73106994627981e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146816","date":"2026-08-08 04:17:30.878409","duration":1.3059108999987075,"mem_peak_pagefile_usage":39481344,"uptime":25068.74754858017},"values":[5.577169799764192e-06,5.594131469721653e-06,5.5971221923911685e-06,5.593981933560421e-06,5.5945831298753745e-06,5.592617797867128e-06],"warmups":[[32768,5.656036377033047e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148922","date":"2026-08-08 04:17:32.392342","duration":1.2977759999994305,"mem_peak_pagefile_usage":39464960,"uptime":25070.260162115097},"values":[5.557507324227551e-06,5.556805419915101e-06,5.549630737289313e-06,5.546563720648656e-06,5.546182251014997e-06,5.5453643797998e-06],"warmups":[[32768,5.629071044954692e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137982","date":"2026-08-08 04:17:33.943644","duration":1.3350067999999737,"mem_peak_pagefile_usage":38957056,"uptime":25071.82221364975},"values":[5.706420898476949e-06,5.703970336834452e-06,5.7093383789563745e-06,5.712173461902559e-06,5.707302856428065e-06,5.705651855536509e-06],"warmups":[[32768,5.826968383804143e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146219","date":"2026-08-08 04:17:35.512358","duration":1.3307967000000644,"mem_peak_pagefile_usage":38694912,"uptime":25073.382961034775},"values":[5.690521240331314e-06,5.6925262451601455e-06,5.703237915044568e-06,5.700396728536283e-06,5.692480468777461e-06,5.692834472714736e-06],"warmups":[[32768,5.771066284188109e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153279","date":"2026-08-08 04:17:37.049181","duration":1.3193957000003138,"mem_peak_pagefile_usage":39473152,"uptime":25074.912746191025},"values":[5.644931030279743e-06,5.646817016646821e-06,5.641696167013599e-06,5.6400054931904364e-06,5.642013549800318e-06,5.641723632821005e-06],"warmups":[[32768,5.733535766605513e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148590","date":"2026-08-08 04:17:38.593161","duration":1.3252250000005006,"mem_peak_pagefile_usage":39075840,"uptime":25076.460817575455},"values":[5.66408691404785e-06,5.666809082094382e-06,5.661703491255388e-06,5.668161010774497e-06,5.689596557667542e-06,5.694000244083064e-06],"warmups":[[32768,5.74336853031987e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142616","date":"2026-08-08 04:17:40.135167","duration":1.320719100000133,"mem_peak_pagefile_usage":39550976,"uptime":25078.009076356888},"values":[5.655303955021118e-06,5.64533996583183e-06,5.6318054199033796e-06,5.645065307646746e-06,5.6507019042806306e-06,5.659210205122278e-06],"warmups":[[32768,5.753674316433255e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151279","date":"2026-08-08 04:17:41.673499","duration":1.3194631999976991,"mem_peak_pagefile_usage":38928384,"uptime":25079.538373947144},"values":[5.651943969731121e-06,5.6479156493871585e-06,5.642352294943365e-06,5.650421142533446e-06,5.6476806640226584e-06,5.657354736343656e-06],"warmups":[[32768,5.716152954082787e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147030","date":"2026-08-08 04:17:43.216843","duration":1.3232277999995858,"mem_peak_pagefile_usage":39706624,"uptime":25081.08660364151},"values":[5.666619873001544e-06,5.672335815387619e-06,5.667800903275122e-06,5.654223632856059e-06,5.651446533194715e-06,5.643801879950949e-06],"warmups":[[32768,5.7504211424808105e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141252","date":"2026-08-08 04:17:44.739077","duration":1.3046384999979637,"mem_peak_pagefile_usage":39235584,"uptime":25082.614593029022},"values":[5.571392822201204e-06,5.561511230434135e-06,5.572241210893836e-06,5.581808471655236e-06,5.589993286037043e-06,5.588171386738949e-06],"warmups":[[32768,5.678515625051617e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152829","date":"2026-08-08 04:17:46.266000","duration":1.3073293999987072,"mem_peak_pagefile_usage":39010304,"uptime":25084.12922525406},"values":[5.6042663574285e-06,5.596707153388003e-06,5.5986236572325154e-06,5.594427490263065e-06,5.586074829033727e-06,5.596490478598781e-06],"warmups":[[32768,5.672756957952885e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139374","date":"2026-08-08 04:17:47.796764","duration":1.3136101999989478,"mem_peak_pagefile_usage":39260160,"uptime":25085.6739089489},"values":[5.62232360845627e-06,5.623278808597476e-06,5.623052978576126e-06,5.6212158203727824e-06,5.630136108436545e-06,5.612020874012913e-06],"warmups":[[32768,5.692416381819498e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153381","date":"2026-08-08 04:17:49.324462","duration":1.3087529000003997,"mem_peak_pagefile_usage":39243776,"uptime":25087.187765598297},"values":[5.609237670900491e-06,5.602032470686247e-06,5.596154785125762e-06,5.597564697312762e-06,5.596417236297668e-06,5.6024902342910465e-06],"warmups":[[32768,5.66968383786115e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144099","date":"2026-08-08 04:17:50.860209","duration":1.3194489999987127,"mem_peak_pagefile_usage":39288832,"uptime":25088.733133792877},"values":[5.63833007805048e-06,5.641592407235052e-06,5.649581909183965e-06,5.643603515625983e-06,5.652368164077437e-06,5.654354858442012e-06],"warmups":[[32768,5.713320922806631e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142429","date":"2026-08-08 04:17:52.389359","duration":1.310638700000709,"mem_peak_pagefile_usage":39567360,"uptime":25090.26296377182},"values":[5.604611206022625e-06,5.60722961429061e-06,5.612231445240035e-06,5.612286376965869e-06,5.611019897489022e-06,5.609420776431229e-06],"warmups":[[32768,5.691186523382186e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148484","date":"2026-08-08 04:17:53.926156","duration":1.3153486000010162,"mem_peak_pagefile_usage":39776256,"uptime":25091.79394197464},"values":[5.6152252196906005e-06,5.626577758821583e-06,5.633193969734052e-06,5.637847900419324e-06,5.637835693406146e-06,5.639608764651527e-06],"warmups":[[32768,5.695980834996561e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151754","date":"2026-08-08 04:17:55.472793","duration":1.3309269999990647,"mem_peak_pagefile_usage":39329792,"uptime":25093.33764910698},"values":[5.696676635746911e-06,5.695001220717977e-06,5.692471313545333e-06,5.702334594737124e-06,5.70003356936688e-06,5.700750732362536e-06],"warmups":[[32768,5.765066528273799e-06]]}]},{"metadata":{"loops":256,"name":"mako/controlled/large-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.152228","calibrate_loops":256,"date":"2026-08-08 04:17:56.893270","duration":1.192867199999455,"mem_peak_pagefile_usage":38936576,"uptime":25094.75749015808},"warmups":[[1,0.0010039000007964205],[2,0.0006591000001208158],[4,0.000664649999635003],[8,0.0006680000001324515],[16,0.0006762749999325024],[32,0.000685425000028772],[64,0.0006813156250018437],[128,0.000570354687482677],[256,0.0005649460937462436],[256,0.0005634691406157799],[256,0.0005639964843737744],[256,0.0005646957031331112],[256,0.0005647613281212216],[256,0.0005646289062468668],[256,0.0005644414062544456]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137859","date":"2026-08-08 04:17:58.141210","duration":1.029318000000785,"mem_peak_pagefile_usage":40157184,"uptime":25096.019908428192},"values":[0.000560840234371085,0.0005611597656240974,0.0005616039062488198,0.0005628496093663671,0.0005641882812597032,0.0005651941406341621],"warmups":[[256,0.0005588382812504733]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138397","date":"2026-08-08 04:17:59.387821","duration":1.030694199998834,"mem_peak_pagefile_usage":40288256,"uptime":25097.26641535759},"values":[0.0005564234375015076,0.0005555375000056983,0.0005570468750022428,0.0005565878906281796,0.0005569917968699656,0.00055795664061975],"warmups":[[256,0.0005980808593761822]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148334","date":"2026-08-08 04:18:00.645576","duration":1.0361259000019345,"mem_peak_pagefile_usage":39137280,"uptime":25098.513533115387},"values":[0.0005651464843765552,0.0005654742187601869,0.0005672789062458605,0.0005670160156228121,0.0005710324218739515,0.0005690582031121494],"warmups":[[256,0.0005574667968772928]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153352","date":"2026-08-08 04:18:01.912988","duration":1.0497835999995004,"mem_peak_pagefile_usage":39600128,"uptime":25099.776542425156},"values":[0.0005618792968675734,0.0005602675781233302,0.0005606832031190834,0.0005603984374999982,0.0005605871093763426,0.0005606246093634581],"warmups":[[256,0.0006496996093687812]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144526","date":"2026-08-08 04:18:03.151043","duration":1.0183233999996446,"mem_peak_pagefile_usage":40386560,"uptime":25101.023365736008},"values":[0.0005584175781194745,0.0005576664062516556,0.0005568097656265536,0.0005547539062575879,0.0005551269531309799,0.0005550542968677519],"warmups":[[256,0.0005540519531308519]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151290","date":"2026-08-08 04:18:04.404041","duration":1.0358425000013085,"mem_peak_pagefile_usage":38785024,"uptime":25102.26939892769},"values":[0.0005671078125004669,0.0005657875000082413,0.0005660753906227001,0.0005658035156130836,0.0005657187500105465,0.0005658875000023045],"warmups":[[256,0.0005638820312583448]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147355","date":"2026-08-08 04:18:05.647648","duration":1.0230564999983471,"mem_peak_pagefile_usage":40181760,"uptime":25103.51674747467},"values":[0.0005601460937469938,0.0005584671875027425,0.0005594011718699221,0.0005580582031257109,0.0005583136718740889,0.0005610289062474294],"warmups":[[256,0.0005561113281373764]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150472","date":"2026-08-08 04:18:06.911832","duration":1.0426267000002554,"mem_peak_pagefile_usage":38903808,"uptime":25104.777770996094},"values":[0.0005708304687459531,0.0005704789062548343,0.0005686585937496602,0.0005704527343652899,0.0005727156249974996,0.000572524999995494],"warmups":[[256,0.0005623335937485763]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142052","date":"2026-08-08 04:18:08.151038","duration":1.0226003999996465,"mem_peak_pagefile_usage":39014400,"uptime":25106.025264024734},"values":[0.000559451562509139,0.0005596144531239133,0.0005596425781249081,0.0005594359375038493,0.0005593824218834698,0.000559529296879191],"warmups":[[256,0.0005534195312577594]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141398","date":"2026-08-08 04:18:09.396784","duration":1.0282196000007389,"mem_peak_pagefile_usage":39268352,"uptime":25107.27194738388},"values":[0.000562036328119575,0.0005624179687515607,0.0005617847656225194,0.0005617164062527991,0.0005615914062531147,0.0005643835937547692],"warmups":[[256,0.0005573898437489788]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141841","date":"2026-08-08 04:18:10.675262","duration":1.0632356999994954,"mem_peak_pagefile_usage":39301120,"uptime":25108.549802064896},"values":[0.0005895214843718577,0.0005816007812455837,0.0005759367187465614,0.0005755253906158941,0.0005758808593725462,0.0006052843749984049],"warmups":[[256,0.0005648054687554804]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152287","date":"2026-08-08 04:18:11.914836","duration":1.019400000001042,"mem_peak_pagefile_usage":39485440,"uptime":25109.779205799103},"values":[0.0005569972656331856,0.0005572613281259464,0.0005583539062570253,0.0005584390625017477,0.0005583726562576885,0.0005583390624934736],"warmups":[[256,0.00054908476562332]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140943","date":"2026-08-08 04:18:13.165356","duration":1.0356307000001834,"mem_peak_pagefile_usage":38969344,"uptime":25111.041658639908},"values":[0.0005637535156353124,0.0005650226562607941,0.0005665234374987449,0.000567167968753779,0.000567328906257103,0.0005674281249952173],"warmups":[[256,0.0005599339843769258]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146108","date":"2026-08-08 04:18:14.417333","duration":1.0276910000029602,"mem_peak_pagefile_usage":39464960,"uptime":25112.287702322006},"values":[0.0005616628906324195,0.0005619300781205538,0.0005623507812515527,0.0005622839843653082,0.0005626691406206419,0.0005621433593745451],"warmups":[[256,0.0005567777343742364]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143440","date":"2026-08-08 04:18:15.660326","duration":1.024769899999228,"mem_peak_pagefile_usage":39116800,"uptime":25113.53337454796},"values":[0.0005588472656228305,0.0005581207031326585,0.0005585847656135456,0.0005590699218771533,0.0005603214843716842,0.0005664140625043501],"warmups":[[256,0.0005566855468686072]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139859","date":"2026-08-08 04:18:16.903841","duration":1.0262837999980547,"mem_peak_pagefile_usage":39571456,"uptime":25114.780658006668},"values":[0.0005609179687553478,0.0005596749999909889,0.0005599207031252718,0.0005599980468815602,0.0005619773437501863,0.0005623187499992355],"warmups":[[256,0.0005587109374971533]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141682","date":"2026-08-08 04:18:18.151074","duration":1.0287739000013971,"mem_peak_pagefile_usage":39526400,"uptime":25116.02617955208},"values":[0.0005638124999904903,0.0005620140624955638,0.0005621898437482287,0.0005622125000002143,0.0005628617187483087,0.0005655277343663556],"warmups":[[256,0.0005540273437532051]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145274","date":"2026-08-08 04:18:19.384334","duration":1.0174762000024202,"mem_peak_pagefile_usage":39006208,"uptime":25117.25570654869},"values":[0.0005521332031293014,0.0005510628906222337,0.000558359765619798,0.0005573734375019512,0.0005578089843822909,0.0005600300781338774],"warmups":[[256,0.0005527964843707878]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148678","date":"2026-08-08 04:18:20.617651","duration":1.0173344000031648,"mem_peak_pagefile_usage":39432192,"uptime":25118.48539376259},"values":[0.0005557156250119988,0.0005551324218799891,0.0005556074218731055,0.0005551093750000291,0.0005553351562497255,0.0005551085937440803],"warmups":[[256,0.0005579238281256949]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148724","date":"2026-08-08 04:18:21.851683","duration":1.016238100000919,"mem_peak_pagefile_usage":40099840,"uptime":25119.71933913231},"values":[0.0005555234374980955,0.0005545964843776119,0.0005558214843830456,0.0005552996093740603,0.0005556707031217911,0.0005556460937583552],"warmups":[[256,0.0005527691406257418]]}]},{"metadata":{"loops":8192,"name":"mako/controlled/mixed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.144715","calibrate_loops":8192,"date":"2026-08-08 04:18:23.088011","duration":0.9856374000009964,"mem_peak_pagefile_usage":38617088,"uptime":25120.960364103317},"warmups":[[1,9.270000009564683e-05],[2,3.719999949680641e-05],[4,2.8649999876506627e-05],[8,2.761250016192207e-05],[16,2.1249999917927198e-05],[32,1.3556249996327097e-05],[64,1.54640624714375e-05],[128,1.3838281233802263e-05],[256,1.5919140622600025e-05],[512,1.4635937503726382e-05],[1024,1.4496679689557368e-05],[2048,1.4447753905244554e-05],[4096,1.4477221679243257e-05],[8192,1.4511376952963673e-05],[8192,1.50073852540622e-05],[8192,1.466813964823288e-05],[8192,1.4746032714896273e-05],[8192,1.4707336426056372e-05],[8192,1.4698388671963158e-05],[8192,1.4681982421826945e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140940","date":"2026-08-08 04:18:24.142668","duration":0.8324799000001804,"mem_peak_pagefile_usage":39251968,"uptime":25122.018284082413},"values":[1.3968530273356095e-05,1.4359216308434952e-05,1.4112145996225678e-05,1.4159399414293006e-05,1.4165014648348517e-05,1.4178808593889869e-05],"warmups":[[8192,1.4039318847469673e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148083","date":"2026-08-08 04:18:25.206254","duration":0.8421656999998959,"mem_peak_pagefile_usage":38887424,"uptime":25123.0753800869},"values":[1.4099536132849977e-05,1.4524230956602935e-05,1.4288208007862124e-05,1.4310131835948425e-05,1.4289111328391613e-05,1.4315673828146913e-05],"warmups":[[8192,1.4230126953229671e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138875","date":"2026-08-08 04:18:26.270728","duration":0.8436685999986366,"mem_peak_pagefile_usage":39575552,"uptime":25124.148495435715},"values":[1.4177856445307668e-05,1.4599731445130715e-05,1.431864013667905e-05,1.4332031250230415e-05,1.4325756835908976e-05,1.433515625004489e-05],"warmups":[[8192,1.4252038574191772e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143170","date":"2026-08-08 04:18:27.331495","duration":0.8441608000030101,"mem_peak_pagefile_usage":38973440,"uptime":25125.204853773117},"values":[1.4132080078166354e-05,1.4556591796832663e-05,1.437083740229994e-05,1.4379077148518604e-05,1.4370654297213292e-05,1.4397326660198217e-05],"warmups":[[8192,1.4184497070246493e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149598","date":"2026-08-08 04:18:28.395540","duration":0.8458958999981405,"mem_peak_pagefile_usage":38830080,"uptime":25126.261877298355},"values":[1.4221740722408782e-05,1.4615051269650792e-05,1.4368981933632341e-05,1.4394946289186805e-05,1.4392358398396254e-05,1.4410351562688106e-05],"warmups":[[8192,1.4304492187200424e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139518","date":"2026-08-08 04:18:29.458844","duration":0.8456039000011515,"mem_peak_pagefile_usage":39542784,"uptime":25127.33572411537},"values":[1.425128173826451e-05,1.4652404785042705e-05,1.4343188476484414e-05,1.4354528808269151e-05,1.4325134277459739e-05,1.4321313476450825e-05],"warmups":[[8192,1.432420654268185e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142909","date":"2026-08-08 04:18:30.517781","duration":0.8427869000006467,"mem_peak_pagefile_usage":40165376,"uptime":25128.391693353653},"values":[1.4165002441668406e-05,1.4586633300783802e-05,1.429721679713225e-05,1.4318676757607562e-05,1.4297546386821125e-05,1.4319848632649013e-05],"warmups":[[8192,1.4210778808809721e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138649","date":"2026-08-08 04:18:31.587181","duration":0.8531046999996761,"mem_peak_pagefile_usage":39243776,"uptime":25129.46511244774},"values":[1.4271960449452337e-05,1.4726538085874097e-05,1.4537854003737749e-05,1.451923828144075e-05,1.4510949706725285e-05,1.4507958984388836e-05],"warmups":[[8192,1.4420642090229308e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139612","date":"2026-08-08 04:18:32.644844","duration":0.8418099999980768,"mem_peak_pagefile_usage":39022592,"uptime":25130.52223110199},"values":[1.4119348144436827e-05,1.4565100097563288e-05,1.4267968750036886e-05,1.4293835449041836e-05,1.4284716796986174e-05,1.4304956054367324e-05],"warmups":[[8192,1.4200988769363931e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151305","date":"2026-08-08 04:18:33.713221","duration":0.8508392999974603,"mem_peak_pagefile_usage":39219200,"uptime":25131.578573942184},"values":[1.4324633789364327e-05,1.4747326660291549e-05,1.4416369628733605e-05,1.4442456054641895e-05,1.4431420898297631e-05,1.4468566894798585e-05],"warmups":[[8192,1.4380883789133492e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138041","date":"2026-08-08 04:18:34.803119","duration":0.8531970000003639,"mem_peak_pagefile_usage":39763968,"uptime":25132.681852817535},"values":[1.445819091783207e-05,1.4975109863257785e-05,1.4518579101618911e-05,1.4318298339865976e-05,1.4324584960867526e-05,1.4354199218580277e-05],"warmups":[[8192,1.4530773925880425e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150931","date":"2026-08-08 04:18:35.872955","duration":0.8542527000026894,"mem_peak_pagefile_usage":39038976,"uptime":25133.738173246384},"values":[1.4363476562806454e-05,1.4792211914027575e-05,1.4530285644465124e-05,1.4535681152505475e-05,1.4512927246190799e-05,1.4512390136722786e-05],"warmups":[[8192,1.4413598632856406e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140218","date":"2026-08-08 04:18:36.935115","duration":0.8432352999989234,"mem_peak_pagefile_usage":39374848,"uptime":25134.811378240585},"values":[1.4158764648719568e-05,1.4603845214899991e-05,1.4318041992034125e-05,1.4318603515750539e-05,1.4279528808724962e-05,1.4300610351458687e-05],"warmups":[[8192,1.4287487792863374e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143075","date":"2026-08-08 04:18:37.995502","duration":0.8421390000003157,"mem_peak_pagefile_usage":39514112,"uptime":25135.869084596634},"values":[1.4138037109479029e-05,1.4613757324255516e-05,1.4315161132927301e-05,1.4285229492205787e-05,1.4255053710776622e-05,1.4264831543098211e-05],"warmups":[[8192,1.4294091796873687e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150418","date":"2026-08-08 04:18:39.060157","duration":0.8467673000013747,"mem_peak_pagefile_usage":39514112,"uptime":25136.926676273346},"values":[1.4261096191070521e-05,1.4632568359651543e-05,1.447752685557191e-05,1.4296459960760899e-05,1.4276269531432462e-05,1.4292041015995238e-05],"warmups":[[8192,1.4432275390774407e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148589","date":"2026-08-08 04:18:40.117046","duration":0.836178600002313,"mem_peak_pagefile_usage":39702528,"uptime":25137.98480463028},"values":[1.4018249511860148e-05,1.447009277377731e-05,1.419492187526572e-05,1.4204138183426807e-05,1.4188647460944281e-05,1.426876220689266e-05],"warmups":[[8192,1.4102880859123701e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142562","date":"2026-08-08 04:18:41.197554","duration":0.8422516999999061,"mem_peak_pagefile_usage":38785024,"uptime":25139.07169032097},"values":[1.4264477538716847e-05,1.4660522460907544e-05,1.4207116699083144e-05,1.4220812988519071e-05,1.4193872070134006e-05,1.4274670410152623e-05],"warmups":[[8192,1.4351696777659129e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139546","date":"2026-08-08 04:18:42.283643","duration":0.8667610000011337,"mem_peak_pagefile_usage":39026688,"uptime":25140.160613298416},"values":[1.4587902832374766e-05,1.4979223633027061e-05,1.4710607910028983e-05,1.4734008789041297e-05,1.4706713867163046e-05,1.4726525878749896e-05],"warmups":[[8192,1.4725244140478821e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147716","date":"2026-08-08 04:18:43.369893","duration":0.8455190000022412,"mem_peak_pagefile_usage":38641664,"uptime":25141.23872566223},"values":[1.4195629882696181e-05,1.4610180663954253e-05,1.4371118163936103e-05,1.4393688965164131e-05,1.4365332031474054e-05,1.4364196777361116e-05],"warmups":[[8192,1.4264379882611422e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138068","date":"2026-08-08 04:18:44.427337","duration":0.8382560000027297,"mem_peak_pagefile_usage":40247296,"uptime":25142.3064827919},"values":[1.40502075196558e-05,1.4464184570517347e-05,1.4211315917833645e-05,1.4236816406221209e-05,1.4240246581920246e-05,1.4258776855236022e-05],"warmups":[[8192,1.4152819824087004e-05]]}]},{"metadata":{"loops":4096,"name":"mako/controlled/conditional-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.142464","calibrate_loops":4096,"date":"2026-08-08 04:18:45.962039","duration":1.3035294999972393,"mem_peak_pagefile_usage":39137280,"uptime":25143.83627796173},"warmups":[[1,0.00015970000094966963],[2,8.089999937510584e-05],[4,5.094999960419955e-05],[8,3.7074999909236794e-05],[16,3.745624985640461e-05],[32,3.699999990658398e-05],[64,3.931562503112218e-05],[128,3.81171875005748e-05],[256,4.0262499993559686e-05],[512,3.895039062484784e-05],[1024,3.889511718568883e-05],[2048,3.886337890612879e-05],[4096,3.900603027418015e-05],[4096,3.9008447265231894e-05],[4096,3.9020605468564895e-05],[4096,3.901003417983162e-05],[4096,3.981577148426396e-05],[4096,3.904050293002115e-05],[4096,3.899084472624992e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144223","date":"2026-08-08 04:18:47.320809","duration":1.1373440000024857,"mem_peak_pagefile_usage":39555072,"uptime":25145.193348407745},"values":[3.8658789062395726e-05,3.875043945278378e-05,3.888881835933944e-05,3.887556152371019e-05,3.9681201172037106e-05,3.872373046931443e-05],"warmups":[[4096,3.876328125063111e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151658","date":"2026-08-08 04:18:48.699652","duration":1.163065099997766,"mem_peak_pagefile_usage":39329792,"uptime":25146.565026283264},"values":[3.954177246079382e-05,3.947573242157887e-05,3.947321777353352e-05,3.980563964844919e-05,4.0669824218575457e-05,3.988581543001857e-05],"warmups":[[4096,3.962900390597213e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142533","date":"2026-08-08 04:18:50.080277","duration":1.1638912000016717,"mem_peak_pagefile_usage":39661568,"uptime":25147.954347372055},"values":[3.986970214775454e-05,3.990942382881002e-05,3.983762207049324e-05,3.988220214878879e-05,4.037768554709942e-05,3.930332031298889e-05],"warmups":[[4096,3.9674658203203705e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139670","date":"2026-08-08 04:18:51.434112","duration":1.1366517999995267,"mem_peak_pagefile_usage":39321600,"uptime":25149.31133913994},"values":[3.869396972611128e-05,3.881218261714281e-05,3.8739868164050506e-05,3.880920410193056e-05,3.9535522460276695e-05,3.8765502930360185e-05],"warmups":[[4096,3.870925292925875e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147776","date":"2026-08-08 04:18:52.798255","duration":1.1457406000008632,"mem_peak_pagefile_usage":38944768,"uptime":25150.667177915573},"values":[3.910898437453625e-05,3.90710937505645e-05,3.914680175753915e-05,3.9140624999767226e-05,3.984184570260396e-05,3.889194335915391e-05],"warmups":[[4096,3.915930175768523e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145144","date":"2026-08-08 04:18:54.229786","duration":1.2114756000009947,"mem_peak_pagefile_usage":40243200,"uptime":25152.101697444916},"values":[4.141176757777032e-05,4.136721191372317e-05,4.1320312499593115e-05,4.132448730498339e-05,4.20260498046332e-05,4.1403979492038445e-05],"warmups":[[4096,4.149313964774137e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139097","date":"2026-08-08 04:18:55.579458","duration":1.1320153000015125,"mem_peak_pagefile_usage":39481344,"uptime":25153.457061052322},"values":[3.842548828192349e-05,3.835671386642758e-05,3.841640625079634e-05,3.842604980430764e-05,3.921853027399891e-05,3.8372900391436815e-05],"warmups":[[4096,3.982856445361449e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152273","date":"2026-08-08 04:18:56.948277","duration":1.1513071000008495,"mem_peak_pagefile_usage":39268352,"uptime":25154.812070846558},"values":[3.914765625001593e-05,3.9227783203088507e-05,3.936843261698186e-05,3.937653808616659e-05,4.00552001948995e-05,3.9252661133026834e-05],"warmups":[[4096,3.943154296859319e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139109","date":"2026-08-08 04:18:58.339583","duration":1.1753624000011769,"mem_peak_pagefile_usage":39305216,"uptime":25156.21724176407},"values":[4.1226391600979184e-05,4.119899902299551e-05,3.984624023445349e-05,3.932595214806156e-05,3.996257324256902e-05,3.9033398437027245e-05],"warmups":[[4096,4.0998999024211e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143498","date":"2026-08-08 04:18:59.730627","duration":1.1722532999992836,"mem_peak_pagefile_usage":39428096,"uptime":25157.60400080681},"values":[3.9429052734796244e-05,3.945666503835099e-05,3.950087890647325e-05,3.972670898377828e-05,4.204011230424243e-05,4.1321728515342215e-05],"warmups":[[4096,3.934375000014256e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149688","date":"2026-08-08 04:19:01.092919","duration":1.1445280000007187,"mem_peak_pagefile_usage":40206336,"uptime":25158.959913015366},"values":[3.896801757807822e-05,3.9008032226561795e-05,3.902397460908702e-05,3.8925561523406316e-05,3.980859375030121e-05,3.925249023417621e-05],"warmups":[[4096,3.9075585937631274e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141980","date":"2026-08-08 04:19:02.472821","duration":1.1602841000021726,"mem_peak_pagefile_usage":39616512,"uptime":25160.347250699997},"values":[3.944099121078182e-05,3.95170410163459e-05,3.946159668011262e-05,3.972343750024976e-05,4.0529077148576675e-05,3.959384765650498e-05],"warmups":[[4096,3.9744970703026183e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152710","date":"2026-08-08 04:19:03.887208","duration":1.19708829999945,"mem_peak_pagefile_usage":38748160,"uptime":25161.751579523087},"values":[4.146748046895965e-05,4.1434521484084996e-05,4.1562182617305155e-05,4.0944726562130995e-05,4.0993920898735325e-05,3.932614746027241e-05],"warmups":[[4096,4.1084545898684155e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148077","date":"2026-08-08 04:19:05.288233","duration":1.1829768999996304,"mem_peak_pagefile_usage":39522304,"uptime":25163.15669965744},"values":[4.0437011718630345e-05,4.0464477538471044e-05,4.048662109390477e-05,4.047727050782157e-05,4.111984863275353e-05,4.018249511705818e-05],"warmups":[[4096,4.030354003869974e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144230","date":"2026-08-08 04:19:06.639981","duration":1.1303283999986888,"mem_peak_pagefile_usage":39792640,"uptime":25164.51253604889},"values":[3.8317407226706734e-05,3.8503564453229444e-05,3.851608886673574e-05,3.8532470703067645e-05,3.937863769465366e-05,3.872741699240123e-05],"warmups":[[4096,3.864599609393338e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143980","date":"2026-08-08 04:19:08.012231","duration":1.1573125000031723,"mem_peak_pagefile_usage":39477248,"uptime":25165.884996175766},"values":[3.942194824269052e-05,3.943754882840267e-05,3.943525390592839e-05,3.943176269505244e-05,4.034274902320334e-05,3.964121093691375e-05],"warmups":[[4096,3.95104248047673e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144465","date":"2026-08-08 04:19:09.433619","duration":1.2046543000033125,"mem_peak_pagefile_usage":39301120,"uptime":25167.306144952774},"values":[4.1328222655678815e-05,4.118603515657071e-05,4.122917480486876e-05,4.123215332008101e-05,4.1761206055035416e-05,4.065761718763383e-05],"warmups":[[4096,4.129150390674852e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151500","date":"2026-08-08 04:19:10.798134","duration":1.1460402000011527,"mem_peak_pagefile_usage":39292928,"uptime":25168.662764549255},"values":[3.875952148479911e-05,3.871018066359255e-05,3.990986328084034e-05,3.990036621104309e-05,4.00268310549734e-05,3.829541015587523e-05],"warmups":[[4096,3.9036230468525446e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143943","date":"2026-08-08 04:19:12.240568","duration":1.2252157000002626,"mem_peak_pagefile_usage":39047168,"uptime":25170.113232135773},"values":[4.205024414094538e-05,4.271376953113304e-05,4.281850586007607e-05,4.270046386700699e-05,4.2558764648426006e-05,4.0730346679396234e-05],"warmups":[[4096,4.0301855468882763e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138170","date":"2026-08-08 04:19:13.607800","duration":1.1499752000017907,"mem_peak_pagefile_usage":40169472,"uptime":25171.48615837097},"values":[3.871550292977588e-05,3.8709277343507154e-05,3.923698730456948e-05,3.9260839843180406e-05,3.9997802734781374e-05,3.918913574185723e-05],"warmups":[[4096,3.8814868164038785e-05]]}]},{"metadata":{"loops":256,"name":"mako/controlled/fragment-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.142046","calibrate_loops":256,"date":"2026-08-08 04:19:14.840490","duration":1.0011738000030164,"mem_peak_pagefile_usage":39030784,"uptime":25172.715180158615},"warmups":[[1,0.0007059000017761718],[2,0.0004994999999325955],[4,0.0004968500006725662],[8,0.0004658625002775807],[16,0.0004983687499588996],[32,0.00047580312502759625],[64,0.00047521093750901855],[128,0.0004756757812458545],[256,0.0004765402343736014],[256,0.00047572890625247055],[256,0.00047616249999293814],[256,0.00047567695312977776],[256,0.0004899878906172717],[256,0.000477301953125675],[256,0.00047712578125924665]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138010","date":"2026-08-08 04:19:15.940109","duration":0.8823035999994318,"mem_peak_pagefile_usage":39284736,"uptime":25173.819363355637},"values":[0.00047732695313129625,0.00047786718749875945,0.0004777917968823431,0.00047746093750333785,0.0004914292968720702,0.0004784683593754835],"warmups":[[256,0.00047930312500454875]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139748","date":"2026-08-08 04:19:17.045702","duration":0.8885311999983969,"mem_peak_pagefile_usage":39280640,"uptime":25174.922382593155},"values":[0.00048112265625377404,0.00048180898437522046,0.0004823832031206621,0.00048170546874359843,0.0004937253906120986,0.00048146718749819684],"warmups":[[256,0.0004844894531288446]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149573","date":"2026-08-08 04:19:18.142686","duration":0.8800711000003503,"mem_peak_pagefile_usage":39313408,"uptime":25176.009851694107},"values":[0.0004767632812558986,0.00047723945313293825,0.00047780703124544743,0.0004767234375009366,0.0004889410156181384,0.0004761144531357786],"warmups":[[256,0.0004794097656173335]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153053","date":"2026-08-08 04:19:19.250098","duration":0.8875793000006524,"mem_peak_pagefile_usage":39510016,"uptime":25177.113589286804},"values":[0.00047997070312533197,0.0004807878906234464,0.00048133593750776527,0.0004808984375017644,0.0004945660156323584,0.0004816921875061553],"warmups":[[256,0.0004838125000077298]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143575","date":"2026-08-08 04:19:20.345233","duration":0.8784009999981208,"mem_peak_pagefile_usage":39677952,"uptime":25178.21809077263},"values":[0.0004750531250010681,0.0004765785156308766,0.0004758882812438969,0.0004753335937408565,0.0004893218749941752,0.00047686796875723303],"warmups":[[256,0.0004781996093754515]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138767","date":"2026-08-08 04:19:21.443443","duration":0.8796840999966662,"mem_peak_pagefile_usage":40316928,"uptime":25179.322026014328},"values":[0.00047530468751233457,0.00047616445311859934,0.00047451132812170727,0.00047415742187695287,0.0004908996093746509,0.00047838242188902314],"warmups":[[256,0.0004790421874929507]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148470","date":"2026-08-08 04:19:22.543035","duration":0.8822940999998536,"mem_peak_pagefile_usage":39510016,"uptime":25180.411248207092},"values":[0.0004775832031214122,0.00047744960937734504,0.00047803671874646625,0.00047750429688164786,0.0004921492187577314,0.00047935976563451277],"warmups":[[256,0.0004798164062549404]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147481","date":"2026-08-08 04:19:23.647542","duration":0.8850153999992472,"mem_peak_pagefile_usage":39473152,"uptime":25181.516314983368},"values":[0.0004788789062502019,0.0004790691406242331,0.0004797972656120919,0.00047941875000390155,0.0004927503906202446,0.0004807394531241016],"warmups":[[256,0.00048303242188296736]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147568","date":"2026-08-08 04:19:24.750574","duration":0.8842838999989908,"mem_peak_pagefile_usage":39845888,"uptime":25182.619359731674},"values":[0.0004787085937465463,0.0004794265624923355,0.00047976562500195996,0.00047956835938123277,0.0004917218749938002,0.00047987929687565156],"warmups":[[256,0.00048152890624919564]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140868","date":"2026-08-08 04:19:25.848982","duration":0.8823446000023978,"mem_peak_pagefile_usage":39497728,"uptime":25183.724261283875},"values":[0.00047745859374970223,0.00047873085938476834,0.0004781644531277607,0.00047795507812509186,0.0004919816406356858,0.00047951484374664233],"warmups":[[256,0.0004797699218670459]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153592","date":"2026-08-08 04:19:26.949783","duration":0.8814791000004334,"mem_peak_pagefile_usage":39337984,"uptime":25184.812597990036},"values":[0.0004766417968795622,0.00047772734374973425,0.00047810507811618663,0.0004782261718787595,0.0004920828124994614,0.00047788593749942265],"warmups":[[256,0.0004787066406208851]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149372","date":"2026-08-08 04:19:28.048879","duration":0.8802214999996067,"mem_peak_pagefile_usage":39501824,"uptime":25185.91587662697},"values":[0.0004767468749946602,0.0004768968749999658,0.0004778179687434658,0.0004773910156217198,0.0004899621093699125,0.0004773874999983718],"warmups":[[256,0.00047836289061820025]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143474","date":"2026-08-08 04:19:29.163367","duration":0.8791108999976132,"mem_peak_pagefile_usage":38858752,"uptime":25187.036717891693},"values":[0.00047549453125839136,0.00047595078125084456,0.000476233203130505,0.0004753898437428461,0.0004904449218798845,0.0004773445312480362],"warmups":[[256,0.00047778906250073305]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138811","date":"2026-08-08 04:19:30.262145","duration":0.8827571000001626,"mem_peak_pagefile_usage":38912000,"uptime":25188.139629364014},"values":[0.0004776398437371654,0.0004781027343767619,0.00047873476563609074,0.00047863867186492826,0.000491854296868155,0.0004789535156248803],"warmups":[[256,0.0004806382812461152]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150920","date":"2026-08-08 04:19:31.378422","duration":0.8807405999978073,"mem_peak_pagefile_usage":38825984,"uptime":25189.24400615692},"values":[0.0004765238281265738,0.00047766640625468426,0.0004775867187589711,0.0004771128906213562,0.000491396484378015,0.00047821171874318225],"warmups":[[256,0.00047803320312311826]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150627","date":"2026-08-08 04:19:32.480474","duration":0.8873977000002924,"mem_peak_pagefile_usage":39198720,"uptime":25190.34677863121},"values":[0.000479993750005292,0.00048010429688361,0.000480259765623714,0.000480340234375376,0.0004947402343731255,0.0004822816406289121],"warmups":[[256,0.0004820238281268985]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149359","date":"2026-08-08 04:19:33.583010","duration":0.8818417999973462,"mem_peak_pagefile_usage":38801408,"uptime":25191.450278282166},"values":[0.00047739062500795626,0.00047694882813686945,0.00047740664062700944,0.00047610664061892294,0.0004921031249978114,0.00047976210937861197],"warmups":[[256,0.0004803664062507096]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144598","date":"2026-08-08 04:19:34.681724","duration":0.8816901999998663,"mem_peak_pagefile_usage":39706624,"uptime":25192.553865909576},"values":[0.00047739609375696546,0.00047748750000664586,0.0004781609375044127,0.0004770910156253194,0.0004901351562409673,0.0004785726562488435],"warmups":[[256,0.0004805335937447808]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141062","date":"2026-08-08 04:19:35.782753","duration":0.8818766000003961,"mem_peak_pagefile_usage":39350272,"uptime":25193.658224582672},"values":[0.0004782949218764543,0.00047855898436921507,0.00047887109376176795,0.00047811914062378946,0.0004907906249940197,0.0004781730468863543],"warmups":[[256,0.0004780437500073731]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152375","date":"2026-08-08 04:19:36.882782","duration":0.883794699999271,"mem_peak_pagefile_usage":39407616,"uptime":25194.747148513794},"values":[0.00047810625000010987,0.0004784679687475091,0.0004794066406219599,0.00047897460937917913,0.0004914242187368245,0.0004788964843669419],"warmups":[[256,0.00048136093749917563]]}]},{"metadata":{"loops":16384,"name":"mako/controlled/fortunes-encoded"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.144775","calibrate_loops":16384,"date":"2026-08-08 04:19:38.624302","duration":1.5133332000004884,"mem_peak_pagefile_usage":38944768,"uptime":25196.49603509903},"warmups":[[1,8.1900001532631e-05],[2,3.05499997921288e-05],[4,2.3049999981594738e-05],[8,1.3674999991053483e-05],[16,1.0799999927257886e-05],[32,1.0768749916678644e-05],[64,1.263437502529996e-05],[128,1.0953906269151048e-05],[256,1.2875000010126314e-05],[512,1.1560351559580795e-05],[1024,1.1436230469286102e-05],[2048,1.1372802735110099e-05],[4096,1.1309375000045918e-05],[8192,1.1312548828357194e-05],[16384,1.1518066406424055e-05],[16384,1.1344915771482889e-05],[16384,1.13458984374315e-05],[16384,1.1342327880914382e-05],[16384,1.1361151123212565e-05],[16384,1.1391455078113566e-05],[16384,1.1372009277366146e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144645","date":"2026-08-08 04:19:40.169502","duration":1.3243307000011555,"mem_peak_pagefile_usage":39567360,"uptime":25198.04121685028},"values":[1.1493652343652627e-05,1.1321722412027668e-05,1.1329284667960238e-05,1.1321362304750338e-05,1.1336737060441138e-05,1.1354040527322695e-05],"warmups":[[16384,1.1363690185728359e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146718","date":"2026-08-08 04:19:41.715871","duration":1.331296199998178,"mem_peak_pagefile_usage":39043072,"uptime":25199.58616089821},"values":[1.1440240478499675e-05,1.1330773925788407e-05,1.1364117431522658e-05,1.1471545410035588e-05,1.1492529296885934e-05,1.1393572997953072e-05],"warmups":[[16384,1.1412542724631436e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138456","date":"2026-08-08 04:19:43.252080","duration":1.3181683000002522,"mem_peak_pagefile_usage":39829504,"uptime":25201.130562067032},"values":[1.1467395019559845e-05,1.1257446289159034e-05,1.1264031982483047e-05,1.1252770996117434e-05,1.124929809570574e-05,1.1266296386702734e-05],"warmups":[[16384,1.134333496088935e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141693","date":"2026-08-08 04:19:44.800875","duration":1.3293047000006482,"mem_peak_pagefile_usage":39333888,"uptime":25202.675566911697},"values":[1.1532891845744686e-05,1.1365185546896583e-05,1.1382171630769378e-05,1.139328613275481e-05,1.1375311279149258e-05,1.1420562744168805e-05],"warmups":[[16384,1.1352429199140701e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146791","date":"2026-08-08 04:19:46.336427","duration":1.3181121000015992,"mem_peak_pagefile_usage":39190528,"uptime":25204.20560145378},"values":[1.1426159667982105e-05,1.130733642584758e-05,1.125046386718509e-05,1.1281884765512729e-05,1.1258380127054934e-05,1.1278338623021966e-05],"warmups":[[16384,1.1367016601537827e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151600","date":"2026-08-08 04:19:47.887105","duration":1.3343322000000626,"mem_peak_pagefile_usage":39202816,"uptime":25205.752466201782},"values":[1.1577679443375288e-05,1.140412597666618e-05,1.140889892559116e-05,1.1418664550788549e-05,1.140690917966758e-05,1.1413024902262592e-05],"warmups":[[16384,1.1468072509845939e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151510","date":"2026-08-08 04:19:49.431589","duration":1.3272641000003205,"mem_peak_pagefile_usage":40390656,"uptime":25207.296937942505},"values":[1.154895629884578e-05,1.1355529785372909e-05,1.1349645996139301e-05,1.1348394775234638e-05,1.135626220705177e-05,1.1367962646557928e-05],"warmups":[[16384,1.1342303466665982e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150367","date":"2026-08-08 04:19:50.992248","duration":1.3223309999993944,"mem_peak_pagefile_usage":39206912,"uptime":25208.85814356804},"values":[1.1478051757940477e-05,1.1311895752097456e-05,1.1303948974639155e-05,1.1304644775389505e-05,1.129611206041048e-05,1.130545043936948e-05],"warmups":[[16384,1.1404449463014998e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147267","date":"2026-08-08 04:19:52.534080","duration":1.3220665999979246,"mem_peak_pagefile_usage":39481344,"uptime":25210.40298461914},"values":[1.145832519533485e-05,1.1351556396421714e-05,1.136358032227669e-05,1.1363598632740946e-05,1.1358795166005464e-05,1.1365313720590464e-05],"warmups":[[16384,1.113569946276094e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146975","date":"2026-08-08 04:19:54.079795","duration":1.327629799998249,"mem_peak_pagefile_usage":39387136,"uptime":25211.948848724365},"values":[1.1543560791027474e-05,1.1372363281303421e-05,1.1383435058576197e-05,1.138117065435651e-05,1.1362097168010621e-05,1.1373077392518027e-05],"warmups":[[16384,1.1331787109325475e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138778","date":"2026-08-08 04:19:55.632112","duration":1.3345005999981367,"mem_peak_pagefile_usage":39571456,"uptime":25213.509984970093},"values":[1.1619122314510122e-05,1.1373950195237015e-05,1.1393695068306897e-05,1.1412835693391798e-05,1.1417309570438405e-05,1.1444641113467213e-05],"warmups":[[16384,1.1457464599740064e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138105","date":"2026-08-08 04:19:57.164102","duration":1.316855500001111,"mem_peak_pagefile_usage":39559168,"uptime":25215.042452812195},"values":[1.1419281005675685e-05,1.126187744127094e-05,1.1281256103501391e-05,1.1280084228459941e-05,1.128751220713653e-05,1.1315478515738775e-05],"warmups":[[16384,1.121189575203907e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151083","date":"2026-08-08 04:19:58.709788","duration":1.3247152000003553,"mem_peak_pagefile_usage":40341504,"uptime":25216.57509827614},"values":[1.1473944091955346e-05,1.128027954111488e-05,1.1304266357425874e-05,1.1396228027482636e-05,1.1363366699157496e-05,1.137033081044514e-05],"warmups":[[16384,1.1343505859517933e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139110","date":"2026-08-08 04:20:00.246446","duration":1.3155322999991768,"mem_peak_pagefile_usage":39522304,"uptime":25218.123058080673},"values":[1.142230224604468e-05,1.1264709472547096e-05,1.1269793701140784e-05,1.1270550537068047e-05,1.1253222656160133e-05,1.1261645507909535e-05],"warmups":[[16384,1.1257940673692346e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150252","date":"2026-08-08 04:20:01.790210","duration":1.327048700000887,"mem_peak_pagefile_usage":39477248,"uptime":25219.656024217606},"values":[1.150092773416489e-05,1.1366455078043458e-05,1.1367578125032196e-05,1.1425158691347193e-05,1.1384497070165978e-05,1.1395123290958153e-05],"warmups":[[16384,1.1253930664034684e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144401","date":"2026-08-08 04:20:03.333502","duration":1.322843699999794,"mem_peak_pagefile_usage":39272448,"uptime":25221.205806732178},"values":[1.1499230957001672e-05,1.1305297851649243e-05,1.130404663074458e-05,1.1309942626880343e-05,1.1309118652436112e-05,1.1320184326146787e-05],"warmups":[[16384,1.1351965331973801e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151585","date":"2026-08-08 04:20:04.872772","duration":1.3227422999989358,"mem_peak_pagefile_usage":39559168,"uptime":25222.73759818077},"values":[1.152670898441066e-05,1.130742797861295e-05,1.131104736318278e-05,1.1312689209175275e-05,1.1311279296988275e-05,1.1350451660119276e-05],"warmups":[[16384,1.1304125976607793e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146587","date":"2026-08-08 04:20:06.412838","duration":1.3231918000019505,"mem_peak_pagefile_usage":39337984,"uptime":25224.283024549484},"values":[1.1497747802735603e-05,1.1290045166090223e-05,1.1303710937493605e-05,1.134157714854922e-05,1.1323834228527119e-05,1.1340045166008395e-05],"warmups":[[16384,1.1329650879021713e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145860","date":"2026-08-08 04:20:07.958974","duration":1.3281652999976359,"mem_peak_pagefile_usage":39649280,"uptime":25225.829726934433},"values":[1.1502691650289165e-05,1.1390979003822466e-05,1.1401348877004835e-05,1.1387390136619047e-05,1.1382678222648934e-05,1.1390545654244022e-05],"warmups":[[16384,1.1278015136673147e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139168","date":"2026-08-08 04:20:09.498870","duration":1.323028399998293,"mem_peak_pagefile_usage":39108608,"uptime":25227.376655340195},"values":[1.1508447265606847e-05,1.131816406263475e-05,1.1314038085963318e-05,1.1315649413923268e-05,1.1311505127009625e-05,1.1329980468710588e-05],"warmups":[[16384,1.1311322021478887e-05]]}]},{"metadata":{"loops":32,"name":"mako/controlled/encoded-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.146981","calibrate_loops":32,"date":"2026-08-08 04:20:11.019985","duration":1.2897533999966981,"mem_peak_pagefile_usage":39378944,"uptime":25228.88996696472},"warmups":[[1,0.005661099999997532],[2,0.00471070000094187],[4,0.004736399999273999],[8,0.005127125000399246],[16,0.004762531249980384],[32,0.004963949999932993],[32,0.004979390625067026],[32,0.004902700000002369],[32,0.005041518749976603],[32,0.005024478124937559],[32,0.005036418749909899],[32,0.0049313406250348635]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146032","date":"2026-08-08 04:20:12.373972","duration":1.1324342999978398,"mem_peak_pagefile_usage":39280640,"uptime":25230.244950294495},"values":[0.004989662500065606,0.004986918749978031,0.004983909375027906,0.004862781250039916,0.004960946875030459,0.004938684375019875],"warmups":[[32,0.00496429687507316]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144152","date":"2026-08-08 04:20:13.743600","duration":1.151910599997791,"mem_peak_pagefile_usage":39284736,"uptime":25231.616816043854},"values":[0.005049565624972274,0.005059724999910031,0.00505341562495687,0.004954953124979511,0.005040856250047909,0.005051009375051763],"warmups":[[32,0.004953746875003162]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149639","date":"2026-08-08 04:20:15.122561","duration":1.140024700001959,"mem_peak_pagefile_usage":38637568,"uptime":25232.990127563477},"values":[0.004971121874973505,0.005026187499993284,0.005031812499964872,0.004943953125007283,0.005031271874941012,0.0050182093750663626],"warmups":[[32,0.004900065625065508]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140790","date":"2026-08-08 04:20:16.500369","duration":1.1415416999989247,"mem_peak_pagefile_usage":39731200,"uptime":25234.379513263702},"values":[0.005005268749982861,0.004984103125025285,0.005022721875093339,0.004902078125041953,0.005039990624936763,0.00500747812498048],"warmups":[[32,0.004922881249967759]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145270","date":"2026-08-08 04:20:17.849560","duration":1.1283034999978554,"mem_peak_pagefile_usage":39333888,"uptime":25235.721069574356},"values":[0.004939718749938038,0.0049285874999895896,0.00494979375002913,0.004865468749926549,0.004978775000040514,0.00502450625003803],"warmups":[[32,0.004883565624936637]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137962","date":"2026-08-08 04:20:19.213874","duration":1.1454779999985476,"mem_peak_pagefile_usage":40120320,"uptime":25237.09344267845},"values":[0.0049915187499891545,0.005041715624997778,0.005045984375101398,0.004967462499962494,0.005065224999952989,0.0050618093749790205],"warmups":[[32,0.004908696875077112]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147850","date":"2026-08-08 04:20:20.580626","duration":1.1441081999982998,"mem_peak_pagefile_usage":39452672,"uptime":25238.449488162994},"values":[0.005012387500073601,0.005012824999994336,0.005040968749995045,0.004924956249965362,0.005036990625058024,0.005073621874998935],"warmups":[[32,0.004966181250097179]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145944","date":"2026-08-08 04:20:21.937145","duration":1.140181799997663,"mem_peak_pagefile_usage":39378944,"uptime":25239.80758333206},"values":[0.005016931249997469,0.0050231781250431595,0.005043893749984818,0.004913368750067093,0.005012650000026042,0.005036853125034213],"warmups":[[32,0.004910290625048219]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152397","date":"2026-08-08 04:20:23.299376","duration":1.1418822000014188,"mem_peak_pagefile_usage":39288832,"uptime":25241.16424870491},"values":[0.005001181250008813,0.005007512500014855,0.005003009375059264,0.004923431249949317,0.0050249812500169355,0.0050605625000343935],"warmups":[[32,0.0049551906250826505]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153553","date":"2026-08-08 04:20:24.673416","duration":1.1558432999991055,"mem_peak_pagefile_usage":39391232,"uptime":25242.53709602356},"values":[0.005010106250097124,0.005001368750072288,0.005032203124983425,0.005062437500100714,0.005216534374994808,0.005148346875103016],"warmups":[[32,0.004940493750041242]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150870","date":"2026-08-08 04:20:26.042370","duration":1.1306332999993174,"mem_peak_pagefile_usage":38916096,"uptime":25243.908941745758},"values":[0.004948671875013133,0.004963856250014942,0.004970906250036933,0.004868240625000908,0.004991784374965391,0.004994468750055603],"warmups":[[32,0.004882787500037011]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145952","date":"2026-08-08 04:20:27.409968","duration":1.1486632000014652,"mem_peak_pagefile_usage":39571456,"uptime":25245.280983924866},"values":[0.005025465625067227,0.005015328124954976,0.0050824937500237866,0.004965509374983412,0.005075887500083809,0.005082921874986823],"warmups":[[32,0.004953824999915923]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140476","date":"2026-08-08 04:20:28.761549","duration":1.131797000001825,"mem_peak_pagefile_usage":39731200,"uptime":25246.6376786232},"values":[0.004962400000067646,0.004955637499961085,0.004939331250056966,0.004944237499898918,0.004985337499988418,0.004959584375001214],"warmups":[[32,0.004935243749969231]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138403","date":"2026-08-08 04:20:30.116935","duration":1.1385990000017046,"mem_peak_pagefile_usage":39305216,"uptime":25247.995737552643},"values":[0.004986446875022921,0.0050068062499804,0.0050057749999723455,0.004915068750051432,0.005024696875011614,0.005019468749992484],"warmups":[[32,0.00491514062503029]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139777","date":"2026-08-08 04:20:31.474421","duration":1.1377476000016031,"mem_peak_pagefile_usage":39583744,"uptime":25249.351575613022},"values":[0.005002534375080359,0.0049718718750000335,0.004984359375043823,0.0048838437500080545,0.005030475000012302,0.0050393906250292275],"warmups":[[32,0.004950725000071543]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138076","date":"2026-08-08 04:20:32.844755","duration":1.1526694000021962,"mem_peak_pagefile_usage":39571456,"uptime":25250.724146842957},"values":[0.00508672499995555,0.005064115624918486,0.005114512499972079,0.004975221875042735,0.005108915624987276,0.0050328843749412044],"warmups":[[32,0.004926481249981407]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145878","date":"2026-08-08 04:20:34.193637","duration":1.131235699998797,"mem_peak_pagefile_usage":39260160,"uptime":25252.065193653107},"values":[0.004978803125027298,0.004982153124956312,0.004987990624954364,0.004872034374898249,0.004965634374912042,0.004952609375095562],"warmups":[[32,0.00490816874992106]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139395","date":"2026-08-08 04:20:35.561612","duration":1.1476393999982974,"mem_peak_pagefile_usage":39256064,"uptime":25253.439319610596},"values":[0.005035603125065791,0.00502764374994058,0.005065753124995354,0.004977762500061544,0.005084024999973735,0.005077237500017873],"warmups":[[32,0.004896987499932948]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148402","date":"2026-08-08 04:20:36.929770","duration":1.1505268000000797,"mem_peak_pagefile_usage":39559168,"uptime":25254.799111127853},"values":[0.005118953125020198,0.00512969375006378,0.005000912500008781,0.00488434062503984,0.005119128124988492,0.004992878124994604],"warmups":[[32,0.00499087187506575]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150899","date":"2026-08-08 04:20:38.287987","duration":1.1393407999967167,"mem_peak_pagefile_usage":39628800,"uptime":25256.154585838318},"values":[0.004998353124960886,0.005014231250015655,0.005012884375105386,0.0049396187499723965,0.005009884374999274,0.005010768749912131],"warmups":[[32,0.004909756249958264]]}]}],"metadata":{"cpu_affinity":"4","cpu_count":32,"hostname":"DESKTOP-F5QFSMS","perf_version":"2.10.0","platform":"Windows-11-10.0.26200-SP0","python_compiler":"MSC v.1944 64 bit (AMD64)","python_executable":"E:\\Work\\Heddle\\benchmarks\\python\\.venv\\Scripts\\python.exe","python_implementation":"cpython","python_version":"3.14.7 (64-bit) revision 823f032","timer":"QueryPerformanceCounter(), resolution: 100 ns","unit":"second"},"version":"1.0"} diff --git a/docs/benchmarks/2026-08-08/python/bench_mako_idiomatic.json b/docs/benchmarks/2026-08-08/python/bench_mako_idiomatic.json new file mode 100644 index 00000000..0755a8b6 --- /dev/null +++ b/docs/benchmarks/2026-08-08/python/bench_mako_idiomatic.json @@ -0,0 +1 @@ +{"benchmarks":[{"metadata":{"loops":8192,"name":"mako/idiomatic/composed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.148188","calibrate_loops":8192,"date":"2026-08-08 04:20:39.945889","duration":1.1780990000006568,"mem_peak_pagefile_usage":35999744,"uptime":25257.81440973282},"warmups":[[1,0.00017160000061267056],[2,5.484999928739853e-05],[4,3.7450000490935054e-05],[8,3.248749999329448e-05],[16,2.6606250003169407e-05],[32,2.1415625042209285e-05],[64,1.7232812524525798e-05],[128,2.113906251111075e-05],[256,1.7845703126795343e-05],[512,1.7656054687620326e-05],[1024,1.786621093557983e-05],[2048,1.7838037109640936e-05],[4096,1.785720214808606e-05],[8192,1.8168566894516402e-05],[8192,1.7708874511690453e-05],[8192,1.76666137692294e-05],[8192,1.7765087890975195e-05],[8192,1.7790698242148295e-05],[8192,1.7196960449439302e-05],[8192,1.6897106933644324e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150982","date":"2026-08-08 04:20:41.189749","duration":0.9983534000020882,"mem_peak_pagefile_usage":36073472,"uptime":25259.055480718613},"values":[1.773065185517453e-05,1.6743090820448003e-05,1.675069580064914e-05,1.6709497070444e-05,1.6693786621058138e-05,1.6731494140831416e-05],"warmups":[[8192,1.786231689449025e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146662","date":"2026-08-08 04:20:42.431430","duration":1.020496600001934,"mem_peak_pagefile_usage":36937728,"uptime":25260.301159381866},"values":[1.8299060058346583e-05,1.7056481933508394e-05,1.709644775393926e-05,1.709154052731421e-05,1.707364501957187e-05,1.7075183105674796e-05],"warmups":[[8192,1.8278381347602846e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152030","date":"2026-08-08 04:20:43.650446","duration":0.9959993000011309,"mem_peak_pagefile_usage":35962880,"uptime":25261.514832496643},"values":[1.7270861816243155e-05,1.6685961913953662e-05,1.6746179199333966e-05,1.6739855956959815e-05,1.668078613281665e-05,1.6729089355571602e-05],"warmups":[[8192,1.8129858398108212e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145572","date":"2026-08-08 04:20:44.888428","duration":1.0154353999969317,"mem_peak_pagefile_usage":36614144,"uptime":25262.759258031845},"values":[1.8337548828295525e-05,1.7331176757728883e-05,1.6866198730536297e-05,1.688978271463526e-05,1.690776367180291e-05,1.69603881832181e-05],"warmups":[[8192,1.807113037122221e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151459","date":"2026-08-08 04:20:46.109558","duration":1.0005371000006562,"mem_peak_pagefile_usage":36610048,"uptime":25263.974427461624},"values":[1.799632568344478e-05,1.6781274414068292e-05,1.6779748535089567e-05,1.6757763671826353e-05,1.6754516601658054e-05,1.676186523447143e-05],"warmups":[[8192,1.7712231445532467e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140157","date":"2026-08-08 04:20:47.361436","duration":1.0279719999998633,"mem_peak_pagefile_usage":36585472,"uptime":25265.237565755844},"values":[1.7933715820372953e-05,1.7523913574457595e-05,1.745413818321495e-05,1.7426049804480925e-05,1.7457678222587703e-05,1.7455883789097015e-05],"warmups":[[8192,1.7634875488337087e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142175","date":"2026-08-08 04:20:48.610024","duration":1.0033144999979413,"mem_peak_pagefile_usage":36089856,"uptime":25266.483887672424},"values":[1.810211181618726e-05,1.7136657714633685e-05,1.6758996582044716e-05,1.671572265626864e-05,1.67197265623642e-05,1.678094482393533e-05],"warmups":[[8192,1.7685852050863815e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142415","date":"2026-08-08 04:20:49.888213","duration":1.05499360000249,"mem_peak_pagefile_usage":36712448,"uptime":25267.762671470642},"values":[1.8347497558579562e-05,1.7914733887014478e-05,1.7953308105500554e-05,1.791175537091405e-05,1.796417236343828e-05,1.7934179687539853e-05],"warmups":[[8192,1.8067297363533186e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150433","date":"2026-08-08 04:20:51.157345","duration":1.0465297000009741,"mem_peak_pagefile_usage":36855808,"uptime":25269.023688077927},"values":[1.8145617675546788e-05,1.775679931625973e-05,1.7767163086102045e-05,1.784627685541551e-05,1.7829553222714623e-05,1.7835119628717422e-05],"warmups":[[8192,1.7923095703142877e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141293","date":"2026-08-08 04:20:52.408202","duration":1.0291117999986454,"mem_peak_pagefile_usage":36311040,"uptime":25270.283649683},"values":[1.8312158203137585e-05,1.7952416992095266e-05,1.7826965331924072e-05,1.6889660644281435e-05,1.6872460937733536e-05,1.6856567382816934e-05],"warmups":[[8192,1.8223864746147456e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137895","date":"2026-08-08 04:20:53.635592","duration":1.0011029999986931,"mem_peak_pagefile_usage":37232640,"uptime":25271.51451730728},"values":[1.802379150372957e-05,1.7035021972588993e-05,1.6666064452941498e-05,1.665518798832366e-05,1.668146972688689e-05,1.6686572265722788e-05],"warmups":[[8192,1.7782360840268296e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148370","date":"2026-08-08 04:20:54.908854","duration":1.0453409000001557,"mem_peak_pagefile_usage":36347904,"uptime":25272.77715063095},"values":[1.8220629882659267e-05,1.7742651366781104e-05,1.773353271516953e-05,1.7755664062146792e-05,1.778542480490586e-05,1.7763012694960167e-05],"warmups":[[8192,1.794737548843628e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147474","date":"2026-08-08 04:20:56.155275","duration":0.998894599997584,"mem_peak_pagefile_usage":37261312,"uptime":25274.024013757706},"values":[1.7332897948918458e-05,1.6991430663804152e-05,1.69557617186733e-05,1.69380004879649e-05,1.695130615253504e-05,1.6973059081770714e-05],"warmups":[[8192,1.719829101576309e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142868","date":"2026-08-08 04:20:57.427984","duration":1.052794699997321,"mem_peak_pagefile_usage":36605952,"uptime":25275.301746606827},"values":[1.833720703148245e-05,1.7930554199185877e-05,1.7994592285575095e-05,1.7946276855695942e-05,1.7919567871338415e-05,1.778566894561351e-05],"warmups":[[8192,1.7976440429556817e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148396","date":"2026-08-08 04:20:58.715531","duration":1.0665091999981087,"mem_peak_pagefile_usage":36605952,"uptime":25276.583879709244},"values":[1.8541430663709946e-05,1.8097509765446773e-05,1.815451660158729e-05,1.81195556638869e-05,1.815729980458869e-05,1.8166931152308052e-05],"warmups":[[8192,1.827822265632051e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150453","date":"2026-08-08 04:21:00.024575","duration":1.082437299999583,"mem_peak_pagefile_usage":36425728,"uptime":25277.88942503929},"values":[1.8874389648537715e-05,1.843530273415439e-05,1.8447326660453456e-05,1.8437548828131867e-05,1.8397045898677078e-05,1.843555908198624e-05],"warmups":[[8192,1.8593164062163936e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150757","date":"2026-08-08 04:21:01.255428","duration":1.0085368000000017,"mem_peak_pagefile_usage":35921920,"uptime":25279.12110710144},"values":[1.7476611328337555e-05,1.692424316379615e-05,1.6971923828101865e-05,1.698491210966324e-05,1.7009143066459842e-05,1.6993981933222102e-05],"warmups":[[8192,1.814890136708769e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138520","date":"2026-08-08 04:21:02.474572","duration":0.9897774999990361,"mem_peak_pagefile_usage":37797888,"uptime":25280.353134155273},"values":[1.730969238300517e-05,1.6789904785152743e-05,1.6833044433450794e-05,1.6749914550473477e-05,1.6736096191127814e-05,1.677425537138788e-05],"warmups":[[8192,1.6949780273556314e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140567","date":"2026-08-08 04:21:03.738726","duration":1.043824600001244,"mem_peak_pagefile_usage":36151296,"uptime":25281.614980220795},"values":[1.817294921879764e-05,1.7803710937513983e-05,1.7748803710748717e-05,1.7686108398251577e-05,1.777891845700097e-05,1.777753906262447e-05],"warmups":[[8192,1.7791906738562346e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148233","date":"2026-08-08 04:21:05.012366","duration":1.0498824999995122,"mem_peak_pagefile_usage":36847616,"uptime":25282.88086438179},"values":[1.8278649902114807e-05,1.7822399902556185e-05,1.7859887695426124e-05,1.779730224615861e-05,1.7888989257475174e-05,1.7883190917888925e-05],"warmups":[[8192,1.8005981445412544e-05]]}]},{"metadata":{"loops":32768,"name":"mako/idiomatic/trivial-substitution"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.146602","calibrate_loops":32768,"date":"2026-08-08 04:21:06.743730","duration":1.504544799998257,"mem_peak_pagefile_usage":36687872,"uptime":25284.613490343094},"warmups":[[1,5.450000026030466e-05],[2,1.7950000255950727e-05],[4,1.2524999874585774e-05],[8,1.0437499895488145e-05],[16,1.0168750122829806e-05],[32,1.0196874995926919e-05],[64,6.595312527224451e-06],[128,5.159375007224298e-06],[256,6.904687495534745e-06],[512,5.666406252657907e-06],[1024,5.511621093745589e-06],[2048,5.582763671796442e-06],[4096,5.605029297583997e-06],[8192,5.608288574432407e-06],[16384,5.79788818355631e-06],[32768,5.6419860839929115e-06],[32768,5.645281982435968e-06],[32768,5.660723876976803e-06],[32768,5.642083740209358e-06],[32768,5.655468749976578e-06],[32768,5.64782409662179e-06],[32768,5.645660400399599e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142486","date":"2026-08-08 04:21:08.268468","duration":1.299257700000453,"mem_peak_pagefile_usage":36257792,"uptime":25286.142830848694},"values":[5.550561523404163e-06,5.55555725090251e-06,5.56809082030707e-06,5.5732727050061825e-06,5.556915283255748e-06,5.555239868115791e-06],"warmups":[[32768,5.613912963831069e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147942","date":"2026-08-08 04:21:09.807190","duration":1.3165775000015856,"mem_peak_pagefile_usage":36397056,"uptime":25287.67609190941},"values":[5.631771850533873e-06,5.635891723643205e-06,5.63367309569518e-06,5.626663208024851e-06,5.626647949230623e-06,5.62884826660337e-06],"warmups":[[32768,5.724591064404372e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139487","date":"2026-08-08 04:21:11.388973","duration":1.3339639000005263,"mem_peak_pagefile_usage":36356096,"uptime":25289.266000032425},"values":[5.698007202181721e-06,5.724578857502216e-06,5.709005737375428e-06,5.700369262728877e-06,5.706295776453096e-06,5.7218719482499125e-06],"warmups":[[32768,5.786676025354431e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147839","date":"2026-08-08 04:21:12.930261","duration":1.3169306000017968,"mem_peak_pagefile_usage":36442112,"uptime":25290.798688411713},"values":[5.640234374992836e-06,5.637832641514073e-06,5.647344970771684e-06,5.647222900306836e-06,5.644497680590277e-06,5.639196777318389e-06],"warmups":[[32768,5.680078124958854e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150260","date":"2026-08-08 04:21:14.474832","duration":1.3218230999991647,"mem_peak_pagefile_usage":36229120,"uptime":25292.34131669998},"values":[5.624679565441326e-06,5.6333068847447265e-06,5.638815307573708e-06,5.656771850603981e-06,5.643148803691211e-06,5.652273559531018e-06],"warmups":[[32768,5.705841064407302e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145475","date":"2026-08-08 04:21:16.031537","duration":1.334290400001919,"mem_peak_pagefile_usage":35983360,"uptime":25293.90321135521},"values":[5.714840698334278e-06,5.715429687525031e-06,5.716955566392734e-06,5.715423583962931e-06,5.709790039110096e-06,5.712530517509862e-06],"warmups":[[32768,5.754769897503564e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145509","date":"2026-08-08 04:21:17.560898","duration":1.3074837999993179,"mem_peak_pagefile_usage":36413440,"uptime":25295.432224035263},"values":[5.58684082030414e-06,5.602200317422756e-06,5.610839843739335e-06,5.608020019587379e-06,5.5986389160267436e-06,5.601892089868166e-06],"warmups":[[32768,5.625955200150301e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141314","date":"2026-08-08 04:21:19.100206","duration":1.3140183000032266,"mem_peak_pagefile_usage":36864000,"uptime":25296.97552227974},"values":[5.6142944335757505e-06,5.605850219692066e-06,5.623773193352832e-06,5.6163665771435944e-06,5.638180542000271e-06,5.622515869108113e-06],"warmups":[[32768,5.713156127962193e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138851","date":"2026-08-08 04:21:20.658379","duration":1.3357993000026909,"mem_peak_pagefile_usage":36376576,"uptime":25298.536174058914},"values":[5.726730346600206e-06,5.711553955012327e-06,5.707397460974484e-06,5.711053466805893e-06,5.710546875037359e-06,5.706076049771802e-06],"warmups":[[32768,5.82869262688579e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138172","date":"2026-08-08 04:21:22.202828","duration":1.3219873000016378,"mem_peak_pagefile_usage":36995072,"uptime":25300.080923318863},"values":[5.637124633750545e-06,5.643896484386346e-06,5.652947998147084e-06,5.664862060550391e-06,5.672232055609072e-06,5.678991699231695e-06],"warmups":[[32768,5.739794921799657e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149564","date":"2026-08-08 04:21:23.743347","duration":1.3176060000005236,"mem_peak_pagefile_usage":36454400,"uptime":25301.61060667038},"values":[5.634619140604258e-06,5.619314575211476e-06,5.629516601546314e-06,5.640765380787727e-06,5.644970703100327e-06,5.6612884521412e-06],"warmups":[[32768,5.708514404290099e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141975","date":"2026-08-08 04:21:25.296339","duration":1.3068870000024617,"mem_peak_pagefile_usage":36253696,"uptime":25303.17081427574},"values":[5.598779296844825e-06,5.578897094737911e-06,5.5856689452626895e-06,5.58847351073144e-06,5.5884338379108556e-06,5.58760986324458e-06],"warmups":[[32768,5.690664672819423e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139029","date":"2026-08-08 04:21:26.821072","duration":1.301915200001531,"mem_peak_pagefile_usage":36478976,"uptime":25304.699019432068},"values":[5.57322692873452e-06,5.567361450187214e-06,5.567166137643298e-06,5.5648895264104326e-06,5.566485595687176e-06,5.566281128022155e-06],"warmups":[[32768,5.6502258301005526e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146672","date":"2026-08-08 04:21:28.359130","duration":1.3175654000006034,"mem_peak_pagefile_usage":36511744,"uptime":25306.228633642197},"values":[5.6289001464371324e-06,5.622354125933704e-06,5.63693542476873e-06,5.653814697192949e-06,5.644006347615971e-06,5.643908691399524e-06],"warmups":[[32768,5.72710876467486e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137941","date":"2026-08-08 04:21:29.912037","duration":1.3299213999998756,"mem_peak_pagefile_usage":36106240,"uptime":25307.790714740753},"values":[5.675985717767951e-06,5.705236816422321e-06,5.699179077223171e-06,5.708468627907415e-06,5.686309814456614e-06,5.693011474683374e-06],"warmups":[[32768,5.756710815485455e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138469","date":"2026-08-08 04:21:31.442088","duration":1.3092100000030769,"mem_peak_pagefile_usage":36491264,"uptime":25309.320194005966},"values":[5.6073028564807e-06,5.605001830999434e-06,5.599652099563812e-06,5.601727294912706e-06,5.601287841772162e-06,5.595529174784453e-06],"warmups":[[32768,5.682797241113313e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140930","date":"2026-08-08 04:21:33.003376","duration":1.3345618000021204,"mem_peak_pagefile_usage":37064704,"uptime":25310.87891316414},"values":[5.70561828605598e-06,5.712301635707462e-06,5.720681762744206e-06,5.714544677681843e-06,5.7178192138795936e-06,5.718011474642459e-06],"warmups":[[32768,5.777261352535312e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143206","date":"2026-08-08 04:21:34.534562","duration":1.3105995999976585,"mem_peak_pagefile_usage":36462592,"uptime":25312.408320903778},"values":[5.59890136719865e-06,5.610641479525391e-06,5.608782958965719e-06,5.609771728587454e-06,5.603341674764728e-06,5.606488037157575e-06],"warmups":[[32768,5.680899047844079e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141632","date":"2026-08-08 04:21:36.066320","duration":1.3120894999992743,"mem_peak_pagefile_usage":36102144,"uptime":25313.941281557083},"values":[5.589520263749037e-06,5.611059570309607e-06,5.6156585693800665e-06,5.622332763688398e-06,5.621478271433666e-06,5.629409789986717e-06],"warmups":[[32768,5.6877624512452485e-06]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153098","date":"2026-08-08 04:21:37.607749","duration":1.3215504999971017,"mem_peak_pagefile_usage":36831232,"uptime":25315.47098016739},"values":[5.633547973671327e-06,5.639779663169087e-06,5.648239135735977e-06,5.660275268604131e-06,5.674148559564607e-06,5.699282836890696e-06],"warmups":[[32768,5.719497680689578e-06]]}]},{"metadata":{"loops":256,"name":"mako/idiomatic/large-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.141030","calibrate_loops":256,"date":"2026-08-08 04:21:39.046432","duration":1.2048149000002013,"mem_peak_pagefile_usage":36384768,"uptime":25316.921853780746},"warmups":[[1,0.0012084999980288558],[2,0.0006560000001627486],[4,0.0006624249999731546],[8,0.0006653625000581087],[16,0.0006755375000011554],[32,0.000671984375003376],[64,0.0006193265625142885],[128,0.0005592781250243206],[256,0.0005730070312495172],[256,0.0005723921874931648],[256,0.000572380078125434],[256,0.0005748964843803606],[256,0.000575395312495175],[256,0.0005754171875054226],[256,0.0005759757812597854]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144505","date":"2026-08-08 04:21:40.311917","duration":1.0390508999989834,"mem_peak_pagefile_usage":36536320,"uptime":25318.18373441696},"values":[0.0005651589843722604,0.0005667320312454649,0.0005693339843872991,0.0005705343750008751,0.0005715253906259932,0.0005710945312387139],"warmups":[[256,0.0005599968750118478]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138418","date":"2026-08-08 04:21:41.582711","duration":1.0512099000006856,"mem_peak_pagefile_usage":36515840,"uptime":25319.46094894409},"values":[0.0005718195312596208,0.0005925128906199006,0.0005724015624934964,0.0005719828125023696,0.0005724863281386661,0.0005718269531200804],"warmups":[[256,0.0005676597656218973]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147017","date":"2026-08-08 04:21:42.868368","duration":1.0599858999994467,"mem_peak_pagefile_usage":37240832,"uptime":25320.738108873367},"values":[0.000583638671869835,0.0005820550781123757,0.0005803773437520476,0.0005798308593654156,0.0005787589843748719,0.0005768164062516234],"warmups":[[256,0.0005735753906321861]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146823","date":"2026-08-08 04:21:44.146578","duration":1.0531579999988026,"mem_peak_pagefile_usage":35864576,"uptime":25322.01584792137},"values":[0.000576594140625275,0.0005747472656310038,0.0005766300781289146,0.0005794449218825548,0.0005786957031261863,0.0005765445312562179],"warmups":[[256,0.0005685207031262962]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151712","date":"2026-08-08 04:21:45.411300","duration":1.0422120000002906,"mem_peak_pagefile_usage":35905536,"uptime":25323.276545763016},"values":[0.0005702492187538155,0.000568280078127259,0.0005686449218842426,0.0005685632812486574,0.0005706246093808431,0.0005723410156264208],"warmups":[[256,0.0005654894531232912]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146145","date":"2026-08-08 04:21:46.667633","duration":1.0354200000001583,"mem_peak_pagefile_usage":35721216,"uptime":25324.538504123688},"values":[0.0005637996093668107,0.0005656765625019489,0.0005661906250082893,0.0005661070312612537,0.00056594804686938,0.0005660941406233633],"warmups":[[256,0.0005639812499964592]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139683","date":"2026-08-08 04:21:47.938452","duration":1.0486805000000459,"mem_peak_pagefile_usage":36233216,"uptime":25325.81499838829},"values":[0.0005734714843725897,0.0005725113281300764,0.00057272031249056,0.0005727351562541116,0.0005732542968814869,0.0005758265624962178],"warmups":[[256,0.000571657812500348]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138430","date":"2026-08-08 04:21:49.213878","duration":1.0556897000024037,"mem_peak_pagefile_usage":36675584,"uptime":25327.092238903046},"values":[0.0005780281249911923,0.0005731039062482068,0.0005800652343737056,0.000579333593748288,0.0005791593750075208,0.0005798062500019796],"warmups":[[256,0.0005689769531187494]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144142","date":"2026-08-08 04:21:50.467847","duration":1.0282637999989674,"mem_peak_pagefile_usage":36044800,"uptime":25328.340752601624},"values":[0.0005660117187460401,0.0005586058593820553,0.0005590652343698821,0.0005582078125030421,0.0005583046875017317,0.0005584722656237773],"warmups":[[256,0.0005713570312479987]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142453","date":"2026-08-08 04:21:51.727695","duration":1.0351964000001317,"mem_peak_pagefile_usage":36098048,"uptime":25329.60148882866},"values":[0.0005652679687528916,0.0005665937500083373,0.0005677714843699277,0.0005655492187486288,0.0005665453124947817,0.0005663140625102869],"warmups":[[256,0.0005612792968747726]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150786","date":"2026-08-08 04:21:52.997526","duration":1.047959700001229,"mem_peak_pagefile_usage":36372480,"uptime":25330.863356113434},"values":[0.0005664992187490725,0.0005668445312494441,0.0005646062499948812,0.0005680238281229322,0.0005720074218658056,0.0005718820312523576],"warmups":[[256,0.0005975679687537649]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146845","date":"2026-08-08 04:21:54.255378","duration":1.0338621999981115,"mem_peak_pagefile_usage":36704256,"uptime":25332.124973535538},"values":[0.000564546874997518,0.0005601832031203458,0.0005652648437433072,0.0005657421874900592,0.0005663691406141425,0.0005671765624981617],"warmups":[[256,0.0005648570312501988]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148227","date":"2026-08-08 04:21:55.522577","duration":1.0486070000006293,"mem_peak_pagefile_usage":36470784,"uptime":25333.391062021255},"values":[0.0005705937500124492,0.0005730093750031529,0.0005754410156271206,0.0005743312499930653,0.0005754035156257942,0.0005760488281225662],"warmups":[[256,0.0005661089843727041]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143039","date":"2026-08-08 04:21:56.806291","duration":1.063889700002619,"mem_peak_pagefile_usage":36519936,"uptime":25334.67992925644},"values":[0.0005830457031237302,0.0005816687500015405,0.0005814636718781685,0.0005814300781281645,0.0005819015625121438,0.0005818085937505657],"warmups":[[256,0.0005792574218759228]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149563","date":"2026-08-08 04:21:58.074274","duration":1.0462336000018695,"mem_peak_pagefile_usage":36687872,"uptime":25335.941695213318},"values":[0.0005659582031256605,0.000564231249995828,0.0005644871093721804,0.0005645511718768148,0.0005649972656271984,0.0005663695312421169],"warmups":[[256,0.0006083671874961283]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149037","date":"2026-08-08 04:21:59.336010","duration":1.0423487999978533,"mem_peak_pagefile_usage":36679680,"uptime":25337.20352101326},"values":[0.0005649664062445936,0.0005701910156261647,0.0005715058593693811,0.0005712527343746387,0.0005715144531279748,0.0005716703124960532],"warmups":[[256,0.0005653214843732712]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148119","date":"2026-08-08 04:22:00.582853","duration":1.027019699999073,"mem_peak_pagefile_usage":36478976,"uptime":25338.45093512535},"values":[0.000563780468752384,0.0005592808593775089,0.0005600316406173533,0.000559757421882523,0.0005606671875000302,0.000561014453126063],"warmups":[[256,0.0005631749999963631]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143619","date":"2026-08-08 04:22:01.870388","duration":1.0643347000004724,"mem_peak_pagefile_usage":36855808,"uptime":25339.743092775345},"values":[0.000577175781245387,0.0005771609375102571,0.0005776828124908207,0.0005774218750076443,0.0005770906250006647,0.0005783343750067615],"warmups":[[256,0.0006091410156301436]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150209","date":"2026-08-08 04:22:03.123563","duration":1.0338844999969297,"mem_peak_pagefile_usage":36519936,"uptime":25340.99037504196},"values":[0.0005663460937626041,0.000564499218754122,0.0005650625000015452,0.0005645777343801228,0.0005654191406279097,0.0005661867187427561],"warmups":[[256,0.0005590707031188913]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148948","date":"2026-08-08 04:22:04.416392","duration":1.0466215000014927,"mem_peak_pagefile_usage":36007936,"uptime":25342.283747911453},"values":[0.0005731511718778393,0.00057245078124879,0.0005737113281298889,0.0005732277343781789,0.0005720085937497288,0.0005722777343777352],"warmups":[[256,0.0005672476562494921]]}]},{"metadata":{"loops":4096,"name":"mako/idiomatic/mixed-page"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.151140","calibrate_loops":4096,"date":"2026-08-08 04:22:05.554945","duration":0.9080213000015647,"mem_peak_pagefile_usage":36392960,"uptime":25343.420602798462},"warmups":[[1,0.00019629999951575883],[2,7.525000000896398e-05],[4,5.4224999985308386e-05],[8,5.113750012242235e-05],[16,3.287499998805288e-05],[32,2.9818750022059248e-05],[64,2.564062498322528e-05],[128,2.9996874985727118e-05],[256,2.7333203135526674e-05],[512,2.6793750002696015e-05],[1024,2.6986621094238217e-05],[2048,2.6892187500848763e-05],[4096,2.6826245117739234e-05],[4096,2.7624682616966822e-05],[4096,2.7015014648412716e-05],[4096,2.698386230459704e-05],[4096,2.6910839843630185e-05],[4096,2.693657226604529e-05],[4096,2.6854248047492035e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148423","date":"2026-08-08 04:22:06.565898","duration":0.790369099999225,"mem_peak_pagefile_usage":36376576,"uptime":25344.434367895126},"values":[2.6567578125025193e-05,2.7402734374959437e-05,2.6748828124922852e-05,2.6735888671858277e-05,2.6684301757562423e-05,2.6702587891058727e-05],"warmups":[[4096,2.6814184569623478e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143847","date":"2026-08-08 04:22:07.584270","duration":0.7950115999992704,"mem_peak_pagefile_usage":35868672,"uptime":25345.45702624321},"values":[2.6746582030945376e-05,2.7589062499444594e-05,2.6883618164497136e-05,2.6860009765705684e-05,2.6817016602009858e-05,2.6927221679962088e-05],"warmups":[[4096,2.7024731444669214e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147193","date":"2026-08-08 04:22:08.614081","duration":0.8064336999996158,"mem_peak_pagefile_usage":36139008,"uptime":25346.48282933235},"values":[2.7011572266033568e-05,2.8069824218768247e-05,2.7549291991668667e-05,2.743190917975369e-05,2.7288842773920408e-05,2.7282055664379357e-05],"warmups":[[4096,2.715510253903375e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143571","date":"2026-08-08 04:22:09.634925","duration":0.7972714999996242,"mem_peak_pagefile_usage":36573184,"uptime":25347.50834107399},"values":[2.6854492187311507e-05,2.7717285155937077e-05,2.700854492143634e-05,2.7010131836036066e-05,2.684011230424943e-05,2.6859545898538784e-05],"warmups":[[4096,2.701181640585304e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152416","date":"2026-08-08 04:22:10.654255","duration":0.7963950000012119,"mem_peak_pagefile_usage":36671488,"uptime":25348.518634080887},"values":[2.6730737304525576e-05,2.7594409179876322e-05,2.7001171874374563e-05,2.698669433609524e-05,2.695080566361696e-05,2.7009350586304492e-05],"warmups":[[4096,2.685852050809956e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139122","date":"2026-08-08 04:22:11.681141","duration":0.801741100000072,"mem_peak_pagefile_usage":36536320,"uptime":25349.558747768402},"values":[2.6912768555042987e-05,2.7770874022614578e-05,2.7161816405829597e-05,2.7158447265307473e-05,2.7079052734357845e-05,2.7118017578153797e-05],"warmups":[[4096,2.7226489257792252e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147493","date":"2026-08-08 04:22:12.698503","duration":0.7967332000007445,"mem_peak_pagefile_usage":37359616,"uptime":25350.567628860474},"values":[2.6790673828713807e-05,2.77043212886241e-05,2.6957714843511837e-05,2.6994067383157017e-05,2.6890112304833735e-05,2.6961865233765536e-05],"warmups":[[4096,2.6965820311808386e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150038","date":"2026-08-08 04:22:13.744006","duration":0.7999189000001934,"mem_peak_pagefile_usage":35901440,"uptime":25351.61024427414},"values":[2.6955737304490412e-05,2.783432617192716e-05,2.7088378906192645e-05,2.706496582050022e-05,2.703608398491042e-05,2.703749999977134e-05],"warmups":[[4096,2.7064184570768646e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141162","date":"2026-08-08 04:22:14.776789","duration":0.8083879999976489,"mem_peak_pagefile_usage":36384768,"uptime":25352.652204990387},"values":[2.6844262695391308e-05,2.7757836914332756e-05,2.7253979491881353e-05,2.720405273493043e-05,2.7311816405806155e-05,2.7317431641193934e-05],"warmups":[[4096,2.7088208008230197e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147527","date":"2026-08-08 04:22:15.794488","duration":0.7942763999999443,"mem_peak_pagefile_usage":36249600,"uptime":25353.66280221939},"values":[2.6754711914378504e-05,2.7720019531329854e-05,2.6798681640016753e-05,2.6869873046564408e-05,2.6867700195332134e-05,2.6989550781841842e-05],"warmups":[[4096,2.683474121045748e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151461","date":"2026-08-08 04:22:16.808498","duration":0.7935945999997784,"mem_peak_pagefile_usage":37003264,"uptime":25354.67387318611},"values":[2.657705078146222e-05,2.741330566369271e-05,2.6811059570697182e-05,2.6911743163715585e-05,2.691840820290281e-05,2.691232910123631e-05],"warmups":[[4096,2.6888623046339433e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137906","date":"2026-08-08 04:22:17.837046","duration":0.8075540999998339,"mem_peak_pagefile_usage":36630528,"uptime":25355.71557879448},"values":[2.727717285111453e-05,2.802888183595087e-05,2.7333032226906084e-05,2.735361328110031e-05,2.726716308565358e-05,2.7364770508242486e-05],"warmups":[[4096,2.7328393554348906e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140247","date":"2026-08-08 04:22:18.849850","duration":0.7920090000006894,"mem_peak_pagefile_usage":36315136,"uptime":25356.725923538208},"values":[2.6652832031182072e-05,2.7562036132522394e-05,2.684406738229228e-05,2.6835034179661932e-05,2.675488281322913e-05,2.679096679703008e-05],"warmups":[[4096,2.673105468797843e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148741","date":"2026-08-08 04:22:19.869016","duration":0.7982446999994863,"mem_peak_pagefile_usage":36073472,"uptime":25357.736779928207},"values":[2.6800903320634006e-05,2.7741943359416155e-05,2.7064135742271844e-05,2.7025683593251415e-05,2.699184570342794e-05,2.7050122070271243e-05],"warmups":[[4096,2.6971875000114665e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148928","date":"2026-08-08 04:22:20.893744","duration":0.8026438000015332,"mem_peak_pagefile_usage":36618240,"uptime":25358.76170539856},"values":[2.703139648474462e-05,2.7817651367278984e-05,2.7130395507946048e-05,2.7149853515595623e-05,2.7072583008269646e-05,2.711323242188257e-05],"warmups":[[4096,2.7281591796324278e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146492","date":"2026-08-08 04:22:21.915845","duration":0.799410200001148,"mem_peak_pagefile_usage":37146624,"uptime":25359.78627872467},"values":[2.689165039093666e-05,2.7783422851257455e-05,2.702905273377354e-05,2.7006323241707264e-05,2.7004199218083613e-05,2.7098388671653595e-05],"warmups":[[4096,2.7023583984764343e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137938","date":"2026-08-08 04:22:22.934111","duration":0.7960304999978689,"mem_peak_pagefile_usage":36540416,"uptime":25360.812937021255},"values":[2.67290039062118e-05,2.7626220703957927e-05,2.6930102539068912e-05,2.6953076171842838e-05,2.6907348632754235e-05,2.697712402355279e-05],"warmups":[[4096,2.6939965819927636e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145582","date":"2026-08-08 04:22:23.981862","duration":0.8039244999999937,"mem_peak_pagefile_usage":36270080,"uptime":25361.85323691368},"values":[2.7058154297598946e-05,2.7919262694631186e-05,2.7239624023067677e-05,2.7204370116606924e-05,2.708798828088277e-05,2.7144995116579196e-05],"warmups":[[4096,2.7283642578090905e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142306","date":"2026-08-08 04:22:25.004540","duration":0.7988707000004069,"mem_peak_pagefile_usage":36855808,"uptime":25362.879299402237},"values":[2.6800659179926356e-05,2.7621313477332876e-05,2.72499755853417e-05,2.718078613295205e-05,2.700788574205859e-05,2.693613281223861e-05],"warmups":[[4096,2.6850708008119284e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149083","date":"2026-08-08 04:22:26.019293","duration":0.7940225999991526,"mem_peak_pagefile_usage":36855808,"uptime":25363.886846780777},"values":[2.6691137694712097e-05,2.754050292974597e-05,2.6920800780594334e-05,2.6845190429725108e-05,2.684829101529118e-05,2.6919409179981812e-05],"warmups":[[4096,2.6832080078698084e-05]]}]},{"metadata":{"loops":4096,"name":"mako/idiomatic/conditional-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.146015","calibrate_loops":4096,"date":"2026-08-08 04:22:27.592898","duration":1.3385254999993776,"mem_peak_pagefile_usage":36433920,"uptime":25365.463193178177},"warmups":[[1,0.00012619999688467942],[2,8.275000072899275e-05],[4,5.8799999351322185e-05],[8,3.8099999983387534e-05],[16,3.859375010506483e-05],[32,3.840937495169783e-05],[64,4.030937498100684e-05],[128,3.923437500930049e-05],[256,4.1465234374982174e-05],[512,4.01847656235077e-05],[1024,4.0047460938552604e-05],[2048,4.0071289063803306e-05],[4096,4.007500000025033e-05],[4096,4.0047631835626873e-05],[4096,4.00729980469805e-05],[4096,4.0055419922246926e-05],[4096,4.0910766601953696e-05],[4096,4.007312011644615e-05],[4096,4.0140649414155405e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148181","date":"2026-08-08 04:22:28.980405","duration":1.1619019999998272,"mem_peak_pagefile_usage":36118528,"uptime":25366.848973035812},"values":[3.95454345705204e-05,3.9450732421286716e-05,3.9604296874884426e-05,3.962880859376128e-05,4.05599609374363e-05,3.978452148434286e-05],"warmups":[[4096,3.9739160156315734e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143233","date":"2026-08-08 04:22:30.349377","duration":1.1463527999985672,"mem_peak_pagefile_usage":36786176,"uptime":25368.222646713257},"values":[3.885319824270539e-05,3.907087402321707e-05,3.911086425745225e-05,3.9093579101923126e-05,4.013942871150533e-05,3.945136718730424e-05],"warmups":[[4096,3.8858691405962986e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141948","date":"2026-08-08 04:22:31.750597","duration":1.1781432999996468,"mem_peak_pagefile_usage":37011456,"uptime":25369.62532234192},"values":[3.96302246086222e-05,3.9865258789184566e-05,3.982128906265814e-05,3.985886230495339e-05,4.132270507817282e-05,4.127731933589729e-05],"warmups":[[4096,4.0504150391029725e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151455","date":"2026-08-08 04:22:33.101647","duration":1.1307459000017843,"mem_peak_pagefile_usage":36265984,"uptime":25370.967002391815},"values":[3.865100097666385e-05,3.864040527368218e-05,3.853920898500007e-05,3.855942382813282e-05,3.931149902314246e-05,3.846015624997534e-05],"warmups":[[4096,3.858579101567727e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146821","date":"2026-08-08 04:22:34.469579","duration":1.1465899999966496,"mem_peak_pagefile_usage":36102144,"uptime":25372.339312314987},"values":[3.902214355466782e-05,3.9095361327845524e-05,3.9157128906452954e-05,3.920737304685673e-05,3.992707519540062e-05,3.91293701174078e-05],"warmups":[[4096,3.914729003984263e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141848","date":"2026-08-08 04:22:35.836274","duration":1.1451304000001983,"mem_peak_pagefile_usage":36745216,"uptime":25373.710876226425},"values":[3.902788085952125e-05,3.900959472602494e-05,3.901257324212537e-05,3.9036694335692346e-05,3.984045410199144e-05,3.8965844725957766e-05],"warmups":[[4096,3.940305175742509e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139134","date":"2026-08-08 04:22:37.236990","duration":1.1776050000007672,"mem_peak_pagefile_usage":36974592,"uptime":25375.114615917206},"values":[3.897602539026934e-05,3.8771313477070635e-05,3.8942822265575217e-05,4.118437499922578e-05,4.1973901367065025e-05,4.123479003936836e-05],"warmups":[[4096,4.10679199216446e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149043","date":"2026-08-08 04:22:38.618923","duration":1.1619372999994084,"mem_peak_pagefile_usage":36270080,"uptime":25376.486709356308},"values":[3.946484375028092e-05,3.965056152388513e-05,3.963884277347063e-05,3.9566308593919075e-05,4.0567993163875826e-05,3.994855957056842e-05],"warmups":[[4096,3.944194335936402e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146682","date":"2026-08-08 04:22:39.972652","duration":1.134033599999384,"mem_peak_pagefile_usage":35983360,"uptime":25377.842972278595},"values":[3.86022216796178e-05,3.851782226504952e-05,3.856354980413812e-05,3.8611010742428675e-05,3.95547607423552e-05,3.8970507811875166e-05],"warmups":[[4096,3.864160156208385e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153109","date":"2026-08-08 04:22:41.382118","duration":1.1910103000009258,"mem_peak_pagefile_usage":36876288,"uptime":25379.24588727951},"values":[4.190112304680582e-05,4.064218749988413e-05,3.972412109387591e-05,3.975285644575166e-05,4.05372070320098e-05,4.096557617216945e-05],"warmups":[[4096,4.185869140638232e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150315","date":"2026-08-08 04:22:42.750762","duration":1.146802100000059,"mem_peak_pagefile_usage":37392384,"uptime":25380.61735391617},"values":[3.8970556641260146e-05,3.896623535126764e-05,3.898124999945907e-05,3.9021777343606345e-05,3.9973120117053895e-05,3.948164062439474e-05],"warmups":[[4096,3.9213330078169406e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139303","date":"2026-08-08 04:22:44.126790","duration":1.1531928000003973,"mem_peak_pagefile_usage":36462592,"uptime":25382.004070997238},"values":[3.922082519558501e-05,3.932126464878394e-05,3.9310009765536336e-05,3.9464916992137944e-05,4.019709472657951e-05,3.934057617183129e-05],"warmups":[[4096,3.935786132824859e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143507","date":"2026-08-08 04:22:45.502978","duration":1.1561929999988934,"mem_peak_pagefile_usage":36163584,"uptime":25383.375784635544},"values":[3.937353515581776e-05,3.9401586914067366e-05,3.938747558596134e-05,3.948830566447015e-05,4.061164550783758e-05,3.9335839844056864e-05],"warmups":[[4096,3.944951171863664e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146126","date":"2026-08-08 04:22:46.845997","duration":1.1231281999971543,"mem_peak_pagefile_usage":36405248,"uptime":25384.71690440178},"values":[3.810388183556057e-05,3.827326660132968e-05,3.8226586914547056e-05,3.825620117225981e-05,3.9132714843681526e-05,3.848881835910589e-05],"warmups":[[4096,3.8334228515957136e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152494","date":"2026-08-08 04:22:48.223544","duration":1.1562946000012744,"mem_peak_pagefile_usage":37789696,"uptime":25386.08788871765},"values":[3.927607421871926e-05,3.9119653320263126e-05,3.929890136689096e-05,3.956950683559057e-05,4.021552734378986e-05,3.954272460937602e-05],"warmups":[[4096,3.9858691406102764e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146541","date":"2026-08-08 04:22:49.591457","duration":1.1473455000013928,"mem_peak_pagefile_usage":35684352,"uptime":25387.461785316467},"values":[3.889487304675754e-05,3.8807153320163934e-05,3.936540527327281e-05,3.936323242204054e-05,4.0140405273447755e-05,3.9346557617392364e-05],"warmups":[[4096,3.882333984339681e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138980","date":"2026-08-08 04:22:50.986617","duration":1.175825199999963,"mem_peak_pagefile_usage":36184064,"uptime":25388.86453294754},"values":[4.000727539033022e-05,4.006015625002135e-05,4.025454101608261e-05,4.0302319336049663e-05,4.105112304753078e-05,4.006340332107783e-05],"warmups":[[4096,3.9961523437881397e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.150449","date":"2026-08-08 04:22:52.385397","duration":1.1778956999987713,"mem_peak_pagefile_usage":35880960,"uptime":25390.2511575222},"values":[4.0191870116501605e-05,4.018581542997168e-05,4.028894043006659e-05,4.0274389648153885e-05,4.1108984374815805e-05,4.020063476595226e-05],"warmups":[[4096,4.009277343719475e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148038","date":"2026-08-08 04:22:53.773225","duration":1.162996099999873,"mem_peak_pagefile_usage":37048320,"uptime":25391.64174056053},"values":[3.8731176757345054e-05,3.871123046828018e-05,3.897854003920287e-05,4.070222167928961e-05,4.1701000975891134e-05,4.1016259765491725e-05],"warmups":[[4096,3.879611816426376e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147382","date":"2026-08-08 04:22:55.125318","duration":1.1304918999994698,"mem_peak_pagefile_usage":36007936,"uptime":25392.99462199211},"values":[3.8573022460575146e-05,3.856225585963102e-05,3.8597485350955196e-05,3.8578125000299224e-05,3.936647949220884e-05,3.858811035239995e-05],"warmups":[[4096,3.842758789129874e-05]]}]},{"metadata":{"loops":4096,"name":"mako/idiomatic/fragment-heavy"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.140094","calibrate_loops":4096,"date":"2026-08-08 04:22:56.363913","duration":1.0047414000000572,"mem_peak_pagefile_usage":36687872,"uptime":25394.240438699722},"warmups":[[1,0.0001995999991777353],[2,7.914999878266826e-05],[4,6.035000023985049e-05],[8,5.687499970008503e-05],[16,3.063125018343271e-05],[32,3.235312499327847e-05],[64,2.897812498758867e-05],[128,3.3065624990058495e-05],[256,2.9957812500924774e-05],[512,2.9717773443849183e-05],[1024,2.987705078183467e-05],[2048,2.9700244139618803e-05],[4096,2.973957519447623e-05],[4096,2.9764184570346686e-05],[4096,3.066315917976681e-05],[4096,3.00245361328777e-05],[4096,2.994201660122542e-05],[4096,2.9879956054301715e-05],[4096,2.9948046875283296e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153567","date":"2026-08-08 04:22:57.465457","duration":0.8776599999982864,"mem_peak_pagefile_usage":36466688,"uptime":25395.328456878662},"values":[2.9588891601761702e-05,2.964331054666758e-05,3.0526489257276523e-05,2.983183593752159e-05,2.981994628825646e-05,2.986289062523184e-05],"warmups":[[4096,2.973164062503031e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139813","date":"2026-08-08 04:22:58.556720","duration":0.870515599999635,"mem_peak_pagefile_usage":36966400,"uptime":25396.433419942856},"values":[2.936870117231649e-05,2.9354760742172914e-05,3.024287109365531e-05,2.9554467773529325e-05,2.9570751952867624e-05,2.957370605471965e-05],"warmups":[[4096,2.958256835938755e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151279","date":"2026-08-08 04:22:59.656667","duration":0.8773060999992595,"mem_peak_pagefile_usage":35872768,"uptime":25397.521844148636},"values":[2.9609838867017402e-05,2.9671630858985054e-05,3.0515429688016127e-05,2.976662597653501e-05,2.9797192382829962e-05,2.977177734386771e-05],"warmups":[[4096,2.980881347713904e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144238","date":"2026-08-08 04:23:00.754594","duration":0.8751774999982445,"mem_peak_pagefile_usage":35901440,"uptime":25398.626853466034},"values":[2.9559301757409173e-05,2.9498291015173095e-05,3.04714843757381e-05,2.974216308615496e-05,2.972255859301498e-05,2.972514648469371e-05],"warmups":[[4096,2.968925781310361e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144388","date":"2026-08-08 04:23:01.858642","duration":0.8820005000015954,"mem_peak_pagefile_usage":36847616,"uptime":25399.7307741642},"values":[2.973674316386621e-05,2.9524389648649674e-05,3.05181152349121e-05,2.996088867135427e-05,3.0205639648173133e-05,3.0244873046925136e-05],"warmups":[[4096,2.9901855469027794e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.145124","date":"2026-08-08 04:23:02.978904","duration":0.8993995999990148,"mem_peak_pagefile_usage":36302848,"uptime":25400.850207328796},"values":[3.0457153320284647e-05,3.039665527371227e-05,3.129343261765172e-05,3.053317871071215e-05,3.05358154299995e-05,3.0554296874818476e-05],"warmups":[[4096,3.056999511752423e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144967","date":"2026-08-08 04:23:04.083562","duration":0.8811298000000534,"mem_peak_pagefile_usage":36171776,"uptime":25401.955326795578},"values":[3.0027661132692174e-05,2.955229492229705e-05,3.0484985352075e-05,2.9866430663716415e-05,2.9820776367373014e-05,2.977194824183016e-05],"warmups":[[4096,3.0280444335950563e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140301","date":"2026-08-08 04:23:05.184280","duration":0.8789475999983551,"mem_peak_pagefile_usage":36503552,"uptime":25403.059908866882},"values":[2.959931640678093e-05,2.967690429667158e-05,3.0619238280849004e-05,2.9904174804862294e-05,2.9914404296782493e-05,2.9968457030626894e-05],"warmups":[[4096,2.977612304633226e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146666","date":"2026-08-08 04:23:06.279763","duration":0.8718353000003844,"mem_peak_pagefile_usage":36294656,"uptime":25404.149528503418},"values":[2.9479443359292645e-05,2.947065429648177e-05,3.0308178710747313e-05,2.9549633788761298e-05,2.95436035155916e-05,2.95977050779328e-05],"warmups":[[4096,2.9674414062874632e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147378","date":"2026-08-08 04:23:07.373399","duration":0.8738816999975825,"mem_peak_pagefile_usage":36810752,"uptime":25405.24221587181},"values":[2.9537963867731776e-05,2.9549536132655874e-05,3.041269531234292e-05,2.970017089776178e-05,2.9657177734954132e-05,2.9622998046541227e-05],"warmups":[[4096,2.9678955078438207e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144482","date":"2026-08-08 04:23:08.473333","duration":0.8780970000007073,"mem_peak_pagefile_usage":36384768,"uptime":25406.345198392868},"values":[2.9564257812531025e-05,2.9539941405865022e-05,3.0549389648193426e-05,2.9854467772594262e-05,2.9850512694551412e-05,2.988195800845972e-05],"warmups":[[4096,2.9888867187466417e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138584","date":"2026-08-08 04:23:09.587077","duration":0.8899960999988252,"mem_peak_pagefile_usage":36802560,"uptime":25407.465142965317},"values":[3.0013769531045398e-05,3.0087548827495425e-05,3.080644531294752e-05,2.9939575195925272e-05,3.0277954102153615e-05,3.071206054627851e-05],"warmups":[[4096,3.0149829101766557e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147952","date":"2026-08-08 04:23:10.702925","duration":0.8733695000009902,"mem_peak_pagefile_usage":35983360,"uptime":25408.571811676025},"values":[2.935068359377624e-05,2.951708984344492e-05,3.029482421901264e-05,2.9771582031656862e-05,2.971511230409618e-05,2.982468261780724e-05],"warmups":[[4096,2.9408398437347216e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147690","date":"2026-08-08 04:23:11.807320","duration":0.8823419000000285,"mem_peak_pagefile_usage":36483072,"uptime":25409.676201820374},"values":[2.9641674804459228e-05,2.9789184570638838e-05,3.076616210950789e-05,3.0202587890215682e-05,2.9976416015209395e-05,2.990852050821502e-05],"warmups":[[4096,2.9863647461603193e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152056","date":"2026-08-08 04:23:12.911986","duration":0.880170000000362,"mem_peak_pagefile_usage":36749312,"uptime":25410.77678346634},"values":[2.9663500976440105e-05,2.973750000023756e-05,3.057346191415178e-05,2.991408691332964e-05,2.9885522460304514e-05,2.983884277352189e-05],"warmups":[[4096,2.9869287109463016e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149127","date":"2026-08-08 04:23:14.015323","duration":0.8790213000029325,"mem_peak_pagefile_usage":36466688,"uptime":25411.88272023201},"values":[2.9877343750150942e-05,2.950798339895755e-05,3.064782714901071e-05,2.979294433558266e-05,2.9696069336004882e-05,2.9762524413889935e-05],"warmups":[[4096,3.005275878908975e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140987","date":"2026-08-08 04:23:15.128435","duration":0.8903180000015709,"mem_peak_pagefile_usage":37072896,"uptime":25413.00409436226},"values":[3.0123852538643803e-05,3.0189135742375584e-05,3.095288085930292e-05,2.9920336913846768e-05,2.9877954101920068e-05,2.9849951172167266e-05],"warmups":[[4096,3.024052734357241e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142659","date":"2026-08-08 04:23:16.233232","duration":0.8811782999982825,"mem_peak_pagefile_usage":36794368,"uptime":25414.10730099678},"values":[2.9685839844084683e-05,2.9729687500257285e-05,3.0866015624297916e-05,2.9934692383548622e-05,2.9930517578158344e-05,2.9715454101797434e-05],"warmups":[[4096,2.9923095703487945e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138496","date":"2026-08-08 04:23:17.333149","duration":0.8764895999993314,"mem_peak_pagefile_usage":36605952,"uptime":25415.211645126343},"values":[2.9873925781132016e-05,2.996469726568307e-05,3.0392041015403493e-05,2.9576635742323276e-05,2.958723144530495e-05,2.9542993163822473e-05],"warmups":[[4096,2.961748046903523e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139484","date":"2026-08-08 04:23:18.424483","duration":0.8709187999993446,"mem_peak_pagefile_usage":36048896,"uptime":25416.301676273346},"values":[2.9356420898629665e-05,2.9285107421728185e-05,3.0323559570000214e-05,2.971811523444501e-05,2.9615551758510605e-05,2.9525048828027423e-05],"warmups":[[4096,2.9468920898167994e-05]]}]},{"metadata":{"loops":16384,"name":"mako/idiomatic/fortunes-encoded"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.149623","calibrate_loops":16384,"date":"2026-08-08 04:23:20.169370","duration":1.5085763999995834,"mem_peak_pagefile_usage":36384768,"uptime":25418.036323308945},"warmups":[[1,8.199999865610152e-05],[2,3.094999919994734e-05],[4,2.4124999981722794e-05],[8,2.336250008738716e-05],[16,2.1625000044878107e-05],[32,1.4190624938237306e-05],[64,1.2439062516023114e-05],[128,1.0802343751947774e-05],[256,1.2888281247569466e-05],[512,1.1458789067830821e-05],[1024,1.1360546878336208e-05],[2048,1.1324462890982545e-05],[4096,1.1328857421943894e-05],[8192,1.1305273437844932e-05],[16384,1.1522882080061692e-05],[16384,1.1364611816278014e-05],[16384,1.136380615229804e-05],[16384,1.1313928222511649e-05],[16384,1.1257666015618284e-05],[16384,1.1269061279239878e-05],[16384,1.127108764653606e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139134","date":"2026-08-08 04:23:21.721183","duration":1.3244405000004917,"mem_peak_pagefile_usage":36102144,"uptime":25419.599239110947},"values":[1.1467803955111933e-05,1.1317498779472857e-05,1.1309240722789937e-05,1.1366943359236714e-05,1.1374932861407672e-05,1.1388800048806047e-05],"warmups":[[16384,1.1247906493982995e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142539","date":"2026-08-08 04:23:23.270045","duration":1.3254030999996758,"mem_peak_pagefile_usage":36188160,"uptime":25421.144023895264},"values":[1.144838867195297e-05,1.1340118408087463e-05,1.1391229248092216e-05,1.1368408203038527e-05,1.1437646484591113e-05,1.1443365478536194e-05],"warmups":[[16384,1.1134875488094664e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151690","date":"2026-08-08 04:23:24.824298","duration":1.3064634000002115,"mem_peak_pagefile_usage":35655680,"uptime":25422.689081192017},"values":[1.1307812499916636e-05,1.1193768310491237e-05,1.1200134277356e-05,1.1194750976661894e-05,1.12047973632734e-05,1.1264862060489378e-05],"warmups":[[16384,1.1056048583979461e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141088","date":"2026-08-08 04:23:26.360124","duration":1.3119355000017094,"mem_peak_pagefile_usage":36610048,"uptime":25424.23558163643},"values":[1.1382379150548516e-05,1.1209545898616113e-05,1.1205578613449063e-05,1.1213616943450688e-05,1.1213500976436919e-05,1.12155273437331e-05],"warmups":[[16384,1.13090576172592e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137849","date":"2026-08-08 04:23:27.887691","duration":1.3050297999980103,"mem_peak_pagefile_usage":36212736,"uptime":25425.766082525253},"values":[1.135367431626122e-05,1.1154382324241041e-05,1.1154284667913572e-05,1.1163458251806091e-05,1.1154266357227272e-05,1.1157775878789522e-05],"warmups":[[16384,1.1212762451195957e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152693","date":"2026-08-08 04:23:29.431788","duration":1.3231290000003355,"mem_peak_pagefile_usage":36585472,"uptime":25427.296070575714},"values":[1.1475286865181289e-05,1.1283636474512804e-05,1.1287896728662261e-05,1.1296075439481967e-05,1.1281671142615579e-05,1.1286743164085067e-05],"warmups":[[16384,1.149244995102272e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.138926","date":"2026-08-08 04:23:30.964281","duration":1.3094932999993034,"mem_peak_pagefile_usage":36208640,"uptime":25428.84198498726},"values":[1.1405841064515698e-05,1.120738525406395e-05,1.1178094482477974e-05,1.1187847900329118e-05,1.1192523193370718e-05,1.1204656982455319e-05],"warmups":[[16384,1.1218542480539995e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146880","date":"2026-08-08 04:23:32.501388","duration":1.313885700001265,"mem_peak_pagefile_usage":36880384,"uptime":25430.371099472046},"values":[1.1385113525275159e-05,1.1233850097491782e-05,1.1277471923865079e-05,1.1275640869223835e-05,1.126596069345176e-05,1.1265600585952384e-05],"warmups":[[16384,1.1158032226621373e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148303","date":"2026-08-08 04:23:34.032493","duration":1.3079390000020794,"mem_peak_pagefile_usage":36683776,"uptime":25431.900812625885},"values":[1.1355450439287651e-05,1.1175433349608355e-05,1.1179028320373874e-05,1.120050048819543e-05,1.1198083496033462e-05,1.1199810791007181e-05],"warmups":[[16384,1.1195251464757305e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152839","date":"2026-08-08 04:23:35.566780","duration":1.3106051000031584,"mem_peak_pagefile_usage":36536320,"uptime":25433.43036055565},"values":[1.1412811279365442e-05,1.1207928466649975e-05,1.1220635986353145e-05,1.1215588378910013e-05,1.1203894042965956e-05,1.1138494873108584e-05],"warmups":[[16384,1.1277154540856316e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144907","date":"2026-08-08 04:23:37.102666","duration":1.3118853999985731,"mem_peak_pagefile_usage":36659200,"uptime":25434.974489212036},"values":[1.1385791015561253e-05,1.1221063232369488e-05,1.1242095947272546e-05,1.1246093750028052e-05,1.1240924072231095e-05,1.1238079833830739e-05],"warmups":[[16384,1.1163427734217635e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146472","date":"2026-08-08 04:23:38.649563","duration":1.3262869000027422,"mem_peak_pagefile_usage":36093952,"uptime":25436.51986002922},"values":[1.1550830078199681e-05,1.1369494628876708e-05,1.1296105957070424e-05,1.1348834228597227e-05,1.1368853759741171e-05,1.1383593749858534e-05],"warmups":[[16384,1.1286236572427555e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152980","date":"2026-08-08 04:23:40.185557","duration":1.310317199997371,"mem_peak_pagefile_usage":36700160,"uptime":25438.049524784088},"values":[1.1396295165999604e-05,1.1200299072200437e-05,1.1201483154144043e-05,1.1206652832163044e-05,1.119630126944493e-05,1.119955444317533e-05],"warmups":[[16384,1.1227795410295727e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143003","date":"2026-08-08 04:23:41.722631","duration":1.3152079999999842,"mem_peak_pagefile_usage":36270080,"uptime":25439.59575676918},"values":[1.1393743896581654e-05,1.1280249023304378e-05,1.1290026855403923e-05,1.1297540283061736e-05,1.1292187499956086e-05,1.1292279052721454e-05],"warmups":[[16384,1.1132391357415727e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.151708","date":"2026-08-08 04:23:43.261193","duration":1.3163989999993646,"mem_peak_pagefile_usage":36884480,"uptime":25441.125996112823},"values":[1.1402990722775286e-05,1.1264617919781728e-05,1.1278845214901523e-05,1.1285900878954536e-05,1.1280285644454935e-05,1.1283697509689716e-05],"warmups":[[16384,1.1231835937541845e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142684","date":"2026-08-08 04:23:44.814803","duration":1.32873059999838,"mem_peak_pagefile_usage":37126144,"uptime":25442.688179969788},"values":[1.1597222900228132e-05,1.1357769775344195e-05,1.1354034423760595e-05,1.1356182861188557e-05,1.1374694824262122e-05,1.1342071533082532e-05],"warmups":[[16384,1.141311035146586e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149327","date":"2026-08-08 04:23:46.350773","duration":1.3104319000012765,"mem_peak_pagefile_usage":36818944,"uptime":25444.217715978622},"values":[1.1380902099622503e-05,1.1201861572329719e-05,1.1209155273306237e-05,1.1217889404280257e-05,1.1183062744057892e-05,1.118452148451965e-05],"warmups":[[16384,1.1301202392788312e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143036","date":"2026-08-08 04:23:47.889085","duration":1.316520500000479,"mem_peak_pagefile_usage":36589568,"uptime":25445.76300263405},"values":[1.1428088378950818e-05,1.127890624985639e-05,1.1254705810648247e-05,1.1254901122859096e-05,1.128554687501726e-05,1.1324566650428025e-05],"warmups":[[16384,1.1175292968790274e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142357","date":"2026-08-08 04:23:49.417645","duration":1.3024575999988883,"mem_peak_pagefile_usage":36569088,"uptime":25447.291847229004},"values":[1.1331195068464694e-05,1.111907348638752e-05,1.1131695556665377e-05,1.1130322265628934e-05,1.113549194342589e-05,1.1136871338024434e-05],"warmups":[[16384,1.119431762708345e-05]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137977","date":"2026-08-08 04:23:50.957469","duration":1.3170296999996935,"mem_peak_pagefile_usage":36253696,"uptime":25448.836272001266},"values":[1.1435772705015168e-05,1.1295849609460618e-05,1.1289965820449055e-05,1.1281402587881573e-05,1.1279168701250342e-05,1.1286212158179154e-05],"warmups":[[16384,1.1182025146494468e-05]]}]},{"metadata":{"loops":32,"name":"mako/idiomatic/encoded-loop"},"runs":[{"metadata":{"boot_time":"2026-08-07 21:19:42.147860","calibrate_loops":32,"date":"2026-08-08 04:23:52.575661","duration":1.3587059000019508,"mem_peak_pagefile_usage":36552704,"uptime":25450.444506168365},"warmups":[[1,0.005793200001789955],[2,0.0049373000001651235],[4,0.004963649999808695],[8,0.005383987499953946],[16,0.004977300000064133],[32,0.0052317656250124855],[32,0.005285400000047957],[32,0.005259784374970877],[32,0.0053250312499812935],[32,0.005295334374977756],[32,0.0052562000000762055],[32,0.005170071874999849]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.147375","date":"2026-08-08 04:23:53.979564","duration":1.1788755000015954,"mem_peak_pagefile_usage":36536320,"uptime":25451.84885597229},"values":[0.005159890625009211,0.005177037500061488,0.005208143749996452,0.00511246562496126,0.005223962500053858,0.005197628125074516],"warmups":[[32,0.005076753125081268]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142976","date":"2026-08-08 04:23:55.394688","duration":1.1885624999995343,"mem_peak_pagefile_usage":37064704,"uptime":25453.26856637001},"values":[0.005178084374961145,0.00518883124993863,0.005264912500024366,0.005171868750039721,0.005291424999995797,0.00529222500006199],"warmups":[[32,0.005061246875015968]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139414","date":"2026-08-08 04:23:56.795212","duration":1.1759476000006543,"mem_peak_pagefile_usage":36339712,"uptime":25454.672429800034},"values":[0.0052304406249277235,0.005202731249937642,0.005172431250002774,0.005062468749997606,0.005138796874916807,0.005148040625044814],"warmups":[[32,0.005108640624939653]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.141593","date":"2026-08-08 04:23:58.201271","duration":1.1836949000025925,"mem_peak_pagefile_usage":36388864,"uptime":25456.076282978058},"values":[0.005183543750035824,0.0051926156251056454,0.005224003125022136,0.005097881249980674,0.005268856249927012,0.00523566250001295],"warmups":[[32,0.005102850000071157]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.142509","date":"2026-08-08 04:23:59.621047","duration":1.1925306000011915,"mem_peak_pagefile_usage":36708352,"uptime":25457.495274305344},"values":[0.005184924999980467,0.005234637500052486,0.0052711843750330445,0.005216659374923438,0.0052774281249412525,0.005284696874923611],"warmups":[[32,0.005111681250014044]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149349","date":"2026-08-08 04:24:01.031259","duration":1.1859900999988895,"mem_peak_pagefile_usage":36216832,"uptime":25458.89914417267},"values":[0.005219487499971365,0.005204978124993431,0.0052254624999932275,0.005146562500044638,0.005228831250065014,0.005248856249977507],"warmups":[[32,0.005081409374952273]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.152756","date":"2026-08-08 04:24:02.456362","duration":1.2005839999983436,"mem_peak_pagefile_usage":35942400,"uptime":25460.32031750679},"values":[0.005253078125065258,0.0052580406249944645,0.005432834375028506,0.005193796875005319,0.00528848124997694,0.005228984374980428],"warmups":[[32,0.005177231250058867]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.143952","date":"2026-08-08 04:24:03.869151","duration":1.1888639999997395,"mem_peak_pagefile_usage":36982784,"uptime":25461.74214220047},"values":[0.005184909374975177,0.005286506249944978,0.005240656250066422,0.005140356250080913,0.005230081250033436,0.005245268749945353],"warmups":[[32,0.005132084374963597]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137999","date":"2026-08-08 04:24:05.279861","duration":1.190446200002043,"mem_peak_pagefile_usage":36069376,"uptime":25463.162368535995},"values":[0.005223281250096079,0.005231684374962242,0.005213799999978619,0.005142306250036199,0.005228574999932789,0.005238678125010665],"warmups":[[32,0.005116543750091296]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139436","date":"2026-08-08 04:24:06.734772","duration":1.2020448000002943,"mem_peak_pagefile_usage":36286464,"uptime":25464.61275267601},"values":[0.005253712500007168,0.005321196875001988,0.005286046874971362,0.005180846875077805,0.0052921437498980595,0.005391131250007675],"warmups":[[32,0.005130868750029549]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.139161","date":"2026-08-08 04:24:08.156006","duration":1.1972229999992123,"mem_peak_pagefile_usage":36556800,"uptime":25466.033757925034},"values":[0.005236546874925807,0.005217075000018667,0.005255559374973018,0.005199490625045655,0.005297512500078483,0.0053199062499516],"warmups":[[32,0.005193081250013165]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.153063","date":"2026-08-08 04:24:09.606786","duration":1.2253386999982467,"mem_peak_pagefile_usage":35999744,"uptime":25467.47034049034},"values":[0.005423524999969231,0.005367909375081581,0.005339415625030597,0.005311546874963824,0.0054778343750285785,0.005408456249938354],"warmups":[[32,0.005280087499954789]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140359","date":"2026-08-08 04:24:11.014734","duration":1.1848962000003667,"mem_peak_pagefile_usage":36397056,"uptime":25468.89098238945},"values":[0.005204246874995988,0.00521006874998875,0.005196587499995076,0.0051104000000350425,0.0052359000000024025,0.005279184375012846],"warmups":[[32,0.005107400000042617]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140060","date":"2026-08-08 04:24:12.433595","duration":1.1908081000001403,"mem_peak_pagefile_usage":36491264,"uptime":25470.310225963593},"values":[0.005174596875008319,0.005197568749963466,0.005315399999972215,0.005211621874991579,0.005264618749947658,0.005257962499968016],"warmups":[[32,0.005103946875010479]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.148272","date":"2026-08-08 04:24:13.846605","duration":1.1910637999972096,"mem_peak_pagefile_usage":36622336,"uptime":25471.71547317505},"values":[0.005224659375016927,0.005235071874949426,0.005248475000030339,0.005152725000016289,0.005257199999959994,0.005276506250083912],"warmups":[[32,0.005123249999996915]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.137890","date":"2026-08-08 04:24:15.239824","duration":1.1700349999991886,"mem_peak_pagefile_usage":36171776,"uptime":25473.118984937668},"values":[0.005116659375062227,0.005076418750036282,0.0051352656249719075,0.0050259125000593485,0.005129400000100759,0.005119778125049379],"warmups":[[32,0.005046109375030028]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.146529","date":"2026-08-08 04:24:16.682755","duration":1.196401799999876,"mem_peak_pagefile_usage":36134912,"uptime":25474.553367853165},"values":[0.005225503125075193,0.005211746875033896,0.005305712500103255,0.005208343750041422,0.005284753125010866,0.005271709374937927],"warmups":[[32,0.005178928125019411]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.144043","date":"2026-08-08 04:24:18.101075","duration":1.1957251999992877,"mem_peak_pagefile_usage":36401152,"uptime":25475.97392487526},"values":[0.005219525000029535,0.00529034062503797,0.0052636531249845575,0.005207903124983204,0.0053137125000830565,0.00528458124995268],"warmups":[[32,0.005099949999930686]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.149780","date":"2026-08-08 04:24:19.511365","duration":1.1862623999986681,"mem_peak_pagefile_usage":36495360,"uptime":25477.378280878067},"values":[0.005186953124962201,0.005194368750039757,0.0052133375000948945,0.005138293749951117,0.005312115624974467,0.005238437499997417],"warmups":[[32,0.005097268749977957]]},{"metadata":{"boot_time":"2026-08-07 21:19:42.140434","date":"2026-08-08 04:24:20.925223","duration":1.19017249999888,"mem_peak_pagefile_usage":36188160,"uptime":25478.801466941833},"values":[0.005219237500000418,0.005224106249897886,0.005257046874930893,0.0051578781250327665,0.005248262500003875,0.005272796875033237],"warmups":[[32,0.005130146874989805]]}]}],"metadata":{"cpu_affinity":"4","cpu_count":32,"hostname":"DESKTOP-F5QFSMS","perf_version":"2.10.0","platform":"Windows-11-10.0.26200-SP0","python_compiler":"MSC v.1944 64 bit (AMD64)","python_executable":"E:\\Work\\Heddle\\benchmarks\\python\\.venv\\Scripts\\python.exe","python_implementation":"cpython","python_version":"3.14.7 (64-bit) revision 823f032","timer":"QueryPerformanceCounter(), resolution: 100 ns","unit":"second"},"version":"1.0"} diff --git a/docs/benchmarks/2026-08-08/python/memory.json b/docs/benchmarks/2026-08-08/python/memory.json new file mode 100644 index 00000000..9bc5d3e7 --- /dev/null +++ b/docs/benchmarks/2026-08-08/python/memory.json @@ -0,0 +1,418 @@ +{ + "jinja2/controlled/composed-page": { + "allocated": { + "mean": 114942.72, + "median": 114922.0, + "std": 70.97446973056829 + }, + "retained": { + "mean": 113034.32, + "median": 113034.0, + "std": 3.2 + }, + "repetitions": 100 + }, + "jinja2/controlled/trivial-substitution": { + "allocated": { + "mean": 4277.12, + "median": 4232.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 2059.0, + "median": 2059.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "jinja2/controlled/large-loop": { + "allocated": { + "mean": 639188.12, + "median": 639143.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 194549.0, + "median": 194549.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "jinja2/controlled/mixed-page": { + "allocated": { + "mean": 18340.12, + "median": 18295.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 11469.0, + "median": 11469.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "jinja2/controlled/conditional-heavy": { + "allocated": { + "mean": 33363.12, + "median": 33318.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 17318.0, + "median": 17318.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "jinja2/controlled/fragment-heavy": { + "allocated": { + "mean": 18184.32, + "median": 18184.0, + "std": 3.2 + }, + "retained": { + "mean": 11275.32, + "median": 11275.0, + "std": 3.2 + }, + "repetitions": 100 + }, + "jinja2/controlled/fortunes-encoded": { + "allocated": { + "mean": 9045.12, + "median": 9000.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 4030.0, + "median": 4030.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "jinja2/controlled/encoded-loop": { + "allocated": { + "mean": 3894425.12, + "median": 3894380.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 1525156.0, + "median": 1525156.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "mako/controlled/composed-page": { + "allocated": { + "mean": 116804.84, + "median": 116709.0, + "std": 244.8294694086255 + }, + "retained": { + "mean": 115343.72, + "median": 115269.0, + "std": 198.58153962236238 + }, + "repetitions": 100 + }, + "mako/controlled/trivial-substitution": { + "allocated": { + "mean": 5541.44, + "median": 5440.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 3569.32, + "median": 3491.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + }, + "mako/controlled/large-loop": { + "allocated": { + "mean": 827265.44, + "median": 827164.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 196016.32, + "median": 195938.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + }, + "mako/controlled/mixed-page": { + "allocated": { + "mean": 23000.44, + "median": 22899.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 13215.32, + "median": 13137.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + }, + "mako/controlled/conditional-heavy": { + "allocated": { + "mean": 46728.44, + "median": 46627.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 18793.32, + "median": 18715.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + }, + "mako/controlled/fragment-heavy": { + "allocated": { + "mean": 56192.8, + "median": 56138.0, + "std": 115.09925448862987 + }, + "retained": { + "mean": 47598.68, + "median": 47565.0, + "std": 67.31125950809164 + }, + "repetitions": 100 + }, + "mako/controlled/fortunes-encoded": { + "allocated": { + "mean": 10234.44, + "median": 10133.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 5505.32, + "median": 5427.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + }, + "mako/controlled/encoded-loop": { + "allocated": { + "mean": 4151930.44, + "median": 4151829.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 1526627.32, + "median": 1526549.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + }, + "jinja2/idiomatic/composed-page": { + "allocated": { + "mean": 115251.28, + "median": 115208.0, + "std": 98.34243203924713 + }, + "retained": { + "mean": 113080.32, + "median": 113080.0, + "std": 3.2 + }, + "repetitions": 100 + }, + "jinja2/idiomatic/trivial-substitution": { + "allocated": { + "mean": 4306.12, + "median": 4261.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 2088.0, + "median": 2088.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "jinja2/idiomatic/large-loop": { + "allocated": { + "mean": 649189.12, + "median": 649144.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 204550.0, + "median": 204550.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "jinja2/idiomatic/mixed-page": { + "allocated": { + "mean": 19184.28, + "median": 19141.0, + "std": 98.34243203924713 + }, + "retained": { + "mean": 12283.32, + "median": 12283.0, + "std": 3.2 + }, + "repetitions": 100 + }, + "jinja2/idiomatic/conditional-heavy": { + "allocated": { + "mean": 40950.12, + "median": 40905.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 23081.0, + "median": 23081.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "jinja2/idiomatic/fragment-heavy": { + "allocated": { + "mean": 20671.44, + "median": 20632.0, + "std": 92.15361790472087 + }, + "retained": { + "mean": 10471.32, + "median": 10471.0, + "std": 3.2 + }, + "repetitions": 100 + }, + "jinja2/idiomatic/fortunes-encoded": { + "allocated": { + "mean": 9117.12, + "median": 9072.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 4102.0, + "median": 4102.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "jinja2/idiomatic/encoded-loop": { + "allocated": { + "mean": 3914431.12, + "median": 3914386.0, + "std": 100.26563506883889 + }, + "retained": { + "mean": 1545162.0, + "median": 1545162.0, + "std": 0.0 + }, + "repetitions": 100 + }, + "mako/idiomatic/composed-page": { + "allocated": { + "mean": 117358.84, + "median": 117273.0, + "std": 261.68524234393897 + }, + "retained": { + "mean": 115369.72, + "median": 115305.0, + "std": 215.23424307934692 + }, + "repetitions": 100 + }, + "mako/idiomatic/trivial-substitution": { + "allocated": { + "mean": 5570.44, + "median": 5469.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 3598.32, + "median": 3520.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + }, + "mako/idiomatic/large-loop": { + "allocated": { + "mean": 832282.44, + "median": 832181.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 201017.32, + "median": 200939.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + }, + "mako/idiomatic/mixed-page": { + "allocated": { + "mean": 25100.79, + "median": 25001.0, + "std": 291.9879025790713 + }, + "retained": { + "mean": 15285.67, + "median": 15207.0, + "std": 246.00139832894848 + }, + "repetitions": 100 + }, + "mako/idiomatic/conditional-heavy": { + "allocated": { + "mean": 47790.44, + "median": 47689.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 19855.32, + "median": 19777.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + }, + "mako/idiomatic/fragment-heavy": { + "allocated": { + "mean": 20095.44, + "median": 19981.0, + "std": 273.49080164762137 + }, + "retained": { + "mean": 9901.32, + "median": 9808.0, + "std": 226.23706525892192 + }, + "repetitions": 100 + }, + "mako/idiomatic/fortunes-encoded": { + "allocated": { + "mean": 10282.44, + "median": 10181.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 5553.32, + "median": 5475.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + }, + "mako/idiomatic/encoded-loop": { + "allocated": { + "mean": 4161952.44, + "median": 4161851.0, + "std": 217.77758647693102 + }, + "retained": { + "mean": 1536633.32, + "median": 1536555.0, + "std": 166.39850426678186 + }, + "repetitions": 100 + } +} diff --git a/docs/benchmarks/2026-08-08/rust/alloc-report.txt b/docs/benchmarks/2026-08-08/rust/alloc-report.txt new file mode 100644 index 00000000..7d68296b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/alloc-report.txt @@ -0,0 +1,38 @@ +# alloc-report — allocation-counter 0.8.1, one counted render per cell (D10) +# Per-ecosystem figures only; Tera is the baseline. Allocation counts are NOT +# comparable across ecosystems (metrics-protocol metric rule 2). + +track engine workload count_total bytes_total +--------------------------------------------------------------------- +controlled askama composed-page 8 112036 +controlled tera composed-page 19 119051 +controlled askama trivial-substitution 2 720 +controlled tera trivial-substitution 5 4704 +controlled askama large-loop 13 401359 +controlled tera large-loop 16 527716 +controlled askama mixed-page 4 20310 +controlled tera mixed-page 8 32353 +controlled askama conditional-heavy 7 35814 +controlled tera conditional-heavy 10 35425 +controlled askama fragment-heavy 6 10458 +controlled tera fragment-heavy 203 196452 +controlled askama fortunes-encoded 4 2655 +controlled tera fortunes-encoded 8 7265 +controlled askama encoded-loop 15 2850729 +controlled tera encoded-loop 17 2100324 +idiomatic askama composed-page 8 112175 +idiomatic tera composed-page 27 186604 +idiomatic askama trivial-substitution 2 831 +idiomatic tera trivial-substitution 5 5728 +idiomatic askama large-loop 13 622516 +idiomatic tera large-loop 15 1051236 +idiomatic askama mixed-page 4 23415 +idiomatic tera mixed-page 8 28385 +idiomatic askama conditional-heavy 7 62484 +idiomatic tera conditional-heavy 10 67169 +idiomatic askama fragment-heavy 6 12537 +idiomatic tera fragment-heavy 201 195684 +idiomatic askama fortunes-encoded 4 3315 +idiomatic tera fortunes-encoded 7 6753 +idiomatic askama encoded-loop 14 2162556 +idiomatic tera encoded-loop 16 2099812 diff --git a/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/benchmark.json new file mode 100644 index 00000000..0be11bc3 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"cold","function_id":"tera-parse-all-templates","value_str":null,"throughput":null,"full_id":"cold/tera-parse-all-templates","directory_name":"cold/tera-parse-all-templates","title":"cold/tera-parse-all-templates"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/estimates.json new file mode 100644 index 00000000..6295d7d8 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":511538.7689140021,"upper_bound":512087.8698734665},"point_estimate":511807.04862298095,"standard_error":139.66561405574836},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":511360.35940803384,"upper_bound":512006.4083457526},"point_estimate":511677.17171717173,"standard_error":179.46656913165975},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":904.8870536921354,"upper_bound":1476.3277034460841},"point_estimate":1240.1076976806519,"standard_error":143.86124810752412},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":511382.99237445096,"upper_bound":512095.43913110695},"point_estimate":511720.528554348,"standard_error":182.29733140452},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1173.8490626376163,"upper_bound":1592.0767035269232},"point_estimate":1392.7181825749274,"standard_error":106.73511692588555}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/sample.json new file mode 100644 index 00000000..f2fd1dd0 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[11.0,22.0,33.0,44.0,55.0,66.0,77.0,88.0,99.0,110.0,121.0,132.0,143.0,154.0,165.0,176.0,187.0,198.0,209.0,220.0,231.0,242.0,253.0,264.0,275.0,286.0,297.0,308.0,319.0,330.0,341.0,352.0,363.0,374.0,385.0,396.0,407.0,418.0,429.0,440.0,451.0,462.0,473.0,484.0,495.0,506.0,517.0,528.0,539.0,550.0,561.0,572.0,583.0,594.0,605.0,616.0,627.0,638.0,649.0,660.0,671.0,682.0,693.0,704.0,715.0,726.0,737.0,748.0,759.0,770.0,781.0,792.0,803.0,814.0,825.0,836.0,847.0,858.0,869.0,880.0,891.0,902.0,913.0,924.0,935.0,946.0,957.0,968.0,979.0,990.0,1001.0,1012.0,1023.0,1034.0,1045.0,1056.0,1067.0,1078.0,1089.0,1100.0],"times":[5641700.0,11248600.0,16834200.0,22452600.0,28141900.0,33809500.0,39406200.0,45063400.0,50747600.0,56304200.0,61990100.0,67590100.0,73399800.0,78636400.0,84345600.0,90006000.0,95758700.0,101350400.0,107543100.0,112389100.0,118840600.0,124079000.0,129750600.0,135198700.0,140759100.0,146276800.0,152038900.0,157630800.0,163246900.0,169685100.0,174798100.0,180425100.0,186133100.0,191264500.0,197243300.0,201941200.0,208087200.0,213156100.0,218633600.0,224058200.0,230007200.0,235570300.0,241721900.0,246823300.0,253283300.0,258278600.0,265098500.0,271467200.0,276878200.0,282326600.0,288826300.0,294473500.0,300897700.0,303624200.0,308473600.0,314666300.0,320706400.0,327966400.0,332657300.0,338171600.0,343556300.0,349575500.0,355109700.0,358769100.0,365069800.0,371072400.0,376346400.0,380753100.0,388218100.0,393243000.0,398863600.0,404287300.0,411265200.0,416130600.0,422261800.0,428789100.0,432409600.0,438836300.0,445114700.0,450056300.0,455261800.0,462047600.0,467893200.0,473337400.0,479168100.0,483746900.0,488543900.0,494952100.0,499933800.0,506070900.0,515478900.0,521091600.0,526043800.0,528601000.0,534368200.0,540142600.0,545506800.0,551046100.0,556233400.0,560873600.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/tukey.json new file mode 100644 index 00000000..2d20ca0c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/base/tukey.json @@ -0,0 +1 @@ +[505895.46448317374,508372.8012350934,514979.0325735457,517456.3693254653] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/change/estimates.json new file mode 100644 index 00000000..e7c69a97 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.03126080877502941,"upper_bound":0.03255540730240675},"point_estimate":0.03191089775567546,"standard_error":0.0003265879534093088},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.030745145352370162,"upper_bound":0.032479853448191154},"point_estimate":0.03171573510496395,"standard_error":0.0004431003509091598}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/benchmark.json new file mode 100644 index 00000000..0be11bc3 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"cold","function_id":"tera-parse-all-templates","value_str":null,"throughput":null,"full_id":"cold/tera-parse-all-templates","directory_name":"cold/tera-parse-all-templates","title":"cold/tera-parse-all-templates"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/estimates.json new file mode 100644 index 00000000..6295d7d8 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":511538.7689140021,"upper_bound":512087.8698734665},"point_estimate":511807.04862298095,"standard_error":139.66561405574836},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":511360.35940803384,"upper_bound":512006.4083457526},"point_estimate":511677.17171717173,"standard_error":179.46656913165975},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":904.8870536921354,"upper_bound":1476.3277034460841},"point_estimate":1240.1076976806519,"standard_error":143.86124810752412},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":511382.99237445096,"upper_bound":512095.43913110695},"point_estimate":511720.528554348,"standard_error":182.29733140452},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1173.8490626376163,"upper_bound":1592.0767035269232},"point_estimate":1392.7181825749274,"standard_error":106.73511692588555}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/sample.json new file mode 100644 index 00000000..f2fd1dd0 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[11.0,22.0,33.0,44.0,55.0,66.0,77.0,88.0,99.0,110.0,121.0,132.0,143.0,154.0,165.0,176.0,187.0,198.0,209.0,220.0,231.0,242.0,253.0,264.0,275.0,286.0,297.0,308.0,319.0,330.0,341.0,352.0,363.0,374.0,385.0,396.0,407.0,418.0,429.0,440.0,451.0,462.0,473.0,484.0,495.0,506.0,517.0,528.0,539.0,550.0,561.0,572.0,583.0,594.0,605.0,616.0,627.0,638.0,649.0,660.0,671.0,682.0,693.0,704.0,715.0,726.0,737.0,748.0,759.0,770.0,781.0,792.0,803.0,814.0,825.0,836.0,847.0,858.0,869.0,880.0,891.0,902.0,913.0,924.0,935.0,946.0,957.0,968.0,979.0,990.0,1001.0,1012.0,1023.0,1034.0,1045.0,1056.0,1067.0,1078.0,1089.0,1100.0],"times":[5641700.0,11248600.0,16834200.0,22452600.0,28141900.0,33809500.0,39406200.0,45063400.0,50747600.0,56304200.0,61990100.0,67590100.0,73399800.0,78636400.0,84345600.0,90006000.0,95758700.0,101350400.0,107543100.0,112389100.0,118840600.0,124079000.0,129750600.0,135198700.0,140759100.0,146276800.0,152038900.0,157630800.0,163246900.0,169685100.0,174798100.0,180425100.0,186133100.0,191264500.0,197243300.0,201941200.0,208087200.0,213156100.0,218633600.0,224058200.0,230007200.0,235570300.0,241721900.0,246823300.0,253283300.0,258278600.0,265098500.0,271467200.0,276878200.0,282326600.0,288826300.0,294473500.0,300897700.0,303624200.0,308473600.0,314666300.0,320706400.0,327966400.0,332657300.0,338171600.0,343556300.0,349575500.0,355109700.0,358769100.0,365069800.0,371072400.0,376346400.0,380753100.0,388218100.0,393243000.0,398863600.0,404287300.0,411265200.0,416130600.0,422261800.0,428789100.0,432409600.0,438836300.0,445114700.0,450056300.0,455261800.0,462047600.0,467893200.0,473337400.0,479168100.0,483746900.0,488543900.0,494952100.0,499933800.0,506070900.0,515478900.0,521091600.0,526043800.0,528601000.0,534368200.0,540142600.0,545506800.0,551046100.0,556233400.0,560873600.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/tukey.json new file mode 100644 index 00000000..2d20ca0c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/cold/tera-parse-all-templates/new/tukey.json @@ -0,0 +1 @@ +[505895.46448317374,508372.8012350934,514979.0325735457,517456.3693254653] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/benchmark.json new file mode 100644 index 00000000..ed234715 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-composed-page","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-composed-page/askama","directory_name":"controlled-composed-page/askama","title":"controlled-composed-page/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/estimates.json new file mode 100644 index 00000000..64aab6aa --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1453.926214741765,"upper_bound":1455.2380494454553},"point_estimate":1454.5680855035864,"standard_error":0.33488954432528945},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1454.1899876565694,"upper_bound":1455.2671927003478},"point_estimate":1454.7234248818468,"standard_error":0.2939477478454523},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2.0957005197732164,"upper_bound":3.834835060305386},"point_estimate":3.144039633133959,"standard_error":0.45276938235061176},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1455.3350723075016,"upper_bound":1457.1302811973171},"point_estimate":1456.1985279716457,"standard_error":0.45750975013576023},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2.6506752113328824,"upper_bound":4.08350318837506},"point_estimate":3.372524684053838,"standard_error":0.36946541265026595}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/sample.json new file mode 100644 index 00000000..dbe89af1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[3553.0,7106.0,10659.0,14212.0,17765.0,21318.0,24871.0,28424.0,31977.0,35530.0,39083.0,42636.0,46189.0,49742.0,53295.0,56848.0,60401.0,63954.0,67507.0,71060.0,74613.0,78166.0,81719.0,85272.0,88825.0,92378.0,95931.0,99484.0,103037.0,106590.0,110143.0,113696.0,117249.0,120802.0,124355.0,127908.0,131461.0,135014.0,138567.0,142120.0,145673.0,149226.0,152779.0,156332.0,159885.0,163438.0,166991.0,170544.0,174097.0,177650.0,181203.0,184756.0,188309.0,191862.0,195415.0,198968.0,202521.0,206074.0,209627.0,213180.0,216733.0,220286.0,223839.0,227392.0,230945.0,234498.0,238051.0,241604.0,245157.0,248710.0,252263.0,255816.0,259369.0,262922.0,266475.0,270028.0,273581.0,277134.0,280687.0,284240.0,287793.0,291346.0,294899.0,298452.0,302005.0,305558.0,309111.0,312664.0,316217.0,319770.0,323323.0,326876.0,330429.0,333982.0,337535.0,341088.0,344641.0,348194.0,351747.0,355300.0],"times":[5182000.0,10315700.0,15465900.0,20599200.0,25772500.0,30919700.0,36115100.0,41265600.0,46401600.0,51479500.0,56686100.0,61849800.0,66878800.0,72139000.0,77288900.0,83464200.0,87579300.0,92999900.0,98229600.0,103398600.0,108488200.0,113713700.0,118913600.0,123929400.0,129016800.0,134130600.0,139587600.0,144618200.0,149877200.0,155171500.0,160178000.0,165340000.0,170652300.0,175369500.0,180642100.0,185744100.0,190959600.0,195959300.0,201012400.0,206209500.0,211476000.0,216578600.0,221650400.0,227006300.0,232040000.0,237201500.0,242366300.0,247249700.0,252547000.0,258755300.0,263775600.0,269180300.0,274014900.0,279415000.0,284372900.0,289618600.0,294826900.0,299977600.0,305242300.0,310425100.0,315549200.0,321011200.0,325836000.0,330984900.0,336096300.0,341571300.0,346900000.0,351877300.0,357431500.0,362447900.0,367505900.0,372637400.0,377829500.0,383190800.0,388403900.0,393444600.0,398569200.0,403631100.0,408896800.0,414144800.0,419452300.0,423813900.0,428916300.0,434130700.0,439179100.0,444537300.0,449567500.0,454590500.0,460040400.0,465182500.0,470114300.0,475343400.0,480342400.0,485845600.0,491351400.0,499150300.0,505366400.0,508727500.0,513729600.0,518840400.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/tukey.json new file mode 100644 index 00000000..160c9f7c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/base/tukey.json @@ -0,0 +1 @@ +[1437.7945548051237,1444.7821359556224,1463.415685690286,1470.403266840785] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/change/estimates.json new file mode 100644 index 00000000..ac2fb80b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.014525455420447664,"upper_bound":0.01602777552376411},"point_estimate":0.015296032935987913,"standard_error":0.0003812518582226388},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.014891965632094939,"upper_bound":0.016843702753858603},"point_estimate":0.01581496793046888,"standard_error":0.0005268622559669577}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/benchmark.json new file mode 100644 index 00000000..ed234715 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-composed-page","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-composed-page/askama","directory_name":"controlled-composed-page/askama","title":"controlled-composed-page/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/estimates.json new file mode 100644 index 00000000..64aab6aa --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1453.926214741765,"upper_bound":1455.2380494454553},"point_estimate":1454.5680855035864,"standard_error":0.33488954432528945},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1454.1899876565694,"upper_bound":1455.2671927003478},"point_estimate":1454.7234248818468,"standard_error":0.2939477478454523},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2.0957005197732164,"upper_bound":3.834835060305386},"point_estimate":3.144039633133959,"standard_error":0.45276938235061176},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1455.3350723075016,"upper_bound":1457.1302811973171},"point_estimate":1456.1985279716457,"standard_error":0.45750975013576023},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2.6506752113328824,"upper_bound":4.08350318837506},"point_estimate":3.372524684053838,"standard_error":0.36946541265026595}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/sample.json new file mode 100644 index 00000000..dbe89af1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[3553.0,7106.0,10659.0,14212.0,17765.0,21318.0,24871.0,28424.0,31977.0,35530.0,39083.0,42636.0,46189.0,49742.0,53295.0,56848.0,60401.0,63954.0,67507.0,71060.0,74613.0,78166.0,81719.0,85272.0,88825.0,92378.0,95931.0,99484.0,103037.0,106590.0,110143.0,113696.0,117249.0,120802.0,124355.0,127908.0,131461.0,135014.0,138567.0,142120.0,145673.0,149226.0,152779.0,156332.0,159885.0,163438.0,166991.0,170544.0,174097.0,177650.0,181203.0,184756.0,188309.0,191862.0,195415.0,198968.0,202521.0,206074.0,209627.0,213180.0,216733.0,220286.0,223839.0,227392.0,230945.0,234498.0,238051.0,241604.0,245157.0,248710.0,252263.0,255816.0,259369.0,262922.0,266475.0,270028.0,273581.0,277134.0,280687.0,284240.0,287793.0,291346.0,294899.0,298452.0,302005.0,305558.0,309111.0,312664.0,316217.0,319770.0,323323.0,326876.0,330429.0,333982.0,337535.0,341088.0,344641.0,348194.0,351747.0,355300.0],"times":[5182000.0,10315700.0,15465900.0,20599200.0,25772500.0,30919700.0,36115100.0,41265600.0,46401600.0,51479500.0,56686100.0,61849800.0,66878800.0,72139000.0,77288900.0,83464200.0,87579300.0,92999900.0,98229600.0,103398600.0,108488200.0,113713700.0,118913600.0,123929400.0,129016800.0,134130600.0,139587600.0,144618200.0,149877200.0,155171500.0,160178000.0,165340000.0,170652300.0,175369500.0,180642100.0,185744100.0,190959600.0,195959300.0,201012400.0,206209500.0,211476000.0,216578600.0,221650400.0,227006300.0,232040000.0,237201500.0,242366300.0,247249700.0,252547000.0,258755300.0,263775600.0,269180300.0,274014900.0,279415000.0,284372900.0,289618600.0,294826900.0,299977600.0,305242300.0,310425100.0,315549200.0,321011200.0,325836000.0,330984900.0,336096300.0,341571300.0,346900000.0,351877300.0,357431500.0,362447900.0,367505900.0,372637400.0,377829500.0,383190800.0,388403900.0,393444600.0,398569200.0,403631100.0,408896800.0,414144800.0,419452300.0,423813900.0,428916300.0,434130700.0,439179100.0,444537300.0,449567500.0,454590500.0,460040400.0,465182500.0,470114300.0,475343400.0,480342400.0,485845600.0,491351400.0,499150300.0,505366400.0,508727500.0,513729600.0,518840400.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/tukey.json new file mode 100644 index 00000000..160c9f7c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/askama/new/tukey.json @@ -0,0 +1 @@ +[1437.7945548051237,1444.7821359556224,1463.415685690286,1470.403266840785] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/benchmark.json new file mode 100644 index 00000000..db8b4559 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-composed-page","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-composed-page/tera","directory_name":"controlled-composed-page/tera","title":"controlled-composed-page/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/estimates.json new file mode 100644 index 00000000..bd0180e1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3576.0525999363667,"upper_bound":3580.467076376467},"point_estimate":3578.261839331556,"standard_error":1.1270454357327178},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3573.4628198078726,"upper_bound":3581.8528197765713},"point_estimate":3578.4422413776047,"standard_error":2.2145792014593533},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":9.94431947612445,"upper_bound":15.671148887434066},"point_estimate":12.895833603199941,"standard_error":1.4857668150872043},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3577.7319308504534,"upper_bound":3583.9063619372705},"point_estimate":3580.7344342471943,"standard_error":1.5744565520934626},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":10.082064699977554,"upper_bound":12.577005244970284},"point_estimate":11.41119362833067,"standard_error":0.6389681356024844}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/sample.json new file mode 100644 index 00000000..6a3dd06c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[1438.0,2876.0,4314.0,5752.0,7190.0,8628.0,10066.0,11504.0,12942.0,14380.0,15818.0,17256.0,18694.0,20132.0,21570.0,23008.0,24446.0,25884.0,27322.0,28760.0,30198.0,31636.0,33074.0,34512.0,35950.0,37388.0,38826.0,40264.0,41702.0,43140.0,44578.0,46016.0,47454.0,48892.0,50330.0,51768.0,53206.0,54644.0,56082.0,57520.0,58958.0,60396.0,61834.0,63272.0,64710.0,66148.0,67586.0,69024.0,70462.0,71900.0,73338.0,74776.0,76214.0,77652.0,79090.0,80528.0,81966.0,83404.0,84842.0,86280.0,87718.0,89156.0,90594.0,92032.0,93470.0,94908.0,96346.0,97784.0,99222.0,100660.0,102098.0,103536.0,104974.0,106412.0,107850.0,109288.0,110726.0,112164.0,113602.0,115040.0,116478.0,117916.0,119354.0,120792.0,122230.0,123668.0,125106.0,126544.0,127982.0,129420.0,130858.0,132296.0,133734.0,135172.0,136610.0,138048.0,139486.0,140924.0,142362.0,143800.0],"times":[5136500.0,10268900.0,15347900.0,20460100.0,25640600.0,30788000.0,35970100.0,41082300.0,46187100.0,51299700.0,56465300.0,61600500.0,66635200.0,71577400.0,76768300.0,81856500.0,87027300.0,92377300.0,97523700.0,102600400.0,107625200.0,112901400.0,118108000.0,123232500.0,128562800.0,133974800.0,139067300.0,143893100.0,149003200.0,154574200.0,159651200.0,164710900.0,169601500.0,174502100.0,179961400.0,185467200.0,190378900.0,195590800.0,201076800.0,206054800.0,210735000.0,215536600.0,222168200.0,227427300.0,232091400.0,236743200.0,241765700.0,247316600.0,253847200.0,258365500.0,262856500.0,266959300.0,272149100.0,277579800.0,282934900.0,289457600.0,293786900.0,298814700.0,304103900.0,309659100.0,314396600.0,319824600.0,325424200.0,330990900.0,335854600.0,341158700.0,346050700.0,350601100.0,355356700.0,360278600.0,365834900.0,371272300.0,377181500.0,383049500.0,388095700.0,392711700.0,398669400.0,403132800.0,407876200.0,412948300.0,418131400.0,424878700.0,428297900.0,430449300.0,435660600.0,441923000.0,448296300.0,453807300.0,458082600.0,461979400.0,467321000.0,472354900.0,477576000.0,482243200.0,488891300.0,492245200.0,496875500.0,502694300.0,507458800.0,514839800.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/tukey.json new file mode 100644 index 00000000..ee7f5f3d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/base/tukey.json @@ -0,0 +1 @@ +[3520.309055528567,3544.9371815475597,3610.6121842648727,3635.240310283865] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/change/estimates.json new file mode 100644 index 00000000..2e07dc4f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.011943972660803742,"upper_bound":0.014996211486711456},"point_estimate":0.013478917020857573,"standard_error":0.0007798098305878899},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.014914069762162807,"upper_bound":0.017766716041240693},"point_estimate":0.016566944063151512,"standard_error":0.0007160804095779262}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/benchmark.json new file mode 100644 index 00000000..db8b4559 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-composed-page","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-composed-page/tera","directory_name":"controlled-composed-page/tera","title":"controlled-composed-page/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/estimates.json new file mode 100644 index 00000000..bd0180e1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3576.0525999363667,"upper_bound":3580.467076376467},"point_estimate":3578.261839331556,"standard_error":1.1270454357327178},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3573.4628198078726,"upper_bound":3581.8528197765713},"point_estimate":3578.4422413776047,"standard_error":2.2145792014593533},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":9.94431947612445,"upper_bound":15.671148887434066},"point_estimate":12.895833603199941,"standard_error":1.4857668150872043},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3577.7319308504534,"upper_bound":3583.9063619372705},"point_estimate":3580.7344342471943,"standard_error":1.5744565520934626},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":10.082064699977554,"upper_bound":12.577005244970284},"point_estimate":11.41119362833067,"standard_error":0.6389681356024844}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/sample.json new file mode 100644 index 00000000..6a3dd06c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[1438.0,2876.0,4314.0,5752.0,7190.0,8628.0,10066.0,11504.0,12942.0,14380.0,15818.0,17256.0,18694.0,20132.0,21570.0,23008.0,24446.0,25884.0,27322.0,28760.0,30198.0,31636.0,33074.0,34512.0,35950.0,37388.0,38826.0,40264.0,41702.0,43140.0,44578.0,46016.0,47454.0,48892.0,50330.0,51768.0,53206.0,54644.0,56082.0,57520.0,58958.0,60396.0,61834.0,63272.0,64710.0,66148.0,67586.0,69024.0,70462.0,71900.0,73338.0,74776.0,76214.0,77652.0,79090.0,80528.0,81966.0,83404.0,84842.0,86280.0,87718.0,89156.0,90594.0,92032.0,93470.0,94908.0,96346.0,97784.0,99222.0,100660.0,102098.0,103536.0,104974.0,106412.0,107850.0,109288.0,110726.0,112164.0,113602.0,115040.0,116478.0,117916.0,119354.0,120792.0,122230.0,123668.0,125106.0,126544.0,127982.0,129420.0,130858.0,132296.0,133734.0,135172.0,136610.0,138048.0,139486.0,140924.0,142362.0,143800.0],"times":[5136500.0,10268900.0,15347900.0,20460100.0,25640600.0,30788000.0,35970100.0,41082300.0,46187100.0,51299700.0,56465300.0,61600500.0,66635200.0,71577400.0,76768300.0,81856500.0,87027300.0,92377300.0,97523700.0,102600400.0,107625200.0,112901400.0,118108000.0,123232500.0,128562800.0,133974800.0,139067300.0,143893100.0,149003200.0,154574200.0,159651200.0,164710900.0,169601500.0,174502100.0,179961400.0,185467200.0,190378900.0,195590800.0,201076800.0,206054800.0,210735000.0,215536600.0,222168200.0,227427300.0,232091400.0,236743200.0,241765700.0,247316600.0,253847200.0,258365500.0,262856500.0,266959300.0,272149100.0,277579800.0,282934900.0,289457600.0,293786900.0,298814700.0,304103900.0,309659100.0,314396600.0,319824600.0,325424200.0,330990900.0,335854600.0,341158700.0,346050700.0,350601100.0,355356700.0,360278600.0,365834900.0,371272300.0,377181500.0,383049500.0,388095700.0,392711700.0,398669400.0,403132800.0,407876200.0,412948300.0,418131400.0,424878700.0,428297900.0,430449300.0,435660600.0,441923000.0,448296300.0,453807300.0,458082600.0,461979400.0,467321000.0,472354900.0,477576000.0,482243200.0,488891300.0,492245200.0,496875500.0,502694300.0,507458800.0,514839800.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/tukey.json new file mode 100644 index 00000000..ee7f5f3d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-composed-page/tera/new/tukey.json @@ -0,0 +1 @@ +[3520.309055528567,3544.9371815475597,3610.6121842648727,3635.240310283865] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/benchmark.json new file mode 100644 index 00000000..bbe006cf --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-conditional-heavy","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-conditional-heavy/askama","directory_name":"controlled-conditional-heavy/askama","title":"controlled-conditional-heavy/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/estimates.json new file mode 100644 index 00000000..7e013a5b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3748.878433532871,"upper_bound":3755.279384819522},"point_estimate":3752.18648759826,"standard_error":1.636190951120783},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3752.302612006902,"upper_bound":3760.2048825809757},"point_estimate":3755.9149232691507,"standard_error":1.9572831398742645},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":9.255993763884945,"upper_bound":16.834218318375},"point_estimate":12.349857332294105,"standard_error":1.889998521146919},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3748.1655692580534,"upper_bound":3757.072811144979},"point_estimate":3752.9506475646476,"standard_error":2.2687062165834266},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":12.872616062152018,"upper_bound":19.788291376823896},"point_estimate":16.48236988694415,"standard_error":1.7678649940965874}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/sample.json new file mode 100644 index 00000000..ef62dc08 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[1372.0,2744.0,4116.0,5488.0,6860.0,8232.0,9604.0,10976.0,12348.0,13720.0,15092.0,16464.0,17836.0,19208.0,20580.0,21952.0,23324.0,24696.0,26068.0,27440.0,28812.0,30184.0,31556.0,32928.0,34300.0,35672.0,37044.0,38416.0,39788.0,41160.0,42532.0,43904.0,45276.0,46648.0,48020.0,49392.0,50764.0,52136.0,53508.0,54880.0,56252.0,57624.0,58996.0,60368.0,61740.0,63112.0,64484.0,65856.0,67228.0,68600.0,69972.0,71344.0,72716.0,74088.0,75460.0,76832.0,78204.0,79576.0,80948.0,82320.0,83692.0,85064.0,86436.0,87808.0,89180.0,90552.0,91924.0,93296.0,94668.0,96040.0,97412.0,98784.0,100156.0,101528.0,102900.0,104272.0,105644.0,107016.0,108388.0,109760.0,111132.0,112504.0,113876.0,115248.0,116620.0,117992.0,119364.0,120736.0,122108.0,123480.0,124852.0,126224.0,127596.0,128968.0,130340.0,131712.0,133084.0,134456.0,135828.0,137200.0],"times":[5156700.0,10349100.0,15514400.0,20677900.0,25846200.0,31016300.0,36023300.0,41349400.0,46531900.0,51692500.0,56617400.0,61504400.0,66679100.0,71781400.0,76928900.0,82041800.0,87920900.0,92972000.0,98136500.0,103024600.0,107451400.0,112578500.0,118661500.0,123946300.0,128744200.0,134312000.0,139455700.0,144640400.0,149809900.0,154944200.0,160136900.0,163875400.0,168922100.0,175317700.0,180355800.0,185867800.0,191048900.0,196188300.0,201369200.0,206502500.0,209986900.0,215170300.0,221240800.0,225097400.0,231919000.0,237296200.0,242331400.0,246986100.0,252259800.0,257605700.0,262616000.0,267278600.0,271834100.0,277656500.0,282954400.0,288463800.0,293567700.0,297710400.0,303533600.0,308553800.0,313743500.0,318838300.0,323607800.0,328540300.0,334958500.0,339753500.0,339308300.0,344666400.0,352016600.0,357297200.0,360487500.0,366844400.0,375158200.0,380775200.0,386272300.0,391693300.0,394770800.0,400352600.0,406378000.0,411309400.0,417952400.0,423465800.0,428266700.0,433777600.0,438618000.0,444159400.0,448878900.0,455944400.0,460315000.0,464715900.0,469469100.0,473771700.0,479850700.0,484842700.0,490387200.0,495674700.0,499873000.0,507293600.0,512542500.0,517580700.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/tukey.json new file mode 100644 index 00000000..c57fff2c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/base/tukey.json @@ -0,0 +1 @@ +[3693.051744464912,3719.6192264076353,3790.465844921563,3817.0333268642858] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/change/estimates.json new file mode 100644 index 00000000..1ec58222 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.011638336852014094,"upper_bound":-0.009727642432356302},"point_estimate":-0.01064045523156365,"standard_error":0.0004847330527198861},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.010415761677797009,"upper_bound":-0.008317193998007788},"point_estimate":-0.009366832911605116,"standard_error":0.0005136191789208192}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/benchmark.json new file mode 100644 index 00000000..bbe006cf --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-conditional-heavy","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-conditional-heavy/askama","directory_name":"controlled-conditional-heavy/askama","title":"controlled-conditional-heavy/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/estimates.json new file mode 100644 index 00000000..7e013a5b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3748.878433532871,"upper_bound":3755.279384819522},"point_estimate":3752.18648759826,"standard_error":1.636190951120783},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3752.302612006902,"upper_bound":3760.2048825809757},"point_estimate":3755.9149232691507,"standard_error":1.9572831398742645},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":9.255993763884945,"upper_bound":16.834218318375},"point_estimate":12.349857332294105,"standard_error":1.889998521146919},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3748.1655692580534,"upper_bound":3757.072811144979},"point_estimate":3752.9506475646476,"standard_error":2.2687062165834266},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":12.872616062152018,"upper_bound":19.788291376823896},"point_estimate":16.48236988694415,"standard_error":1.7678649940965874}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/sample.json new file mode 100644 index 00000000..ef62dc08 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[1372.0,2744.0,4116.0,5488.0,6860.0,8232.0,9604.0,10976.0,12348.0,13720.0,15092.0,16464.0,17836.0,19208.0,20580.0,21952.0,23324.0,24696.0,26068.0,27440.0,28812.0,30184.0,31556.0,32928.0,34300.0,35672.0,37044.0,38416.0,39788.0,41160.0,42532.0,43904.0,45276.0,46648.0,48020.0,49392.0,50764.0,52136.0,53508.0,54880.0,56252.0,57624.0,58996.0,60368.0,61740.0,63112.0,64484.0,65856.0,67228.0,68600.0,69972.0,71344.0,72716.0,74088.0,75460.0,76832.0,78204.0,79576.0,80948.0,82320.0,83692.0,85064.0,86436.0,87808.0,89180.0,90552.0,91924.0,93296.0,94668.0,96040.0,97412.0,98784.0,100156.0,101528.0,102900.0,104272.0,105644.0,107016.0,108388.0,109760.0,111132.0,112504.0,113876.0,115248.0,116620.0,117992.0,119364.0,120736.0,122108.0,123480.0,124852.0,126224.0,127596.0,128968.0,130340.0,131712.0,133084.0,134456.0,135828.0,137200.0],"times":[5156700.0,10349100.0,15514400.0,20677900.0,25846200.0,31016300.0,36023300.0,41349400.0,46531900.0,51692500.0,56617400.0,61504400.0,66679100.0,71781400.0,76928900.0,82041800.0,87920900.0,92972000.0,98136500.0,103024600.0,107451400.0,112578500.0,118661500.0,123946300.0,128744200.0,134312000.0,139455700.0,144640400.0,149809900.0,154944200.0,160136900.0,163875400.0,168922100.0,175317700.0,180355800.0,185867800.0,191048900.0,196188300.0,201369200.0,206502500.0,209986900.0,215170300.0,221240800.0,225097400.0,231919000.0,237296200.0,242331400.0,246986100.0,252259800.0,257605700.0,262616000.0,267278600.0,271834100.0,277656500.0,282954400.0,288463800.0,293567700.0,297710400.0,303533600.0,308553800.0,313743500.0,318838300.0,323607800.0,328540300.0,334958500.0,339753500.0,339308300.0,344666400.0,352016600.0,357297200.0,360487500.0,366844400.0,375158200.0,380775200.0,386272300.0,391693300.0,394770800.0,400352600.0,406378000.0,411309400.0,417952400.0,423465800.0,428266700.0,433777600.0,438618000.0,444159400.0,448878900.0,455944400.0,460315000.0,464715900.0,469469100.0,473771700.0,479850700.0,484842700.0,490387200.0,495674700.0,499873000.0,507293600.0,512542500.0,517580700.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/tukey.json new file mode 100644 index 00000000..c57fff2c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/askama/new/tukey.json @@ -0,0 +1 @@ +[3693.051744464912,3719.6192264076353,3790.465844921563,3817.0333268642858] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/benchmark.json new file mode 100644 index 00000000..9eba1098 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-conditional-heavy","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-conditional-heavy/tera","directory_name":"controlled-conditional-heavy/tera","title":"controlled-conditional-heavy/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/estimates.json new file mode 100644 index 00000000..c2056140 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":41028.5668310042,"upper_bound":41077.47561480361},"point_estimate":41053.04432379028,"standard_error":12.465002064565569},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":41002.6862026862,"upper_bound":41094.12269412269},"point_estimate":41031.42361111111,"standard_error":26.268049163410296},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":98.88651565813389,"upper_bound":191.54885619872604},"point_estimate":139.79765887430327,"standard_error":23.955261574814468},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":41097.7346879178,"upper_bound":41153.2393385326},"point_estimate":41126.92436685033,"standard_error":14.127339164690197},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":111.78301019282242,"upper_bound":138.04951495349573},"point_estimate":125.8063933400137,"standard_error":6.677115577974833}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/sample.json new file mode 100644 index 00000000..98fbbcbc --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[126.0,252.0,378.0,504.0,630.0,756.0,882.0,1008.0,1134.0,1260.0,1386.0,1512.0,1638.0,1764.0,1890.0,2016.0,2142.0,2268.0,2394.0,2520.0,2646.0,2772.0,2898.0,3024.0,3150.0,3276.0,3402.0,3528.0,3654.0,3780.0,3906.0,4032.0,4158.0,4284.0,4410.0,4536.0,4662.0,4788.0,4914.0,5040.0,5166.0,5292.0,5418.0,5544.0,5670.0,5796.0,5922.0,6048.0,6174.0,6300.0,6426.0,6552.0,6678.0,6804.0,6930.0,7056.0,7182.0,7308.0,7434.0,7560.0,7686.0,7812.0,7938.0,8064.0,8190.0,8316.0,8442.0,8568.0,8694.0,8820.0,8946.0,9072.0,9198.0,9324.0,9450.0,9576.0,9702.0,9828.0,9954.0,10080.0,10206.0,10332.0,10458.0,10584.0,10710.0,10836.0,10962.0,11088.0,11214.0,11340.0,11466.0,11592.0,11718.0,11844.0,11970.0,12096.0,12222.0,12348.0,12474.0,12600.0],"times":[5170200.0,10302100.0,15539500.0,20692200.0,25812100.0,31049500.0,36144600.0,41383900.0,46470500.0,51624100.0,56785500.0,61973000.0,67144300.0,72241900.0,77415100.0,82697100.0,87759800.0,92937100.0,98090800.0,103253400.0,108537900.0,113594500.0,118750800.0,123937000.0,129156700.0,134324800.0,139497000.0,144616700.0,149843600.0,154952600.0,160066200.0,165431000.0,170557700.0,175058300.0,180239300.0,185358500.0,190460400.0,195654600.0,200701500.0,205824500.0,210951200.0,216203500.0,221384400.0,226502600.0,231702500.0,236889200.0,242100500.0,247210000.0,252366900.0,259185500.0,264361300.0,269572800.0,274786100.0,280143600.0,285117600.0,290539900.0,295719100.0,300995300.0,306005000.0,311375800.0,316713800.0,320936100.0,325416200.0,330609900.0,335586600.0,341446200.0,346809600.0,352089000.0,357398600.0,362552400.0,367635600.0,372828700.0,378081600.0,383161600.0,388591000.0,393920800.0,399296300.0,405061700.0,410474900.0,415721900.0,420798300.0,426793100.0,432137500.0,434779900.0,440509700.0,445766000.0,451189300.0,456563600.0,461807500.0,466975300.0,472262100.0,478014600.0,483279200.0,488511700.0,493898500.0,499284500.0,504372300.0,506501900.0,511559200.0,516929900.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/tukey.json new file mode 100644 index 00000000..024f01fc --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/base/tukey.json @@ -0,0 +1 @@ +[40449.11646879937,40711.94513112868,41412.82156400685,41675.65022633617] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/change/estimates.json new file mode 100644 index 00000000..5bfdc151 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.0012749469575080337,"upper_bound":0.003271428683022536},"point_estimate":0.0022528466258708857,"standard_error":0.000509694061484137},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.0009031379889159474,"upper_bound":0.003318730917378762},"point_estimate":0.001675294495687929,"standard_error":0.0006827936525040445}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/benchmark.json new file mode 100644 index 00000000..9eba1098 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-conditional-heavy","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-conditional-heavy/tera","directory_name":"controlled-conditional-heavy/tera","title":"controlled-conditional-heavy/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/estimates.json new file mode 100644 index 00000000..c2056140 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":41028.5668310042,"upper_bound":41077.47561480361},"point_estimate":41053.04432379028,"standard_error":12.465002064565569},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":41002.6862026862,"upper_bound":41094.12269412269},"point_estimate":41031.42361111111,"standard_error":26.268049163410296},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":98.88651565813389,"upper_bound":191.54885619872604},"point_estimate":139.79765887430327,"standard_error":23.955261574814468},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":41097.7346879178,"upper_bound":41153.2393385326},"point_estimate":41126.92436685033,"standard_error":14.127339164690197},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":111.78301019282242,"upper_bound":138.04951495349573},"point_estimate":125.8063933400137,"standard_error":6.677115577974833}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/sample.json new file mode 100644 index 00000000..98fbbcbc --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[126.0,252.0,378.0,504.0,630.0,756.0,882.0,1008.0,1134.0,1260.0,1386.0,1512.0,1638.0,1764.0,1890.0,2016.0,2142.0,2268.0,2394.0,2520.0,2646.0,2772.0,2898.0,3024.0,3150.0,3276.0,3402.0,3528.0,3654.0,3780.0,3906.0,4032.0,4158.0,4284.0,4410.0,4536.0,4662.0,4788.0,4914.0,5040.0,5166.0,5292.0,5418.0,5544.0,5670.0,5796.0,5922.0,6048.0,6174.0,6300.0,6426.0,6552.0,6678.0,6804.0,6930.0,7056.0,7182.0,7308.0,7434.0,7560.0,7686.0,7812.0,7938.0,8064.0,8190.0,8316.0,8442.0,8568.0,8694.0,8820.0,8946.0,9072.0,9198.0,9324.0,9450.0,9576.0,9702.0,9828.0,9954.0,10080.0,10206.0,10332.0,10458.0,10584.0,10710.0,10836.0,10962.0,11088.0,11214.0,11340.0,11466.0,11592.0,11718.0,11844.0,11970.0,12096.0,12222.0,12348.0,12474.0,12600.0],"times":[5170200.0,10302100.0,15539500.0,20692200.0,25812100.0,31049500.0,36144600.0,41383900.0,46470500.0,51624100.0,56785500.0,61973000.0,67144300.0,72241900.0,77415100.0,82697100.0,87759800.0,92937100.0,98090800.0,103253400.0,108537900.0,113594500.0,118750800.0,123937000.0,129156700.0,134324800.0,139497000.0,144616700.0,149843600.0,154952600.0,160066200.0,165431000.0,170557700.0,175058300.0,180239300.0,185358500.0,190460400.0,195654600.0,200701500.0,205824500.0,210951200.0,216203500.0,221384400.0,226502600.0,231702500.0,236889200.0,242100500.0,247210000.0,252366900.0,259185500.0,264361300.0,269572800.0,274786100.0,280143600.0,285117600.0,290539900.0,295719100.0,300995300.0,306005000.0,311375800.0,316713800.0,320936100.0,325416200.0,330609900.0,335586600.0,341446200.0,346809600.0,352089000.0,357398600.0,362552400.0,367635600.0,372828700.0,378081600.0,383161600.0,388591000.0,393920800.0,399296300.0,405061700.0,410474900.0,415721900.0,420798300.0,426793100.0,432137500.0,434779900.0,440509700.0,445766000.0,451189300.0,456563600.0,461807500.0,466975300.0,472262100.0,478014600.0,483279200.0,488511700.0,493898500.0,499284500.0,504372300.0,506501900.0,511559200.0,516929900.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/tukey.json new file mode 100644 index 00000000..024f01fc --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-conditional-heavy/tera/new/tukey.json @@ -0,0 +1 @@ +[40449.11646879937,40711.94513112868,41412.82156400685,41675.65022633617] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/benchmark.json new file mode 100644 index 00000000..7bc8c518 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-encoded-loop","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-encoded-loop/askama","directory_name":"controlled-encoded-loop/askama","title":"controlled-encoded-loop/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/estimates.json new file mode 100644 index 00000000..3e8cdee0 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":615321.584219516,"upper_bound":623568.423946493},"point_estimate":619436.85377245,"standard_error":2099.5442504879543},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":611512.7946127946,"upper_bound":627927.0685579196},"point_estimate":622078.0753968253,"standard_error":4283.204521607579},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":18660.58988009043,"upper_bound":29798.795660178752},"point_estimate":24284.792474377027,"standard_error":2811.8616434658675},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":628763.7606112135,"upper_bound":634504.8116925068},"point_estimate":631660.2173291956,"standard_error":1464.7174538776499},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":18606.74556151974,"upper_bound":23261.962854513386},"point_estimate":21058.54647921805,"standard_error":1186.0551086643889}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/sample.json new file mode 100644 index 00000000..8bb9fdb6 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[9.0,18.0,27.0,36.0,45.0,54.0,63.0,72.0,81.0,90.0,99.0,108.0,117.0,126.0,135.0,144.0,153.0,162.0,171.0,180.0,189.0,198.0,207.0,216.0,225.0,234.0,243.0,252.0,261.0,270.0,279.0,288.0,297.0,306.0,315.0,324.0,333.0,342.0,351.0,360.0,369.0,378.0,387.0,396.0,405.0,414.0,423.0,432.0,441.0,450.0,459.0,468.0,477.0,486.0,495.0,504.0,513.0,522.0,531.0,540.0,549.0,558.0,567.0,576.0,585.0,594.0,603.0,612.0,621.0,630.0,639.0,648.0,657.0,666.0,675.0,684.0,693.0,702.0,711.0,720.0,729.0,738.0,747.0,756.0,765.0,774.0,783.0,792.0,801.0,810.0,819.0,828.0,837.0,846.0,855.0,864.0,873.0,882.0,891.0,900.0],"times":[5593200.0,10606000.0,15614500.0,21033700.0,26253700.0,31607400.0,37222900.0,42631000.0,47739800.0,53824000.0,59404200.0,64355000.0,69184300.0,74643800.0,80018200.0,85814300.0,91080000.0,97310000.0,101890100.0,106499300.0,114303100.0,119114300.0,124291500.0,131597100.0,136822000.0,141724200.0,146323400.0,150168900.0,156744400.0,163208600.0,172334800.0,176917800.0,181619300.0,193455200.0,200146100.0,205105400.0,210139800.0,210092200.0,212695400.0,220622700.0,225168100.0,229278500.0,232015700.0,236414200.0,242783200.0,250775300.0,249945100.0,260707200.0,267651200.0,278689100.0,279999900.0,290163200.0,297973400.0,302011800.0,309347200.0,313835500.0,322176900.0,325159300.0,332382500.0,347280000.0,359358100.0,375594000.0,370935300.0,371761800.0,381356800.0,394294900.0,389552000.0,399760400.0,409368100.0,414699000.0,414473300.0,418604400.0,421259700.0,422636200.0,433945100.0,430671100.0,434822300.0,443382600.0,448656300.0,455890800.0,465776000.0,474074800.0,469928200.0,482355600.0,493106600.0,485392600.0,492271400.0,497757200.0,506771600.0,509509300.0,518551800.0,517909700.0,527336400.0,531226300.0,538992300.0,533684400.0,548163700.0,555083800.0,568349300.0,567684400.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/tukey.json new file mode 100644 index 00000000..a4ea33be --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/base/tukey.json @@ -0,0 +1 @@ +[504293.5448864206,552470.5591609625,680942.5972264076,729119.6115009496] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/change/estimates.json new file mode 100644 index 00000000..76b966e0 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.03764125268423011,"upper_bound":-0.022181193835974746},"point_estimate":-0.029893957489014134,"standard_error":0.0038717312867046095},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.048440385719922485,"upper_bound":-0.019989014273097072},"point_estimate":-0.029988126716058106,"standard_error":0.0071762792842146065}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/benchmark.json new file mode 100644 index 00000000..7bc8c518 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-encoded-loop","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-encoded-loop/askama","directory_name":"controlled-encoded-loop/askama","title":"controlled-encoded-loop/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/estimates.json new file mode 100644 index 00000000..3e8cdee0 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":615321.584219516,"upper_bound":623568.423946493},"point_estimate":619436.85377245,"standard_error":2099.5442504879543},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":611512.7946127946,"upper_bound":627927.0685579196},"point_estimate":622078.0753968253,"standard_error":4283.204521607579},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":18660.58988009043,"upper_bound":29798.795660178752},"point_estimate":24284.792474377027,"standard_error":2811.8616434658675},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":628763.7606112135,"upper_bound":634504.8116925068},"point_estimate":631660.2173291956,"standard_error":1464.7174538776499},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":18606.74556151974,"upper_bound":23261.962854513386},"point_estimate":21058.54647921805,"standard_error":1186.0551086643889}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/sample.json new file mode 100644 index 00000000..8bb9fdb6 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[9.0,18.0,27.0,36.0,45.0,54.0,63.0,72.0,81.0,90.0,99.0,108.0,117.0,126.0,135.0,144.0,153.0,162.0,171.0,180.0,189.0,198.0,207.0,216.0,225.0,234.0,243.0,252.0,261.0,270.0,279.0,288.0,297.0,306.0,315.0,324.0,333.0,342.0,351.0,360.0,369.0,378.0,387.0,396.0,405.0,414.0,423.0,432.0,441.0,450.0,459.0,468.0,477.0,486.0,495.0,504.0,513.0,522.0,531.0,540.0,549.0,558.0,567.0,576.0,585.0,594.0,603.0,612.0,621.0,630.0,639.0,648.0,657.0,666.0,675.0,684.0,693.0,702.0,711.0,720.0,729.0,738.0,747.0,756.0,765.0,774.0,783.0,792.0,801.0,810.0,819.0,828.0,837.0,846.0,855.0,864.0,873.0,882.0,891.0,900.0],"times":[5593200.0,10606000.0,15614500.0,21033700.0,26253700.0,31607400.0,37222900.0,42631000.0,47739800.0,53824000.0,59404200.0,64355000.0,69184300.0,74643800.0,80018200.0,85814300.0,91080000.0,97310000.0,101890100.0,106499300.0,114303100.0,119114300.0,124291500.0,131597100.0,136822000.0,141724200.0,146323400.0,150168900.0,156744400.0,163208600.0,172334800.0,176917800.0,181619300.0,193455200.0,200146100.0,205105400.0,210139800.0,210092200.0,212695400.0,220622700.0,225168100.0,229278500.0,232015700.0,236414200.0,242783200.0,250775300.0,249945100.0,260707200.0,267651200.0,278689100.0,279999900.0,290163200.0,297973400.0,302011800.0,309347200.0,313835500.0,322176900.0,325159300.0,332382500.0,347280000.0,359358100.0,375594000.0,370935300.0,371761800.0,381356800.0,394294900.0,389552000.0,399760400.0,409368100.0,414699000.0,414473300.0,418604400.0,421259700.0,422636200.0,433945100.0,430671100.0,434822300.0,443382600.0,448656300.0,455890800.0,465776000.0,474074800.0,469928200.0,482355600.0,493106600.0,485392600.0,492271400.0,497757200.0,506771600.0,509509300.0,518551800.0,517909700.0,527336400.0,531226300.0,538992300.0,533684400.0,548163700.0,555083800.0,568349300.0,567684400.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/tukey.json new file mode 100644 index 00000000..a4ea33be --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/askama/new/tukey.json @@ -0,0 +1 @@ +[504293.5448864206,552470.5591609625,680942.5972264076,729119.6115009496] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/benchmark.json new file mode 100644 index 00000000..bdd37ece --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-encoded-loop","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-encoded-loop/tera","directory_name":"controlled-encoded-loop/tera","title":"controlled-encoded-loop/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/estimates.json new file mode 100644 index 00000000..67b8727e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1689539.2651856255,"upper_bound":1693078.6879534875},"point_estimate":1691277.3940457585,"standard_error":904.5209955916761},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1687200.0,"upper_bound":1691533.3333333333},"point_estimate":1689961.298076923,"standard_error":1191.7048416225425},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":7086.162028674172,"upper_bound":12599.618852617066},"point_estimate":10189.263357565984,"standard_error":1339.3308091090892},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1689802.2393992355,"upper_bound":1694508.577337559},"point_estimate":1692224.80190631,"standard_error":1195.2183085003353},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":8028.360758908013,"upper_bound":9979.913577533367},"point_estimate":9089.905751315571,"standard_error":496.5356593334205}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/sample.json new file mode 100644 index 00000000..2340f447 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[4.0,8.0,12.0,16.0,20.0,24.0,28.0,32.0,36.0,40.0,44.0,48.0,52.0,56.0,60.0,64.0,68.0,72.0,76.0,80.0,84.0,88.0,92.0,96.0,100.0,104.0,108.0,112.0,116.0,120.0,124.0,128.0,132.0,136.0,140.0,144.0,148.0,152.0,156.0,160.0,164.0,168.0,172.0,176.0,180.0,184.0,188.0,192.0,196.0,200.0,204.0,208.0,212.0,216.0,220.0,224.0,228.0,232.0,236.0,240.0,244.0,248.0,252.0,256.0,260.0,264.0,268.0,272.0,276.0,280.0,284.0,288.0,292.0,296.0,300.0,304.0,308.0,312.0,316.0,320.0,324.0,328.0,332.0,336.0,340.0,344.0,348.0,352.0,356.0,360.0,364.0,368.0,372.0,376.0,380.0,384.0,388.0,392.0,396.0,400.0],"times":[6748800.0,13455500.0,20233900.0,26928000.0,33712400.0,40596800.0,47628000.0,54077800.0,60858700.0,67619800.0,74456300.0,81920700.0,87592100.0,94022800.0,100833200.0,107677400.0,114261500.0,122596400.0,129727900.0,136487000.0,143644400.0,149198100.0,156302600.0,162728400.0,170565800.0,177525800.0,185026800.0,189744700.0,196782300.0,203689800.0,211552400.0,218904400.0,223971400.0,228699600.0,236245900.0,243513000.0,249269600.0,254975500.0,262829900.0,270478100.0,275603900.0,282308800.0,290530400.0,297443100.0,301975300.0,309741600.0,317546800.0,322707000.0,330147500.0,338959800.0,342760400.0,350367900.0,358493800.0,363156200.0,371191600.0,377897300.0,382917300.0,392242000.0,397100900.0,404367700.0,412100300.0,416276700.0,426069800.0,430338800.0,438727900.0,445390100.0,451468800.0,459275500.0,465439200.0,473691300.0,477657600.0,487245000.0,491687700.0,502022400.0,504913000.0,514581100.0,519365000.0,527277300.0,531489300.0,540195400.0,546205600.0,558766500.0,564073900.0,571731300.0,579980600.0,584186600.0,593431100.0,598484600.0,605183400.0,612146800.0,617631000.0,628175500.0,633197400.0,639895400.0,647546100.0,651256700.0,659971200.0,660918300.0,664596800.0,673144100.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/tukey.json new file mode 100644 index 00000000..b2cac001 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/base/tukey.json @@ -0,0 +1 @@ +[1641430.2341561513,1662793.1356360172,1719760.8729156596,1741123.7743955255] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/change/estimates.json new file mode 100644 index 00000000..ccca272a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.038012612566872064,"upper_bound":-0.03499447688140239},"point_estimate":-0.03648157764546922,"standard_error":0.0007719944683355253},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.039081952926304675,"upper_bound":-0.0351212635727296},"point_estimate":-0.03711682759828727,"standard_error":0.0009444260826975661}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/benchmark.json new file mode 100644 index 00000000..bdd37ece --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-encoded-loop","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-encoded-loop/tera","directory_name":"controlled-encoded-loop/tera","title":"controlled-encoded-loop/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/estimates.json new file mode 100644 index 00000000..67b8727e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1689539.2651856255,"upper_bound":1693078.6879534875},"point_estimate":1691277.3940457585,"standard_error":904.5209955916761},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1687200.0,"upper_bound":1691533.3333333333},"point_estimate":1689961.298076923,"standard_error":1191.7048416225425},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":7086.162028674172,"upper_bound":12599.618852617066},"point_estimate":10189.263357565984,"standard_error":1339.3308091090892},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1689802.2393992355,"upper_bound":1694508.577337559},"point_estimate":1692224.80190631,"standard_error":1195.2183085003353},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":8028.360758908013,"upper_bound":9979.913577533367},"point_estimate":9089.905751315571,"standard_error":496.5356593334205}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/sample.json new file mode 100644 index 00000000..2340f447 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[4.0,8.0,12.0,16.0,20.0,24.0,28.0,32.0,36.0,40.0,44.0,48.0,52.0,56.0,60.0,64.0,68.0,72.0,76.0,80.0,84.0,88.0,92.0,96.0,100.0,104.0,108.0,112.0,116.0,120.0,124.0,128.0,132.0,136.0,140.0,144.0,148.0,152.0,156.0,160.0,164.0,168.0,172.0,176.0,180.0,184.0,188.0,192.0,196.0,200.0,204.0,208.0,212.0,216.0,220.0,224.0,228.0,232.0,236.0,240.0,244.0,248.0,252.0,256.0,260.0,264.0,268.0,272.0,276.0,280.0,284.0,288.0,292.0,296.0,300.0,304.0,308.0,312.0,316.0,320.0,324.0,328.0,332.0,336.0,340.0,344.0,348.0,352.0,356.0,360.0,364.0,368.0,372.0,376.0,380.0,384.0,388.0,392.0,396.0,400.0],"times":[6748800.0,13455500.0,20233900.0,26928000.0,33712400.0,40596800.0,47628000.0,54077800.0,60858700.0,67619800.0,74456300.0,81920700.0,87592100.0,94022800.0,100833200.0,107677400.0,114261500.0,122596400.0,129727900.0,136487000.0,143644400.0,149198100.0,156302600.0,162728400.0,170565800.0,177525800.0,185026800.0,189744700.0,196782300.0,203689800.0,211552400.0,218904400.0,223971400.0,228699600.0,236245900.0,243513000.0,249269600.0,254975500.0,262829900.0,270478100.0,275603900.0,282308800.0,290530400.0,297443100.0,301975300.0,309741600.0,317546800.0,322707000.0,330147500.0,338959800.0,342760400.0,350367900.0,358493800.0,363156200.0,371191600.0,377897300.0,382917300.0,392242000.0,397100900.0,404367700.0,412100300.0,416276700.0,426069800.0,430338800.0,438727900.0,445390100.0,451468800.0,459275500.0,465439200.0,473691300.0,477657600.0,487245000.0,491687700.0,502022400.0,504913000.0,514581100.0,519365000.0,527277300.0,531489300.0,540195400.0,546205600.0,558766500.0,564073900.0,571731300.0,579980600.0,584186600.0,593431100.0,598484600.0,605183400.0,612146800.0,617631000.0,628175500.0,633197400.0,639895400.0,647546100.0,651256700.0,659971200.0,660918300.0,664596800.0,673144100.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/tukey.json new file mode 100644 index 00000000..b2cac001 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-encoded-loop/tera/new/tukey.json @@ -0,0 +1 @@ +[1641430.2341561513,1662793.1356360172,1719760.8729156596,1741123.7743955255] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/benchmark.json new file mode 100644 index 00000000..52e22b06 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-fortunes-encoded","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-fortunes-encoded/askama","directory_name":"controlled-fortunes-encoded/askama","title":"controlled-fortunes-encoded/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/estimates.json new file mode 100644 index 00000000..6eddc020 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":422.92248079246497,"upper_bound":423.7720993049591},"point_estimate":423.346819638663,"standard_error":0.21660851985022314},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":422.7597835250605,"upper_bound":423.5894386880966},"point_estimate":423.11831060372265,"standard_error":0.22742481483085908},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1.5157402333142003,"upper_bound":2.614628272455295},"point_estimate":2.048975526156888,"standard_error":0.2835814825014932},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":422.2660267197487,"upper_bound":423.49919194101403},"point_estimate":422.8655440121561,"standard_error":0.3156846597394906},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1.8626752623489582,"upper_bound":2.4425205008003266},"point_estimate":2.169298772832828,"standard_error":0.14854041656642145}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/sample.json new file mode 100644 index 00000000..57b82350 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[12257.0,24514.0,36771.0,49028.0,61285.0,73542.0,85799.0,98056.0,110313.0,122570.0,134827.0,147084.0,159341.0,171598.0,183855.0,196112.0,208369.0,220626.0,232883.0,245140.0,257397.0,269654.0,281911.0,294168.0,306425.0,318682.0,330939.0,343196.0,355453.0,367710.0,379967.0,392224.0,404481.0,416738.0,428995.0,441252.0,453509.0,465766.0,478023.0,490280.0,502537.0,514794.0,527051.0,539308.0,551565.0,563822.0,576079.0,588336.0,600593.0,612850.0,625107.0,637364.0,649621.0,661878.0,674135.0,686392.0,698649.0,710906.0,723163.0,735420.0,747677.0,759934.0,772191.0,784448.0,796705.0,808962.0,821219.0,833476.0,845733.0,857990.0,870247.0,882504.0,894761.0,907018.0,919275.0,931532.0,943789.0,956046.0,968303.0,980560.0,992817.0,1005074.0,1017331.0,1029588.0,1041845.0,1054102.0,1066359.0,1078616.0,1090873.0,1103130.0,1115387.0,1127644.0,1139901.0,1152158.0,1164415.0,1176672.0,1188929.0,1201186.0,1213443.0,1225700.0],"times":[5172700.0,10347500.0,15512900.0,20691700.0,25860100.0,31036600.0,36246400.0,41438300.0,46635900.0,51873600.0,56999100.0,62464000.0,67448600.0,73099800.0,78345300.0,82999100.0,88741600.0,93785100.0,98749700.0,103911000.0,109110000.0,114399500.0,119262900.0,124642900.0,129674500.0,134905300.0,140835600.0,145148100.0,150560400.0,156504600.0,161591100.0,166739700.0,171170300.0,175159900.0,182199300.0,185578500.0,191079100.0,197493100.0,204134500.0,209858600.0,213077300.0,218629000.0,224749900.0,230108000.0,234610200.0,239709400.0,244425400.0,248814700.0,254628600.0,263012100.0,267300000.0,270166600.0,277167500.0,278736700.0,285109700.0,288649400.0,293246900.0,298672200.0,304099100.0,308541000.0,314102900.0,320505300.0,328072500.0,331406600.0,335824200.0,341692700.0,346848000.0,351875300.0,357185100.0,362432900.0,366854000.0,371845800.0,382045700.0,388531000.0,389281300.0,393933500.0,399052800.0,404272000.0,409958200.0,415044000.0,419738400.0,427119600.0,433148700.0,439618800.0,442416400.0,447727100.0,455338800.0,456062000.0,460497100.0,468017100.0,468361400.0,475759400.0,480717300.0,484734100.0,490672900.0,496460900.0,500556600.0,502149700.0,509082000.0,516114700.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/tukey.json new file mode 100644 index 00000000..f7bcd963 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/base/tukey.json @@ -0,0 +1 @@ +[413.6508740434534,417.80210044194916,428.87203750460446,433.0232639031002] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/change/estimates.json new file mode 100644 index 00000000..ae79ea8a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.012051278625214651,"upper_bound":-0.00825399402101508},"point_estimate":-0.01012864776519029,"standard_error":0.000968219195615997},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.013448033903473045,"upper_bound":-0.006639948716059441},"point_estimate":-0.010381946510300222,"standard_error":0.0016580182484231762}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/benchmark.json new file mode 100644 index 00000000..52e22b06 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-fortunes-encoded","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-fortunes-encoded/askama","directory_name":"controlled-fortunes-encoded/askama","title":"controlled-fortunes-encoded/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/estimates.json new file mode 100644 index 00000000..6eddc020 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":422.92248079246497,"upper_bound":423.7720993049591},"point_estimate":423.346819638663,"standard_error":0.21660851985022314},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":422.7597835250605,"upper_bound":423.5894386880966},"point_estimate":423.11831060372265,"standard_error":0.22742481483085908},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1.5157402333142003,"upper_bound":2.614628272455295},"point_estimate":2.048975526156888,"standard_error":0.2835814825014932},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":422.2660267197487,"upper_bound":423.49919194101403},"point_estimate":422.8655440121561,"standard_error":0.3156846597394906},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1.8626752623489582,"upper_bound":2.4425205008003266},"point_estimate":2.169298772832828,"standard_error":0.14854041656642145}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/sample.json new file mode 100644 index 00000000..57b82350 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[12257.0,24514.0,36771.0,49028.0,61285.0,73542.0,85799.0,98056.0,110313.0,122570.0,134827.0,147084.0,159341.0,171598.0,183855.0,196112.0,208369.0,220626.0,232883.0,245140.0,257397.0,269654.0,281911.0,294168.0,306425.0,318682.0,330939.0,343196.0,355453.0,367710.0,379967.0,392224.0,404481.0,416738.0,428995.0,441252.0,453509.0,465766.0,478023.0,490280.0,502537.0,514794.0,527051.0,539308.0,551565.0,563822.0,576079.0,588336.0,600593.0,612850.0,625107.0,637364.0,649621.0,661878.0,674135.0,686392.0,698649.0,710906.0,723163.0,735420.0,747677.0,759934.0,772191.0,784448.0,796705.0,808962.0,821219.0,833476.0,845733.0,857990.0,870247.0,882504.0,894761.0,907018.0,919275.0,931532.0,943789.0,956046.0,968303.0,980560.0,992817.0,1005074.0,1017331.0,1029588.0,1041845.0,1054102.0,1066359.0,1078616.0,1090873.0,1103130.0,1115387.0,1127644.0,1139901.0,1152158.0,1164415.0,1176672.0,1188929.0,1201186.0,1213443.0,1225700.0],"times":[5172700.0,10347500.0,15512900.0,20691700.0,25860100.0,31036600.0,36246400.0,41438300.0,46635900.0,51873600.0,56999100.0,62464000.0,67448600.0,73099800.0,78345300.0,82999100.0,88741600.0,93785100.0,98749700.0,103911000.0,109110000.0,114399500.0,119262900.0,124642900.0,129674500.0,134905300.0,140835600.0,145148100.0,150560400.0,156504600.0,161591100.0,166739700.0,171170300.0,175159900.0,182199300.0,185578500.0,191079100.0,197493100.0,204134500.0,209858600.0,213077300.0,218629000.0,224749900.0,230108000.0,234610200.0,239709400.0,244425400.0,248814700.0,254628600.0,263012100.0,267300000.0,270166600.0,277167500.0,278736700.0,285109700.0,288649400.0,293246900.0,298672200.0,304099100.0,308541000.0,314102900.0,320505300.0,328072500.0,331406600.0,335824200.0,341692700.0,346848000.0,351875300.0,357185100.0,362432900.0,366854000.0,371845800.0,382045700.0,388531000.0,389281300.0,393933500.0,399052800.0,404272000.0,409958200.0,415044000.0,419738400.0,427119600.0,433148700.0,439618800.0,442416400.0,447727100.0,455338800.0,456062000.0,460497100.0,468017100.0,468361400.0,475759400.0,480717300.0,484734100.0,490672900.0,496460900.0,500556600.0,502149700.0,509082000.0,516114700.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/tukey.json new file mode 100644 index 00000000..f7bcd963 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/askama/new/tukey.json @@ -0,0 +1 @@ +[413.6508740434534,417.80210044194916,428.87203750460446,433.0232639031002] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/benchmark.json new file mode 100644 index 00000000..c72fc344 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-fortunes-encoded","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-fortunes-encoded/tera","directory_name":"controlled-fortunes-encoded/tera","title":"controlled-fortunes-encoded/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/estimates.json new file mode 100644 index 00000000..946c11c3 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3456.5556007968144,"upper_bound":3459.549617757819},"point_estimate":3458.042789238222,"standard_error":0.7650571565295674},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3455.6144595149303,"upper_bound":3459.589521266528},"point_estimate":3457.085124181981,"standard_error":1.1434641742368707},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5.751015869384569,"upper_bound":10.708788687221514},"point_estimate":8.255130313901235,"standard_error":1.1661356166853358},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3459.841115741105,"upper_bound":3463.982824038643},"point_estimate":3461.9973956845242,"standard_error":1.0576725363428512},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":6.787071235297224,"upper_bound":8.461246846176515},"point_estimate":7.703971340954309,"standard_error":0.42788714616295864}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/sample.json new file mode 100644 index 00000000..114a556d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[1487.0,2974.0,4461.0,5948.0,7435.0,8922.0,10409.0,11896.0,13383.0,14870.0,16357.0,17844.0,19331.0,20818.0,22305.0,23792.0,25279.0,26766.0,28253.0,29740.0,31227.0,32714.0,34201.0,35688.0,37175.0,38662.0,40149.0,41636.0,43123.0,44610.0,46097.0,47584.0,49071.0,50558.0,52045.0,53532.0,55019.0,56506.0,57993.0,59480.0,60967.0,62454.0,63941.0,65428.0,66915.0,68402.0,69889.0,71376.0,72863.0,74350.0,75837.0,77324.0,78811.0,80298.0,81785.0,83272.0,84759.0,86246.0,87733.0,89220.0,90707.0,92194.0,93681.0,95168.0,96655.0,98142.0,99629.0,101116.0,102603.0,104090.0,105577.0,107064.0,108551.0,110038.0,111525.0,113012.0,114499.0,115986.0,117473.0,118960.0,120447.0,121934.0,123421.0,124908.0,126395.0,127882.0,129369.0,130856.0,132343.0,133830.0,135317.0,136804.0,138291.0,139778.0,141265.0,142752.0,144239.0,145726.0,147213.0,148700.0],"times":[5131800.0,10263000.0,15407000.0,20531000.0,25640400.0,30784400.0,35933200.0,41308800.0,46224300.0,51319900.0,56422200.0,61573400.0,66699800.0,71849900.0,77045900.0,82068800.0,87192200.0,92568800.0,97667700.0,102819500.0,108073600.0,113281700.0,118373100.0,123578200.0,128679400.0,133836200.0,138899000.0,144159600.0,149322400.0,154391500.0,159537600.0,164585800.0,169760300.0,174201900.0,179392900.0,184549700.0,189604100.0,194917700.0,199932300.0,205105600.0,210143400.0,215408700.0,220399300.0,225754300.0,230906800.0,236005400.0,240899600.0,246245300.0,251245900.0,257238900.0,262532200.0,267579700.0,272687300.0,278058900.0,283235700.0,288337400.0,293452000.0,298349000.0,303446700.0,308579600.0,314030900.0,319139200.0,324282900.0,329366300.0,334705000.0,339156900.0,344158200.0,349400300.0,354547100.0,359568100.0,364690100.0,369997000.0,375235500.0,380408400.0,385408500.0,390694500.0,395664400.0,400788500.0,405964200.0,410658300.0,416062300.0,423174300.0,428566900.0,433547800.0,438809600.0,443711600.0,449032700.0,454190900.0,459351900.0,464705500.0,469932100.0,474841100.0,479864100.0,485396100.0,490378500.0,495446400.0,500551900.0,503694700.0,509061900.0,513999200.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/tukey.json new file mode 100644 index 00000000..d0ebb663 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/base/tukey.json @@ -0,0 +1 @@ +[3418.103943449746,3434.654695329446,3478.7900336753123,3495.340785555012] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/change/estimates.json new file mode 100644 index 00000000..ae94c352 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.022873395307539235,"upper_bound":-0.020280483111301546},"point_estimate":-0.021597087589162123,"standard_error":0.0006650426277149258},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.02553540966926726,"upper_bound":-0.01758563136320901},"point_estimate":-0.02087027298743971,"standard_error":0.0027779770537520315}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/benchmark.json new file mode 100644 index 00000000..c72fc344 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-fortunes-encoded","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-fortunes-encoded/tera","directory_name":"controlled-fortunes-encoded/tera","title":"controlled-fortunes-encoded/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/estimates.json new file mode 100644 index 00000000..946c11c3 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3456.5556007968144,"upper_bound":3459.549617757819},"point_estimate":3458.042789238222,"standard_error":0.7650571565295674},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3455.6144595149303,"upper_bound":3459.589521266528},"point_estimate":3457.085124181981,"standard_error":1.1434641742368707},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5.751015869384569,"upper_bound":10.708788687221514},"point_estimate":8.255130313901235,"standard_error":1.1661356166853358},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3459.841115741105,"upper_bound":3463.982824038643},"point_estimate":3461.9973956845242,"standard_error":1.0576725363428512},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":6.787071235297224,"upper_bound":8.461246846176515},"point_estimate":7.703971340954309,"standard_error":0.42788714616295864}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/sample.json new file mode 100644 index 00000000..114a556d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[1487.0,2974.0,4461.0,5948.0,7435.0,8922.0,10409.0,11896.0,13383.0,14870.0,16357.0,17844.0,19331.0,20818.0,22305.0,23792.0,25279.0,26766.0,28253.0,29740.0,31227.0,32714.0,34201.0,35688.0,37175.0,38662.0,40149.0,41636.0,43123.0,44610.0,46097.0,47584.0,49071.0,50558.0,52045.0,53532.0,55019.0,56506.0,57993.0,59480.0,60967.0,62454.0,63941.0,65428.0,66915.0,68402.0,69889.0,71376.0,72863.0,74350.0,75837.0,77324.0,78811.0,80298.0,81785.0,83272.0,84759.0,86246.0,87733.0,89220.0,90707.0,92194.0,93681.0,95168.0,96655.0,98142.0,99629.0,101116.0,102603.0,104090.0,105577.0,107064.0,108551.0,110038.0,111525.0,113012.0,114499.0,115986.0,117473.0,118960.0,120447.0,121934.0,123421.0,124908.0,126395.0,127882.0,129369.0,130856.0,132343.0,133830.0,135317.0,136804.0,138291.0,139778.0,141265.0,142752.0,144239.0,145726.0,147213.0,148700.0],"times":[5131800.0,10263000.0,15407000.0,20531000.0,25640400.0,30784400.0,35933200.0,41308800.0,46224300.0,51319900.0,56422200.0,61573400.0,66699800.0,71849900.0,77045900.0,82068800.0,87192200.0,92568800.0,97667700.0,102819500.0,108073600.0,113281700.0,118373100.0,123578200.0,128679400.0,133836200.0,138899000.0,144159600.0,149322400.0,154391500.0,159537600.0,164585800.0,169760300.0,174201900.0,179392900.0,184549700.0,189604100.0,194917700.0,199932300.0,205105600.0,210143400.0,215408700.0,220399300.0,225754300.0,230906800.0,236005400.0,240899600.0,246245300.0,251245900.0,257238900.0,262532200.0,267579700.0,272687300.0,278058900.0,283235700.0,288337400.0,293452000.0,298349000.0,303446700.0,308579600.0,314030900.0,319139200.0,324282900.0,329366300.0,334705000.0,339156900.0,344158200.0,349400300.0,354547100.0,359568100.0,364690100.0,369997000.0,375235500.0,380408400.0,385408500.0,390694500.0,395664400.0,400788500.0,405964200.0,410658300.0,416062300.0,423174300.0,428566900.0,433547800.0,438809600.0,443711600.0,449032700.0,454190900.0,459351900.0,464705500.0,469932100.0,474841100.0,479864100.0,485396100.0,490378500.0,495446400.0,500551900.0,503694700.0,509061900.0,513999200.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/tukey.json new file mode 100644 index 00000000..d0ebb663 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fortunes-encoded/tera/new/tukey.json @@ -0,0 +1 @@ +[3418.103943449746,3434.654695329446,3478.7900336753123,3495.340785555012] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/benchmark.json new file mode 100644 index 00000000..d2bda05b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-fragment-heavy","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-fragment-heavy/askama","directory_name":"controlled-fragment-heavy/askama","title":"controlled-fragment-heavy/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/estimates.json new file mode 100644 index 00000000..0bfde83c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":899.3732379775543,"upper_bound":901.3135499765258},"point_estimate":900.3545943558797,"standard_error":0.4961743470995528},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":899.1217606373665,"upper_bound":901.4323610778815},"point_estimate":900.4583260374716,"standard_error":0.6224850078866163},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3.4255394263392813,"upper_bound":8.588011513801783},"point_estimate":6.748306093385109,"standard_error":1.4724741051773294},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":901.1957360509672,"upper_bound":903.585842519133},"point_estimate":902.472812520369,"standard_error":0.6090183269131836},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4.439515275927639,"upper_bound":5.441820158516582},"point_estimate":4.991077328728037,"standard_error":0.2556631284943815}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/sample.json new file mode 100644 index 00000000..243c63ab --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[5711.0,11422.0,17133.0,22844.0,28555.0,34266.0,39977.0,45688.0,51399.0,57110.0,62821.0,68532.0,74243.0,79954.0,85665.0,91376.0,97087.0,102798.0,108509.0,114220.0,119931.0,125642.0,131353.0,137064.0,142775.0,148486.0,154197.0,159908.0,165619.0,171330.0,177041.0,182752.0,188463.0,194174.0,199885.0,205596.0,211307.0,217018.0,222729.0,228440.0,234151.0,239862.0,245573.0,251284.0,256995.0,262706.0,268417.0,274128.0,279839.0,285550.0,291261.0,296972.0,302683.0,308394.0,314105.0,319816.0,325527.0,331238.0,336949.0,342660.0,348371.0,354082.0,359793.0,365504.0,371215.0,376926.0,382637.0,388348.0,394059.0,399770.0,405481.0,411192.0,416903.0,422614.0,428325.0,434036.0,439747.0,445458.0,451169.0,456880.0,462591.0,468302.0,474013.0,479724.0,485435.0,491146.0,496857.0,502568.0,508279.0,513990.0,519701.0,525412.0,531123.0,536834.0,542545.0,548256.0,553967.0,559678.0,565389.0,571100.0],"times":[5126800.0,10260500.0,15511500.0,20618500.0,25665400.0,30801800.0,36060200.0,41011800.0,46141300.0,51439000.0,56391100.0,61538300.0,66747300.0,71860300.0,77266100.0,82134700.0,87216600.0,92351700.0,97669400.0,102853900.0,107736500.0,112871300.0,118109100.0,123261400.0,128475700.0,133684000.0,138799000.0,143730900.0,148954000.0,154270200.0,159314000.0,164316300.0,169446300.0,175023700.0,180125100.0,185487600.0,190564800.0,195571500.0,200908300.0,205785500.0,209760800.0,214089700.0,219647400.0,224324900.0,229412600.0,234670100.0,239637300.0,244618000.0,249850100.0,255174000.0,259668000.0,264660100.0,270059600.0,274875500.0,279998200.0,285261400.0,290130600.0,295103800.0,300367100.0,306264900.0,313803200.0,319149600.0,324231100.0,329994000.0,334651000.0,341743000.0,346702100.0,352018700.0,356906300.0,362782100.0,367248500.0,373214500.0,377351400.0,383059300.0,388308800.0,393300000.0,398545300.0,403611300.0,408794500.0,413448500.0,418570100.0,424476100.0,429399900.0,434862600.0,439677600.0,445144100.0,450418200.0,455414000.0,460605800.0,465347300.0,470880900.0,476204000.0,481471700.0,486490300.0,491497600.0,496565700.0,499325300.0,502137100.0,507320600.0,512686100.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/tukey.json new file mode 100644 index 00000000..6d298fb1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/base/tukey.json @@ -0,0 +1 @@ +[873.6762194081344,885.6919298172991,917.7338242417379,929.7495346509024] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/change/estimates.json new file mode 100644 index 00000000..43a9031e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.014374099423372876,"upper_bound":0.016772635031000852},"point_estimate":0.015544209351632032,"standard_error":0.000617941236139008},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.01373115893243542,"upper_bound":0.01684886547513198},"point_estimate":0.015338164617596295,"standard_error":0.0007960636301831325}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/benchmark.json new file mode 100644 index 00000000..d2bda05b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-fragment-heavy","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-fragment-heavy/askama","directory_name":"controlled-fragment-heavy/askama","title":"controlled-fragment-heavy/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/estimates.json new file mode 100644 index 00000000..0bfde83c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":899.3732379775543,"upper_bound":901.3135499765258},"point_estimate":900.3545943558797,"standard_error":0.4961743470995528},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":899.1217606373665,"upper_bound":901.4323610778815},"point_estimate":900.4583260374716,"standard_error":0.6224850078866163},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3.4255394263392813,"upper_bound":8.588011513801783},"point_estimate":6.748306093385109,"standard_error":1.4724741051773294},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":901.1957360509672,"upper_bound":903.585842519133},"point_estimate":902.472812520369,"standard_error":0.6090183269131836},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4.439515275927639,"upper_bound":5.441820158516582},"point_estimate":4.991077328728037,"standard_error":0.2556631284943815}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/sample.json new file mode 100644 index 00000000..243c63ab --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[5711.0,11422.0,17133.0,22844.0,28555.0,34266.0,39977.0,45688.0,51399.0,57110.0,62821.0,68532.0,74243.0,79954.0,85665.0,91376.0,97087.0,102798.0,108509.0,114220.0,119931.0,125642.0,131353.0,137064.0,142775.0,148486.0,154197.0,159908.0,165619.0,171330.0,177041.0,182752.0,188463.0,194174.0,199885.0,205596.0,211307.0,217018.0,222729.0,228440.0,234151.0,239862.0,245573.0,251284.0,256995.0,262706.0,268417.0,274128.0,279839.0,285550.0,291261.0,296972.0,302683.0,308394.0,314105.0,319816.0,325527.0,331238.0,336949.0,342660.0,348371.0,354082.0,359793.0,365504.0,371215.0,376926.0,382637.0,388348.0,394059.0,399770.0,405481.0,411192.0,416903.0,422614.0,428325.0,434036.0,439747.0,445458.0,451169.0,456880.0,462591.0,468302.0,474013.0,479724.0,485435.0,491146.0,496857.0,502568.0,508279.0,513990.0,519701.0,525412.0,531123.0,536834.0,542545.0,548256.0,553967.0,559678.0,565389.0,571100.0],"times":[5126800.0,10260500.0,15511500.0,20618500.0,25665400.0,30801800.0,36060200.0,41011800.0,46141300.0,51439000.0,56391100.0,61538300.0,66747300.0,71860300.0,77266100.0,82134700.0,87216600.0,92351700.0,97669400.0,102853900.0,107736500.0,112871300.0,118109100.0,123261400.0,128475700.0,133684000.0,138799000.0,143730900.0,148954000.0,154270200.0,159314000.0,164316300.0,169446300.0,175023700.0,180125100.0,185487600.0,190564800.0,195571500.0,200908300.0,205785500.0,209760800.0,214089700.0,219647400.0,224324900.0,229412600.0,234670100.0,239637300.0,244618000.0,249850100.0,255174000.0,259668000.0,264660100.0,270059600.0,274875500.0,279998200.0,285261400.0,290130600.0,295103800.0,300367100.0,306264900.0,313803200.0,319149600.0,324231100.0,329994000.0,334651000.0,341743000.0,346702100.0,352018700.0,356906300.0,362782100.0,367248500.0,373214500.0,377351400.0,383059300.0,388308800.0,393300000.0,398545300.0,403611300.0,408794500.0,413448500.0,418570100.0,424476100.0,429399900.0,434862600.0,439677600.0,445144100.0,450418200.0,455414000.0,460605800.0,465347300.0,470880900.0,476204000.0,481471700.0,486490300.0,491497600.0,496565700.0,499325300.0,502137100.0,507320600.0,512686100.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/tukey.json new file mode 100644 index 00000000..6d298fb1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/askama/new/tukey.json @@ -0,0 +1 @@ +[873.6762194081344,885.6919298172991,917.7338242417379,929.7495346509024] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/benchmark.json new file mode 100644 index 00000000..ffb4c88d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-fragment-heavy","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-fragment-heavy/tera","directory_name":"controlled-fragment-heavy/tera","title":"controlled-fragment-heavy/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/estimates.json new file mode 100644 index 00000000..33eeeb37 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":12118.85701443701,"upper_bound":12129.707166149177},"point_estimate":12124.366257788013,"standard_error":2.7756633382997733},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":12130.253919432504,"upper_bound":12141.743822387187},"point_estimate":12136.04605776737,"standard_error":3.01444243248425},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":14.354917348028925,"upper_bound":36.473761745825605},"point_estimate":21.71735324441671,"standard_error":5.729276805886297},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":12115.298427797872,"upper_bound":12130.148798566148},"point_estimate":12122.747338734713,"standard_error":3.7881497209276724},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":25.35106401642307,"upper_bound":29.70028251247198},"point_estimate":27.86997900183369,"standard_error":1.1085250377560831}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/sample.json new file mode 100644 index 00000000..600c0fea --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[427.0,854.0,1281.0,1708.0,2135.0,2562.0,2989.0,3416.0,3843.0,4270.0,4697.0,5124.0,5551.0,5978.0,6405.0,6832.0,7259.0,7686.0,8113.0,8540.0,8967.0,9394.0,9821.0,10248.0,10675.0,11102.0,11529.0,11956.0,12383.0,12810.0,13237.0,13664.0,14091.0,14518.0,14945.0,15372.0,15799.0,16226.0,16653.0,17080.0,17507.0,17934.0,18361.0,18788.0,19215.0,19642.0,20069.0,20496.0,20923.0,21350.0,21777.0,22204.0,22631.0,23058.0,23485.0,23912.0,24339.0,24766.0,25193.0,25620.0,26047.0,26474.0,26901.0,27328.0,27755.0,28182.0,28609.0,29036.0,29463.0,29890.0,30317.0,30744.0,31171.0,31598.0,32025.0,32452.0,32879.0,33306.0,33733.0,34160.0,34587.0,35014.0,35441.0,35868.0,36295.0,36722.0,37149.0,37576.0,38003.0,38430.0,38857.0,39284.0,39711.0,40138.0,40565.0,40992.0,41419.0,41846.0,42273.0,42700.0],"times":[5190300.0,10332500.0,15493900.0,20729200.0,25822000.0,30987500.0,36138800.0,41298600.0,46445100.0,51618100.0,56737000.0,61908800.0,67084400.0,72335100.0,77347300.0,82505300.0,87727000.0,93235100.0,98459900.0,103657500.0,108820900.0,114016700.0,119299000.0,124442600.0,129448300.0,134702200.0,140003000.0,145002600.0,150257900.0,155462500.0,160734800.0,165720300.0,170911200.0,176505600.0,181418400.0,186682200.0,192030100.0,197250900.0,202443900.0,207468400.0,212639800.0,217912500.0,222981500.0,228137200.0,233300300.0,238784600.0,243903600.0,249158100.0,254087200.0,259527200.0,264672000.0,269832700.0,274783700.0,279981000.0,285356500.0,290423100.0,295616500.0,300775300.0,306050000.0,311163000.0,316380400.0,321651000.0,326622700.0,332010900.0,337392300.0,340486800.0,345721600.0,351021600.0,356330000.0,361342800.0,366461400.0,371416100.0,376700700.0,382124000.0,387393700.0,392403500.0,397550800.0,402563000.0,407859100.0,412962200.0,418112200.0,425407400.0,430288200.0,435699200.0,441070900.0,446415100.0,451422000.0,456566000.0,461334700.0,466273400.0,471705000.0,476238800.0,481503200.0,486930300.0,492185800.0,497301000.0,502569400.0,505331700.0,510584600.0,515721500.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/tukey.json new file mode 100644 index 00000000..984c372d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/base/tukey.json @@ -0,0 +1 @@ +[11926.950567315347,12009.32108128726,12228.975785212362,12311.346299184275] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/change/estimates.json new file mode 100644 index 00000000..96cbc77d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.00805462470865334,"upper_bound":0.009260777740668191},"point_estimate":0.008683414039601933,"standard_error":0.0003091901526405989},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.009069636421876304,"upper_bound":0.010144380352693938},"point_estimate":0.009577451551123106,"standard_error":0.00027505063204824945}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/benchmark.json new file mode 100644 index 00000000..ffb4c88d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-fragment-heavy","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-fragment-heavy/tera","directory_name":"controlled-fragment-heavy/tera","title":"controlled-fragment-heavy/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/estimates.json new file mode 100644 index 00000000..33eeeb37 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":12118.85701443701,"upper_bound":12129.707166149177},"point_estimate":12124.366257788013,"standard_error":2.7756633382997733},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":12130.253919432504,"upper_bound":12141.743822387187},"point_estimate":12136.04605776737,"standard_error":3.01444243248425},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":14.354917348028925,"upper_bound":36.473761745825605},"point_estimate":21.71735324441671,"standard_error":5.729276805886297},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":12115.298427797872,"upper_bound":12130.148798566148},"point_estimate":12122.747338734713,"standard_error":3.7881497209276724},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":25.35106401642307,"upper_bound":29.70028251247198},"point_estimate":27.86997900183369,"standard_error":1.1085250377560831}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/sample.json new file mode 100644 index 00000000..600c0fea --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[427.0,854.0,1281.0,1708.0,2135.0,2562.0,2989.0,3416.0,3843.0,4270.0,4697.0,5124.0,5551.0,5978.0,6405.0,6832.0,7259.0,7686.0,8113.0,8540.0,8967.0,9394.0,9821.0,10248.0,10675.0,11102.0,11529.0,11956.0,12383.0,12810.0,13237.0,13664.0,14091.0,14518.0,14945.0,15372.0,15799.0,16226.0,16653.0,17080.0,17507.0,17934.0,18361.0,18788.0,19215.0,19642.0,20069.0,20496.0,20923.0,21350.0,21777.0,22204.0,22631.0,23058.0,23485.0,23912.0,24339.0,24766.0,25193.0,25620.0,26047.0,26474.0,26901.0,27328.0,27755.0,28182.0,28609.0,29036.0,29463.0,29890.0,30317.0,30744.0,31171.0,31598.0,32025.0,32452.0,32879.0,33306.0,33733.0,34160.0,34587.0,35014.0,35441.0,35868.0,36295.0,36722.0,37149.0,37576.0,38003.0,38430.0,38857.0,39284.0,39711.0,40138.0,40565.0,40992.0,41419.0,41846.0,42273.0,42700.0],"times":[5190300.0,10332500.0,15493900.0,20729200.0,25822000.0,30987500.0,36138800.0,41298600.0,46445100.0,51618100.0,56737000.0,61908800.0,67084400.0,72335100.0,77347300.0,82505300.0,87727000.0,93235100.0,98459900.0,103657500.0,108820900.0,114016700.0,119299000.0,124442600.0,129448300.0,134702200.0,140003000.0,145002600.0,150257900.0,155462500.0,160734800.0,165720300.0,170911200.0,176505600.0,181418400.0,186682200.0,192030100.0,197250900.0,202443900.0,207468400.0,212639800.0,217912500.0,222981500.0,228137200.0,233300300.0,238784600.0,243903600.0,249158100.0,254087200.0,259527200.0,264672000.0,269832700.0,274783700.0,279981000.0,285356500.0,290423100.0,295616500.0,300775300.0,306050000.0,311163000.0,316380400.0,321651000.0,326622700.0,332010900.0,337392300.0,340486800.0,345721600.0,351021600.0,356330000.0,361342800.0,366461400.0,371416100.0,376700700.0,382124000.0,387393700.0,392403500.0,397550800.0,402563000.0,407859100.0,412962200.0,418112200.0,425407400.0,430288200.0,435699200.0,441070900.0,446415100.0,451422000.0,456566000.0,461334700.0,466273400.0,471705000.0,476238800.0,481503200.0,486930300.0,492185800.0,497301000.0,502569400.0,505331700.0,510584600.0,515721500.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/tukey.json new file mode 100644 index 00000000..984c372d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-fragment-heavy/tera/new/tukey.json @@ -0,0 +1 @@ +[11926.950567315347,12009.32108128726,12228.975785212362,12311.346299184275] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/benchmark.json new file mode 100644 index 00000000..26723690 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-large-loop","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-large-loop/askama","directory_name":"controlled-large-loop/askama","title":"controlled-large-loop/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/estimates.json new file mode 100644 index 00000000..59592294 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":59957.6924787131,"upper_bound":61177.86084629213},"point_estimate":60567.68623804595,"standard_error":312.22628440368675},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":59620.30884904569,"upper_bound":63980.51753068974},"point_estimate":59641.982600732605,"standard_error":1046.23369550961},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":55.96187167386033,"upper_bound":4837.435510944591},"point_estimate":4154.541297121273,"standard_error":911.5500219650578},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":62207.960230192126,"upper_bound":63196.74926283883},"point_estimate":62745.339860376065,"standard_error":254.8639314877276},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2955.0928378836034,"upper_bound":3280.2113192024935},"point_estimate":3142.9751921345196,"standard_error":83.10861614919247}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/sample.json new file mode 100644 index 00000000..97bd8076 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[91.0,182.0,273.0,364.0,455.0,546.0,637.0,728.0,819.0,910.0,1001.0,1092.0,1183.0,1274.0,1365.0,1456.0,1547.0,1638.0,1729.0,1820.0,1911.0,2002.0,2093.0,2184.0,2275.0,2366.0,2457.0,2548.0,2639.0,2730.0,2821.0,2912.0,3003.0,3094.0,3185.0,3276.0,3367.0,3458.0,3549.0,3640.0,3731.0,3822.0,3913.0,4004.0,4095.0,4186.0,4277.0,4368.0,4459.0,4550.0,4641.0,4732.0,4823.0,4914.0,5005.0,5096.0,5187.0,5278.0,5369.0,5460.0,5551.0,5642.0,5733.0,5824.0,5915.0,6006.0,6097.0,6188.0,6279.0,6370.0,6461.0,6552.0,6643.0,6734.0,6825.0,6916.0,7007.0,7098.0,7189.0,7280.0,7371.0,7462.0,7553.0,7644.0,7735.0,7826.0,7917.0,8008.0,8099.0,8190.0,8281.0,8372.0,8463.0,8554.0,8645.0,8736.0,8827.0,8918.0,9009.0,9100.0],"times":[5173700.0,10341200.0,15527400.0,20688800.0,25838700.0,31029000.0,36216200.0,41382200.0,46563800.0,51754900.0,56903700.0,62069200.0,67247600.0,72413700.0,77559300.0,82718700.0,87909600.0,93182900.0,98368700.0,103553700.0,108785500.0,113929200.0,119085300.0,124286500.0,129467600.0,134649100.0,139828600.0,144978600.0,150190200.0,155350900.0,160531500.0,165661700.0,170838900.0,180233600.0,189908200.0,195333400.0,200769400.0,206157000.0,211643000.0,217101300.0,222445000.0,227900100.0,233393800.0,238755000.0,244240500.0,249606700.0,255128400.0,260510800.0,265984900.0,271285600.0,276648600.0,292479800.0,308636700.0,314475600.0,320280100.0,326107200.0,332060300.0,337739700.0,343585700.0,349379900.0,343151000.0,333183500.0,342058400.0,372620200.0,378457000.0,384295100.0,390076600.0,396033000.0,401883500.0,407692000.0,413447700.0,419302900.0,425149400.0,431044600.0,436794900.0,442652700.0,448416900.0,454192900.0,460035900.0,465897600.0,471683600.0,477571600.0,483425700.0,489161600.0,495107500.0,500925700.0,506725500.0,512605300.0,518455700.0,524213300.0,529923600.0,535902200.0,541739500.0,547609800.0,553341000.0,559237400.0,565119000.0,530742800.0,530526600.0,539794000.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/tukey.json new file mode 100644 index 00000000..056dbe41 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/base/tukey.json @@ -0,0 +1 @@ +[35635.8448847619,46270.76555357083,74630.55400372799,85265.47467253692] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/change/estimates.json new file mode 100644 index 00000000..6bbf115c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.0561501686345265,"upper_bound":0.07746572982694518},"point_estimate":0.06635305872317221,"standard_error":0.005311453336147673},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.04968564073116166,"upper_bound":0.12646857095834996},"point_estimate":0.05006755816603836,"standard_error":0.01847724806494392}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/benchmark.json new file mode 100644 index 00000000..26723690 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-large-loop","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-large-loop/askama","directory_name":"controlled-large-loop/askama","title":"controlled-large-loop/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/estimates.json new file mode 100644 index 00000000..59592294 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":59957.6924787131,"upper_bound":61177.86084629213},"point_estimate":60567.68623804595,"standard_error":312.22628440368675},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":59620.30884904569,"upper_bound":63980.51753068974},"point_estimate":59641.982600732605,"standard_error":1046.23369550961},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":55.96187167386033,"upper_bound":4837.435510944591},"point_estimate":4154.541297121273,"standard_error":911.5500219650578},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":62207.960230192126,"upper_bound":63196.74926283883},"point_estimate":62745.339860376065,"standard_error":254.8639314877276},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2955.0928378836034,"upper_bound":3280.2113192024935},"point_estimate":3142.9751921345196,"standard_error":83.10861614919247}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/sample.json new file mode 100644 index 00000000..97bd8076 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[91.0,182.0,273.0,364.0,455.0,546.0,637.0,728.0,819.0,910.0,1001.0,1092.0,1183.0,1274.0,1365.0,1456.0,1547.0,1638.0,1729.0,1820.0,1911.0,2002.0,2093.0,2184.0,2275.0,2366.0,2457.0,2548.0,2639.0,2730.0,2821.0,2912.0,3003.0,3094.0,3185.0,3276.0,3367.0,3458.0,3549.0,3640.0,3731.0,3822.0,3913.0,4004.0,4095.0,4186.0,4277.0,4368.0,4459.0,4550.0,4641.0,4732.0,4823.0,4914.0,5005.0,5096.0,5187.0,5278.0,5369.0,5460.0,5551.0,5642.0,5733.0,5824.0,5915.0,6006.0,6097.0,6188.0,6279.0,6370.0,6461.0,6552.0,6643.0,6734.0,6825.0,6916.0,7007.0,7098.0,7189.0,7280.0,7371.0,7462.0,7553.0,7644.0,7735.0,7826.0,7917.0,8008.0,8099.0,8190.0,8281.0,8372.0,8463.0,8554.0,8645.0,8736.0,8827.0,8918.0,9009.0,9100.0],"times":[5173700.0,10341200.0,15527400.0,20688800.0,25838700.0,31029000.0,36216200.0,41382200.0,46563800.0,51754900.0,56903700.0,62069200.0,67247600.0,72413700.0,77559300.0,82718700.0,87909600.0,93182900.0,98368700.0,103553700.0,108785500.0,113929200.0,119085300.0,124286500.0,129467600.0,134649100.0,139828600.0,144978600.0,150190200.0,155350900.0,160531500.0,165661700.0,170838900.0,180233600.0,189908200.0,195333400.0,200769400.0,206157000.0,211643000.0,217101300.0,222445000.0,227900100.0,233393800.0,238755000.0,244240500.0,249606700.0,255128400.0,260510800.0,265984900.0,271285600.0,276648600.0,292479800.0,308636700.0,314475600.0,320280100.0,326107200.0,332060300.0,337739700.0,343585700.0,349379900.0,343151000.0,333183500.0,342058400.0,372620200.0,378457000.0,384295100.0,390076600.0,396033000.0,401883500.0,407692000.0,413447700.0,419302900.0,425149400.0,431044600.0,436794900.0,442652700.0,448416900.0,454192900.0,460035900.0,465897600.0,471683600.0,477571600.0,483425700.0,489161600.0,495107500.0,500925700.0,506725500.0,512605300.0,518455700.0,524213300.0,529923600.0,535902200.0,541739500.0,547609800.0,553341000.0,559237400.0,565119000.0,530742800.0,530526600.0,539794000.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/tukey.json new file mode 100644 index 00000000..056dbe41 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/askama/new/tukey.json @@ -0,0 +1 @@ +[35635.8448847619,46270.76555357083,74630.55400372799,85265.47467253692] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/benchmark.json new file mode 100644 index 00000000..454cdb23 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-large-loop","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-large-loop/tera","directory_name":"controlled-large-loop/tera","title":"controlled-large-loop/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/estimates.json new file mode 100644 index 00000000..584271ee --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":328361.5003753428,"upper_bound":328627.89213856263},"point_estimate":328491.2143819996,"standard_error":68.19200037320726},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":328291.45014044945,"upper_bound":328490.09146341466},"point_estimate":328349.25426136365,"standard_error":50.82645295638078},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":504.2752815512351,"upper_bound":808.1823256246103},"point_estimate":649.9376299149125,"standard_error":72.76724831777453},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":328457.74996724125,"upper_bound":328760.3440347066},"point_estimate":328599.1660632481,"standard_error":77.01129287125109},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":564.0229928494123,"upper_bound":800.9819647090233},"point_estimate":683.1563919927374,"standard_error":60.769448240076166}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/sample.json new file mode 100644 index 00000000..602954cb --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[16.0,32.0,48.0,64.0,80.0,96.0,112.0,128.0,144.0,160.0,176.0,192.0,208.0,224.0,240.0,256.0,272.0,288.0,304.0,320.0,336.0,352.0,368.0,384.0,400.0,416.0,432.0,448.0,464.0,480.0,496.0,512.0,528.0,544.0,560.0,576.0,592.0,608.0,624.0,640.0,656.0,672.0,688.0,704.0,720.0,736.0,752.0,768.0,784.0,800.0,816.0,832.0,848.0,864.0,880.0,896.0,912.0,928.0,944.0,960.0,976.0,992.0,1008.0,1024.0,1040.0,1056.0,1072.0,1088.0,1104.0,1120.0,1136.0,1152.0,1168.0,1184.0,1200.0,1216.0,1232.0,1248.0,1264.0,1280.0,1296.0,1312.0,1328.0,1344.0,1360.0,1376.0,1392.0,1408.0,1424.0,1440.0,1456.0,1472.0,1488.0,1504.0,1520.0,1536.0,1552.0,1568.0,1584.0,1600.0],"times":[5253000.0,10541800.0,15732500.0,20980900.0,26228000.0,31475900.0,36688500.0,41999000.0,47218600.0,52443800.0,57705000.0,63004900.0,68287700.0,73479400.0,78692200.0,83922900.0,89201800.0,94376900.0,99762100.0,104766500.0,110065500.0,115420000.0,120680900.0,125859100.0,131130800.0,136291800.0,141689100.0,146843100.0,152124100.0,157491200.0,162625100.0,167726600.0,173045600.0,178618000.0,183882500.0,189470100.0,194482200.0,199636800.0,205092200.0,210154700.0,215489500.0,220853100.0,225972400.0,231235700.0,236533800.0,241744300.0,247048700.0,252296000.0,257475400.0,263421200.0,268615800.0,273843200.0,279361300.0,284409700.0,289743000.0,294899100.0,300727100.0,306110900.0,311313900.0,316840800.0,321994300.0,327138500.0,333803300.0,337659700.0,342938600.0,347808200.0,352993800.0,358306800.0,363381100.0,368082700.0,373397100.0,378626600.0,384088500.0,389278300.0,394748500.0,399686100.0,405100400.0,410103100.0,415607000.0,420804200.0,426029500.0,430597500.0,435996100.0,441272300.0,446485800.0,451667100.0,457059400.0,462314700.0,467497100.0,472729500.0,478041600.0,483354500.0,488615200.0,493346300.0,498250900.0,503675500.0,509044600.0,514276900.0,519406300.0,524869300.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/tukey.json new file mode 100644 index 00000000..a8be6dbe --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/base/tukey.json @@ -0,0 +1 @@ +[325307.21271607425,326619.284078259,330118.14104408515,331430.21240627] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/change/estimates.json new file mode 100644 index 00000000..38176d27 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.005578045164569337,"upper_bound":-0.004503084469092664},"point_estimate":-0.0050278584676504146,"standard_error":0.00027505756956312083},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.006525599205271182,"upper_bound":-0.004222445148477139},"point_estimate":-0.004911074739869181,"standard_error":0.000632028322426423}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/benchmark.json new file mode 100644 index 00000000..454cdb23 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-large-loop","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-large-loop/tera","directory_name":"controlled-large-loop/tera","title":"controlled-large-loop/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/estimates.json new file mode 100644 index 00000000..584271ee --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":328361.5003753428,"upper_bound":328627.89213856263},"point_estimate":328491.2143819996,"standard_error":68.19200037320726},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":328291.45014044945,"upper_bound":328490.09146341466},"point_estimate":328349.25426136365,"standard_error":50.82645295638078},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":504.2752815512351,"upper_bound":808.1823256246103},"point_estimate":649.9376299149125,"standard_error":72.76724831777453},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":328457.74996724125,"upper_bound":328760.3440347066},"point_estimate":328599.1660632481,"standard_error":77.01129287125109},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":564.0229928494123,"upper_bound":800.9819647090233},"point_estimate":683.1563919927374,"standard_error":60.769448240076166}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/sample.json new file mode 100644 index 00000000..602954cb --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[16.0,32.0,48.0,64.0,80.0,96.0,112.0,128.0,144.0,160.0,176.0,192.0,208.0,224.0,240.0,256.0,272.0,288.0,304.0,320.0,336.0,352.0,368.0,384.0,400.0,416.0,432.0,448.0,464.0,480.0,496.0,512.0,528.0,544.0,560.0,576.0,592.0,608.0,624.0,640.0,656.0,672.0,688.0,704.0,720.0,736.0,752.0,768.0,784.0,800.0,816.0,832.0,848.0,864.0,880.0,896.0,912.0,928.0,944.0,960.0,976.0,992.0,1008.0,1024.0,1040.0,1056.0,1072.0,1088.0,1104.0,1120.0,1136.0,1152.0,1168.0,1184.0,1200.0,1216.0,1232.0,1248.0,1264.0,1280.0,1296.0,1312.0,1328.0,1344.0,1360.0,1376.0,1392.0,1408.0,1424.0,1440.0,1456.0,1472.0,1488.0,1504.0,1520.0,1536.0,1552.0,1568.0,1584.0,1600.0],"times":[5253000.0,10541800.0,15732500.0,20980900.0,26228000.0,31475900.0,36688500.0,41999000.0,47218600.0,52443800.0,57705000.0,63004900.0,68287700.0,73479400.0,78692200.0,83922900.0,89201800.0,94376900.0,99762100.0,104766500.0,110065500.0,115420000.0,120680900.0,125859100.0,131130800.0,136291800.0,141689100.0,146843100.0,152124100.0,157491200.0,162625100.0,167726600.0,173045600.0,178618000.0,183882500.0,189470100.0,194482200.0,199636800.0,205092200.0,210154700.0,215489500.0,220853100.0,225972400.0,231235700.0,236533800.0,241744300.0,247048700.0,252296000.0,257475400.0,263421200.0,268615800.0,273843200.0,279361300.0,284409700.0,289743000.0,294899100.0,300727100.0,306110900.0,311313900.0,316840800.0,321994300.0,327138500.0,333803300.0,337659700.0,342938600.0,347808200.0,352993800.0,358306800.0,363381100.0,368082700.0,373397100.0,378626600.0,384088500.0,389278300.0,394748500.0,399686100.0,405100400.0,410103100.0,415607000.0,420804200.0,426029500.0,430597500.0,435996100.0,441272300.0,446485800.0,451667100.0,457059400.0,462314700.0,467497100.0,472729500.0,478041600.0,483354500.0,488615200.0,493346300.0,498250900.0,503675500.0,509044600.0,514276900.0,519406300.0,524869300.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/tukey.json new file mode 100644 index 00000000..a8be6dbe --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-large-loop/tera/new/tukey.json @@ -0,0 +1 @@ +[325307.21271607425,326619.284078259,330118.14104408515,331430.21240627] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/benchmark.json new file mode 100644 index 00000000..2f0c0f6e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-mixed-page","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-mixed-page/askama","directory_name":"controlled-mixed-page/askama","title":"controlled-mixed-page/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/estimates.json new file mode 100644 index 00000000..bfd37448 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1107.6793492767767,"upper_bound":1109.0913020743064},"point_estimate":1108.3674706032527,"standard_error":0.359941429059245},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1107.4835347445166,"upper_bound":1108.6528444280384},"point_estimate":1108.0782834370166,"standard_error":0.3294075917483078},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2.4541352800927454,"upper_bound":4.5542434053646454},"point_estimate":3.3374968714892694,"standard_error":0.5426378796851564},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1106.7001754478495,"upper_bound":1109.0673530137033},"point_estimate":1107.7972135001305,"standard_error":0.6080894685877063},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2.934412734172169,"upper_bound":4.19187762289311},"point_estimate":3.5924109044143164,"standard_error":0.3209968293986909}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/sample.json new file mode 100644 index 00000000..b08cb650 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[4644.0,9288.0,13932.0,18576.0,23220.0,27864.0,32508.0,37152.0,41796.0,46440.0,51084.0,55728.0,60372.0,65016.0,69660.0,74304.0,78948.0,83592.0,88236.0,92880.0,97524.0,102168.0,106812.0,111456.0,116100.0,120744.0,125388.0,130032.0,134676.0,139320.0,143964.0,148608.0,153252.0,157896.0,162540.0,167184.0,171828.0,176472.0,181116.0,185760.0,190404.0,195048.0,199692.0,204336.0,208980.0,213624.0,218268.0,222912.0,227556.0,232200.0,236844.0,241488.0,246132.0,250776.0,255420.0,260064.0,264708.0,269352.0,273996.0,278640.0,283284.0,287928.0,292572.0,297216.0,301860.0,306504.0,311148.0,315792.0,320436.0,325080.0,329724.0,334368.0,339012.0,343656.0,348300.0,352944.0,357588.0,362232.0,366876.0,371520.0,376164.0,380808.0,385452.0,390096.0,394740.0,399384.0,404028.0,408672.0,413316.0,417960.0,422604.0,427248.0,431892.0,436536.0,441180.0,445824.0,450468.0,455112.0,459756.0,464400.0],"times":[5125900.0,10289500.0,15431100.0,20606500.0,25707400.0,30890300.0,35988800.0,41068200.0,46246000.0,51622200.0,56466000.0,61760300.0,66923300.0,71925600.0,77166600.0,82379700.0,87213900.0,92423700.0,97628600.0,102978100.0,107860400.0,113143100.0,118395700.0,123276100.0,128702400.0,133793600.0,138812400.0,144051800.0,149305800.0,154780400.0,159452200.0,164653200.0,169691900.0,174959000.0,180195900.0,185163800.0,190965200.0,195635100.0,200875000.0,206185200.0,211532400.0,215978100.0,221251400.0,226559900.0,231692100.0,236797500.0,241858400.0,247400300.0,251840900.0,258410800.0,262849100.0,268210200.0,272951700.0,278446600.0,283327200.0,289069300.0,294300300.0,299252700.0,304720500.0,309862800.0,314519200.0,319678400.0,325704700.0,330464000.0,335503800.0,340809300.0,345473500.0,350989200.0,356202700.0,360491600.0,366461500.0,372860300.0,379109000.0,384735300.0,389962900.0,394651400.0,399144200.0,399951900.0,404953500.0,410271800.0,416162000.0,420453700.0,425437300.0,430895500.0,435874400.0,440725300.0,445880500.0,450606500.0,456000400.0,461880000.0,466345400.0,471846300.0,476652500.0,482028100.0,487203600.0,492344100.0,497071200.0,503385100.0,508066900.0,514230100.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/tukey.json new file mode 100644 index 00000000..71bfbe54 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/base/tukey.json @@ -0,0 +1 @@ +[1092.6448466008424,1099.2745812307767,1116.9538735772685,1123.583608207203] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/change/estimates.json new file mode 100644 index 00000000..6fb3f93e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.004484179363630441,"upper_bound":0.005994743981829758},"point_estimate":0.005214293525868774,"standard_error":0.00038579021205401086},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.004641789515927197,"upper_bound":0.005996314512981549},"point_estimate":0.005346211509116516,"standard_error":0.00036003567994488726}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/benchmark.json new file mode 100644 index 00000000..2f0c0f6e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-mixed-page","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-mixed-page/askama","directory_name":"controlled-mixed-page/askama","title":"controlled-mixed-page/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/estimates.json new file mode 100644 index 00000000..bfd37448 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1107.6793492767767,"upper_bound":1109.0913020743064},"point_estimate":1108.3674706032527,"standard_error":0.359941429059245},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1107.4835347445166,"upper_bound":1108.6528444280384},"point_estimate":1108.0782834370166,"standard_error":0.3294075917483078},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2.4541352800927454,"upper_bound":4.5542434053646454},"point_estimate":3.3374968714892694,"standard_error":0.5426378796851564},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1106.7001754478495,"upper_bound":1109.0673530137033},"point_estimate":1107.7972135001305,"standard_error":0.6080894685877063},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2.934412734172169,"upper_bound":4.19187762289311},"point_estimate":3.5924109044143164,"standard_error":0.3209968293986909}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/sample.json new file mode 100644 index 00000000..b08cb650 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[4644.0,9288.0,13932.0,18576.0,23220.0,27864.0,32508.0,37152.0,41796.0,46440.0,51084.0,55728.0,60372.0,65016.0,69660.0,74304.0,78948.0,83592.0,88236.0,92880.0,97524.0,102168.0,106812.0,111456.0,116100.0,120744.0,125388.0,130032.0,134676.0,139320.0,143964.0,148608.0,153252.0,157896.0,162540.0,167184.0,171828.0,176472.0,181116.0,185760.0,190404.0,195048.0,199692.0,204336.0,208980.0,213624.0,218268.0,222912.0,227556.0,232200.0,236844.0,241488.0,246132.0,250776.0,255420.0,260064.0,264708.0,269352.0,273996.0,278640.0,283284.0,287928.0,292572.0,297216.0,301860.0,306504.0,311148.0,315792.0,320436.0,325080.0,329724.0,334368.0,339012.0,343656.0,348300.0,352944.0,357588.0,362232.0,366876.0,371520.0,376164.0,380808.0,385452.0,390096.0,394740.0,399384.0,404028.0,408672.0,413316.0,417960.0,422604.0,427248.0,431892.0,436536.0,441180.0,445824.0,450468.0,455112.0,459756.0,464400.0],"times":[5125900.0,10289500.0,15431100.0,20606500.0,25707400.0,30890300.0,35988800.0,41068200.0,46246000.0,51622200.0,56466000.0,61760300.0,66923300.0,71925600.0,77166600.0,82379700.0,87213900.0,92423700.0,97628600.0,102978100.0,107860400.0,113143100.0,118395700.0,123276100.0,128702400.0,133793600.0,138812400.0,144051800.0,149305800.0,154780400.0,159452200.0,164653200.0,169691900.0,174959000.0,180195900.0,185163800.0,190965200.0,195635100.0,200875000.0,206185200.0,211532400.0,215978100.0,221251400.0,226559900.0,231692100.0,236797500.0,241858400.0,247400300.0,251840900.0,258410800.0,262849100.0,268210200.0,272951700.0,278446600.0,283327200.0,289069300.0,294300300.0,299252700.0,304720500.0,309862800.0,314519200.0,319678400.0,325704700.0,330464000.0,335503800.0,340809300.0,345473500.0,350989200.0,356202700.0,360491600.0,366461500.0,372860300.0,379109000.0,384735300.0,389962900.0,394651400.0,399144200.0,399951900.0,404953500.0,410271800.0,416162000.0,420453700.0,425437300.0,430895500.0,435874400.0,440725300.0,445880500.0,450606500.0,456000400.0,461880000.0,466345400.0,471846300.0,476652500.0,482028100.0,487203600.0,492344100.0,497071200.0,503385100.0,508066900.0,514230100.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/tukey.json new file mode 100644 index 00000000..71bfbe54 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/askama/new/tukey.json @@ -0,0 +1 @@ +[1092.6448466008424,1099.2745812307767,1116.9538735772685,1123.583608207203] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/benchmark.json new file mode 100644 index 00000000..24eebf4f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-mixed-page","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-mixed-page/tera","directory_name":"controlled-mixed-page/tera","title":"controlled-mixed-page/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/estimates.json new file mode 100644 index 00000000..379a2950 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5697.26352456682,"upper_bound":5705.14410027452},"point_estimate":5701.152483330889,"standard_error":2.0110783342550285},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5695.171928250884,"upper_bound":5705.579392982708},"point_estimate":5698.606544628306,"standard_error":2.502248562556382},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":13.882586125542119,"upper_bound":21.212645569193754},"point_estimate":17.969893300126294,"standard_error":1.8763482770629814},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5708.742804398113,"upper_bound":5719.660611386159},"point_estimate":5714.40282488874,"standard_error":2.777987037892972},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":17.21164349096849,"upper_bound":23.002877034315414},"point_estimate":20.282549078857862,"standard_error":1.473931333242165}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/sample.json new file mode 100644 index 00000000..427123c4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[905.0,1810.0,2715.0,3620.0,4525.0,5430.0,6335.0,7240.0,8145.0,9050.0,9955.0,10860.0,11765.0,12670.0,13575.0,14480.0,15385.0,16290.0,17195.0,18100.0,19005.0,19910.0,20815.0,21720.0,22625.0,23530.0,24435.0,25340.0,26245.0,27150.0,28055.0,28960.0,29865.0,30770.0,31675.0,32580.0,33485.0,34390.0,35295.0,36200.0,37105.0,38010.0,38915.0,39820.0,40725.0,41630.0,42535.0,43440.0,44345.0,45250.0,46155.0,47060.0,47965.0,48870.0,49775.0,50680.0,51585.0,52490.0,53395.0,54300.0,55205.0,56110.0,57015.0,57920.0,58825.0,59730.0,60635.0,61540.0,62445.0,63350.0,64255.0,65160.0,66065.0,66970.0,67875.0,68780.0,69685.0,70590.0,71495.0,72400.0,73305.0,74210.0,75115.0,76020.0,76925.0,77830.0,78735.0,79640.0,80545.0,81450.0,82355.0,83260.0,84165.0,85070.0,85975.0,86880.0,87785.0,88690.0,89595.0,90500.0],"times":[5166400.0,10305400.0,15494000.0,20609900.0,25799500.0,30970300.0,35996400.0,41182500.0,46338500.0,51219000.0,56340800.0,61605600.0,66782100.0,72263200.0,77255200.0,82377500.0,87413600.0,92625800.0,97886500.0,102888500.0,107845400.0,113446900.0,118786000.0,123630900.0,129205400.0,134282200.0,139007900.0,144267700.0,149513700.0,154811400.0,159831900.0,164994900.0,170054000.0,174409600.0,179150700.0,185273000.0,190103600.0,195339100.0,200332700.0,206064800.0,211122400.0,216072900.0,220433800.0,225665100.0,231511900.0,236878100.0,241565100.0,246971800.0,252560900.0,258421100.0,263513000.0,268789300.0,274141400.0,278400500.0,283326800.0,288379900.0,294697300.0,299728900.0,304447100.0,308824800.0,314513400.0,320352800.0,323917700.0,330176000.0,335933000.0,340468500.0,346045100.0,351685000.0,357423600.0,361824400.0,368266200.0,372364100.0,377620700.0,381564700.0,387791700.0,391931200.0,397593300.0,403207500.0,407984900.0,413871300.0,417536300.0,424673900.0,428962800.0,433445400.0,437596200.0,443544000.0,449306700.0,455122400.0,462237100.0,466753600.0,472791100.0,478249100.0,482834300.0,487782400.0,492822000.0,499365200.0,504767000.0,510238000.0,513351700.0,518705800.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/tukey.json new file mode 100644 index 00000000..eee6b5d4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/base/tukey.json @@ -0,0 +1 @@ +[5620.634320947531,5654.725007222041,5745.633503954068,5779.724190228578] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/change/estimates.json new file mode 100644 index 00000000..a2f0555c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.01620139520709702,"upper_bound":-0.012557776988471245},"point_estimate":-0.014414896628624607,"standard_error":0.0009321056075981378},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.020287224819504963,"upper_bound":-0.01167478301131697},"point_estimate":-0.019010480101830374,"standard_error":0.0019225597830077072}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/benchmark.json new file mode 100644 index 00000000..24eebf4f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-mixed-page","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-mixed-page/tera","directory_name":"controlled-mixed-page/tera","title":"controlled-mixed-page/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/estimates.json new file mode 100644 index 00000000..379a2950 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5697.26352456682,"upper_bound":5705.14410027452},"point_estimate":5701.152483330889,"standard_error":2.0110783342550285},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5695.171928250884,"upper_bound":5705.579392982708},"point_estimate":5698.606544628306,"standard_error":2.502248562556382},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":13.882586125542119,"upper_bound":21.212645569193754},"point_estimate":17.969893300126294,"standard_error":1.8763482770629814},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5708.742804398113,"upper_bound":5719.660611386159},"point_estimate":5714.40282488874,"standard_error":2.777987037892972},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":17.21164349096849,"upper_bound":23.002877034315414},"point_estimate":20.282549078857862,"standard_error":1.473931333242165}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/sample.json new file mode 100644 index 00000000..427123c4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[905.0,1810.0,2715.0,3620.0,4525.0,5430.0,6335.0,7240.0,8145.0,9050.0,9955.0,10860.0,11765.0,12670.0,13575.0,14480.0,15385.0,16290.0,17195.0,18100.0,19005.0,19910.0,20815.0,21720.0,22625.0,23530.0,24435.0,25340.0,26245.0,27150.0,28055.0,28960.0,29865.0,30770.0,31675.0,32580.0,33485.0,34390.0,35295.0,36200.0,37105.0,38010.0,38915.0,39820.0,40725.0,41630.0,42535.0,43440.0,44345.0,45250.0,46155.0,47060.0,47965.0,48870.0,49775.0,50680.0,51585.0,52490.0,53395.0,54300.0,55205.0,56110.0,57015.0,57920.0,58825.0,59730.0,60635.0,61540.0,62445.0,63350.0,64255.0,65160.0,66065.0,66970.0,67875.0,68780.0,69685.0,70590.0,71495.0,72400.0,73305.0,74210.0,75115.0,76020.0,76925.0,77830.0,78735.0,79640.0,80545.0,81450.0,82355.0,83260.0,84165.0,85070.0,85975.0,86880.0,87785.0,88690.0,89595.0,90500.0],"times":[5166400.0,10305400.0,15494000.0,20609900.0,25799500.0,30970300.0,35996400.0,41182500.0,46338500.0,51219000.0,56340800.0,61605600.0,66782100.0,72263200.0,77255200.0,82377500.0,87413600.0,92625800.0,97886500.0,102888500.0,107845400.0,113446900.0,118786000.0,123630900.0,129205400.0,134282200.0,139007900.0,144267700.0,149513700.0,154811400.0,159831900.0,164994900.0,170054000.0,174409600.0,179150700.0,185273000.0,190103600.0,195339100.0,200332700.0,206064800.0,211122400.0,216072900.0,220433800.0,225665100.0,231511900.0,236878100.0,241565100.0,246971800.0,252560900.0,258421100.0,263513000.0,268789300.0,274141400.0,278400500.0,283326800.0,288379900.0,294697300.0,299728900.0,304447100.0,308824800.0,314513400.0,320352800.0,323917700.0,330176000.0,335933000.0,340468500.0,346045100.0,351685000.0,357423600.0,361824400.0,368266200.0,372364100.0,377620700.0,381564700.0,387791700.0,391931200.0,397593300.0,403207500.0,407984900.0,413871300.0,417536300.0,424673900.0,428962800.0,433445400.0,437596200.0,443544000.0,449306700.0,455122400.0,462237100.0,466753600.0,472791100.0,478249100.0,482834300.0,487782400.0,492822000.0,499365200.0,504767000.0,510238000.0,513351700.0,518705800.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/tukey.json new file mode 100644 index 00000000..eee6b5d4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-mixed-page/tera/new/tukey.json @@ -0,0 +1 @@ +[5620.634320947531,5654.725007222041,5745.633503954068,5779.724190228578] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/benchmark.json new file mode 100644 index 00000000..5c7f7b54 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-trivial-substitution","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-trivial-substitution/askama","directory_name":"controlled-trivial-substitution/askama","title":"controlled-trivial-substitution/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/estimates.json new file mode 100644 index 00000000..9fdba747 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":85.90335450639394,"upper_bound":86.13379683157363},"point_estimate":86.00877645588075,"standard_error":0.05898705925807873},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":85.95682624607554,"upper_bound":86.0046239615413},"point_estimate":85.9887318295375,"standard_error":0.011883476125082872},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.08481579764766482,"upper_bound":0.14490544641328673},"point_estimate":0.11900908548810232,"standard_error":0.015383526530097844},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":85.94475015754983,"upper_bound":86.51019525686839},"point_estimate":86.20781662002578,"standard_error":0.1443481750416636},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.2846988203411018,"upper_bound":0.8227952760135071},"point_estimate":0.5940718990926456,"standard_error":0.12992778568163224}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/sample.json new file mode 100644 index 00000000..1443e99f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[59810.0,119620.0,179430.0,239240.0,299050.0,358860.0,418670.0,478480.0,538290.0,598100.0,657910.0,717720.0,777530.0,837340.0,897150.0,956960.0,1016770.0,1076580.0,1136390.0,1196200.0,1256010.0,1315820.0,1375630.0,1435440.0,1495250.0,1555060.0,1614870.0,1674680.0,1734490.0,1794300.0,1854110.0,1913920.0,1973730.0,2033540.0,2093350.0,2153160.0,2212970.0,2272780.0,2332590.0,2392400.0,2452210.0,2512020.0,2571830.0,2631640.0,2691450.0,2751260.0,2811070.0,2870880.0,2930690.0,2990500.0,3050310.0,3110120.0,3169930.0,3229740.0,3289550.0,3349360.0,3409170.0,3468980.0,3528790.0,3588600.0,3648410.0,3708220.0,3768030.0,3827840.0,3887650.0,3947460.0,4007270.0,4067080.0,4126890.0,4186700.0,4246510.0,4306320.0,4366130.0,4425940.0,4485750.0,4545560.0,4605370.0,4665180.0,4724990.0,4784800.0,4844610.0,4904420.0,4964230.0,5024040.0,5083850.0,5143660.0,5203470.0,5263280.0,5323090.0,5382900.0,5442710.0,5502520.0,5562330.0,5622140.0,5681950.0,5741760.0,5801570.0,5861380.0,5921190.0,5981000.0],"times":[5122200.0,10279700.0,15431100.0,20570400.0,25723100.0,30865900.0,35999300.0,41144600.0,46269700.0,51407100.0,56556200.0,61706600.0,66870400.0,71997000.0,77159200.0,82271400.0,87426100.0,92615900.0,97798400.0,102943600.0,108078100.0,113246000.0,118389900.0,123547600.0,128724400.0,133812200.0,139040900.0,144135000.0,149237200.0,154403700.0,159597900.0,164721500.0,169918200.0,174699300.0,179812700.0,184955800.0,190084400.0,195225100.0,200371400.0,205517300.0,210654100.0,215763600.0,220893500.0,226069600.0,231245100.0,236359100.0,241473600.0,246625500.0,251134100.0,254789000.0,259953500.0,265210900.0,270609300.0,275757300.0,280857600.0,286114400.0,291271500.0,296382900.0,301401500.0,306511100.0,311647600.0,316759900.0,321811300.0,327047800.0,332126200.0,339283800.0,344432900.0,349551500.0,354859900.0,361836300.0,366925000.0,372074600.0,377331500.0,382529600.0,387753900.0,392809500.0,398105400.0,403206000.0,406877600.0,410157500.0,415364000.0,421735500.0,426847600.0,432123400.0,437229600.0,442377200.0,447473400.0,452750200.0,457804800.0,463001600.0,468108200.0,473272200.0,478386100.0,483542900.0,488662000.0,493837500.0,499050300.0,521549300.0,526770500.0,532086400.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/tukey.json new file mode 100644 index 00000000..91cc6d01 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/base/tukey.json @@ -0,0 +1 @@ +[85.4454877870277,85.67226957404188,86.27702100607968,86.50380279309385] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/change/estimates.json new file mode 100644 index 00000000..8a046045 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.0603940816807824,"upper_bound":-0.008740357654821248},"point_estimate":-0.027238278384976833,"standard_error":0.016146878016013326},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.013352107902812271,"upper_bound":-0.008764552032323292},"point_estimate":-0.011693707500012973,"standard_error":0.001614559079907907}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/benchmark.json new file mode 100644 index 00000000..5c7f7b54 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-trivial-substitution","function_id":"askama","value_str":null,"throughput":null,"full_id":"controlled-trivial-substitution/askama","directory_name":"controlled-trivial-substitution/askama","title":"controlled-trivial-substitution/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/estimates.json new file mode 100644 index 00000000..9fdba747 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":85.90335450639394,"upper_bound":86.13379683157363},"point_estimate":86.00877645588075,"standard_error":0.05898705925807873},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":85.95682624607554,"upper_bound":86.0046239615413},"point_estimate":85.9887318295375,"standard_error":0.011883476125082872},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.08481579764766482,"upper_bound":0.14490544641328673},"point_estimate":0.11900908548810232,"standard_error":0.015383526530097844},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":85.94475015754983,"upper_bound":86.51019525686839},"point_estimate":86.20781662002578,"standard_error":0.1443481750416636},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.2846988203411018,"upper_bound":0.8227952760135071},"point_estimate":0.5940718990926456,"standard_error":0.12992778568163224}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/sample.json new file mode 100644 index 00000000..1443e99f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[59810.0,119620.0,179430.0,239240.0,299050.0,358860.0,418670.0,478480.0,538290.0,598100.0,657910.0,717720.0,777530.0,837340.0,897150.0,956960.0,1016770.0,1076580.0,1136390.0,1196200.0,1256010.0,1315820.0,1375630.0,1435440.0,1495250.0,1555060.0,1614870.0,1674680.0,1734490.0,1794300.0,1854110.0,1913920.0,1973730.0,2033540.0,2093350.0,2153160.0,2212970.0,2272780.0,2332590.0,2392400.0,2452210.0,2512020.0,2571830.0,2631640.0,2691450.0,2751260.0,2811070.0,2870880.0,2930690.0,2990500.0,3050310.0,3110120.0,3169930.0,3229740.0,3289550.0,3349360.0,3409170.0,3468980.0,3528790.0,3588600.0,3648410.0,3708220.0,3768030.0,3827840.0,3887650.0,3947460.0,4007270.0,4067080.0,4126890.0,4186700.0,4246510.0,4306320.0,4366130.0,4425940.0,4485750.0,4545560.0,4605370.0,4665180.0,4724990.0,4784800.0,4844610.0,4904420.0,4964230.0,5024040.0,5083850.0,5143660.0,5203470.0,5263280.0,5323090.0,5382900.0,5442710.0,5502520.0,5562330.0,5622140.0,5681950.0,5741760.0,5801570.0,5861380.0,5921190.0,5981000.0],"times":[5122200.0,10279700.0,15431100.0,20570400.0,25723100.0,30865900.0,35999300.0,41144600.0,46269700.0,51407100.0,56556200.0,61706600.0,66870400.0,71997000.0,77159200.0,82271400.0,87426100.0,92615900.0,97798400.0,102943600.0,108078100.0,113246000.0,118389900.0,123547600.0,128724400.0,133812200.0,139040900.0,144135000.0,149237200.0,154403700.0,159597900.0,164721500.0,169918200.0,174699300.0,179812700.0,184955800.0,190084400.0,195225100.0,200371400.0,205517300.0,210654100.0,215763600.0,220893500.0,226069600.0,231245100.0,236359100.0,241473600.0,246625500.0,251134100.0,254789000.0,259953500.0,265210900.0,270609300.0,275757300.0,280857600.0,286114400.0,291271500.0,296382900.0,301401500.0,306511100.0,311647600.0,316759900.0,321811300.0,327047800.0,332126200.0,339283800.0,344432900.0,349551500.0,354859900.0,361836300.0,366925000.0,372074600.0,377331500.0,382529600.0,387753900.0,392809500.0,398105400.0,403206000.0,406877600.0,410157500.0,415364000.0,421735500.0,426847600.0,432123400.0,437229600.0,442377200.0,447473400.0,452750200.0,457804800.0,463001600.0,468108200.0,473272200.0,478386100.0,483542900.0,488662000.0,493837500.0,499050300.0,521549300.0,526770500.0,532086400.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/tukey.json new file mode 100644 index 00000000..91cc6d01 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/askama/new/tukey.json @@ -0,0 +1 @@ +[85.4454877870277,85.67226957404188,86.27702100607968,86.50380279309385] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/benchmark.json new file mode 100644 index 00000000..c157d52e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-trivial-substitution","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-trivial-substitution/tera","directory_name":"controlled-trivial-substitution/tera","title":"controlled-trivial-substitution/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/estimates.json new file mode 100644 index 00000000..45727ab4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":365.1857297519217,"upper_bound":366.80961815952793},"point_estimate":365.98174257595434,"standard_error":0.41344699148270575},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":363.30509953420943,"upper_bound":365.2229460182801},"point_estimate":364.32688356754494,"standard_error":0.5655051827868948},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1.7497713548392337,"upper_bound":4.258010953037179},"point_estimate":2.661486287404617,"standard_error":0.7457118265586513},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":364.2736079046247,"upper_bound":366.08291275065966},"point_estimate":365.0884763315286,"standard_error":0.45938402405680157},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3.645318643275399,"upper_bound":4.516315439518455},"point_estimate":4.148097211469255,"standard_error":0.22287570214174224}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/sample.json new file mode 100644 index 00000000..73b17e40 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[14145.0,28290.0,42435.0,56580.0,70725.0,84870.0,99015.0,113160.0,127305.0,141450.0,155595.0,169740.0,183885.0,198030.0,212175.0,226320.0,240465.0,254610.0,268755.0,282900.0,297045.0,311190.0,325335.0,339480.0,353625.0,367770.0,381915.0,396060.0,410205.0,424350.0,438495.0,452640.0,466785.0,480930.0,495075.0,509220.0,523365.0,537510.0,551655.0,565800.0,579945.0,594090.0,608235.0,622380.0,636525.0,650670.0,664815.0,678960.0,693105.0,707250.0,721395.0,735540.0,749685.0,763830.0,777975.0,792120.0,806265.0,820410.0,834555.0,848700.0,862845.0,876990.0,891135.0,905280.0,919425.0,933570.0,947715.0,961860.0,976005.0,990150.0,1004295.0,1018440.0,1032585.0,1046730.0,1060875.0,1075020.0,1089165.0,1103310.0,1117455.0,1131600.0,1145745.0,1159890.0,1174035.0,1188180.0,1202325.0,1216470.0,1230615.0,1244760.0,1258905.0,1273050.0,1287195.0,1301340.0,1315485.0,1329630.0,1343775.0,1357920.0,1372065.0,1386210.0,1400355.0,1414500.0],"times":[5124100.0,10345800.0,15498400.0,20665200.0,25836600.0,30985500.0,36155700.0,41315700.0,46521100.0,51652100.0,56880700.0,62012100.0,67156600.0,72325100.0,77533100.0,82647500.0,87975000.0,92418100.0,97406400.0,102575100.0,107749300.0,112870500.0,117955300.0,123063200.0,128235300.0,133327100.0,138456700.0,143616600.0,148780600.0,153879200.0,158973200.0,164095900.0,169268900.0,174418500.0,181391700.0,188704400.0,193873600.0,199182800.0,204424500.0,209664700.0,214967900.0,220126500.0,225349600.0,230540300.0,235810000.0,241048700.0,246413400.0,251654700.0,256870600.0,263950200.0,269184500.0,274371500.0,279722300.0,284988500.0,290737700.0,296052100.0,301220600.0,306601600.0,311917800.0,317238000.0,322664600.0,327756500.0,332824100.0,337927900.0,333016900.0,337730300.0,343201700.0,348197900.0,353469600.0,358721000.0,365874600.0,372935900.0,376879400.0,380655600.0,386076600.0,391678200.0,396830600.0,401860700.0,405977100.0,411370400.0,416999300.0,421355300.0,426374800.0,430691200.0,435981300.0,442870300.0,446988100.0,451298900.0,455639100.0,461918000.0,467370000.0,470934300.0,475597100.0,480799300.0,488349600.0,491611000.0,497464300.0,501683000.0,507428200.0,514725600.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/tukey.json new file mode 100644 index 00000000..30f8dcee --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/base/tukey.json @@ -0,0 +1 @@ +[339.0054137909574,350.8057102283071,382.2731673945729,394.0734638319226] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/change/estimates.json new file mode 100644 index 00000000..1752ba99 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.020756698395813088,"upper_bound":0.026700393714028693},"point_estimate":0.02364420163423331,"standard_error":0.0015136440736131897},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.012587750210621307,"upper_bound":0.018004962938107827},"point_estimate":0.015286477306239554,"standard_error":0.0015436271747543365}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/benchmark.json new file mode 100644 index 00000000..c157d52e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"controlled-trivial-substitution","function_id":"tera","value_str":null,"throughput":null,"full_id":"controlled-trivial-substitution/tera","directory_name":"controlled-trivial-substitution/tera","title":"controlled-trivial-substitution/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/estimates.json new file mode 100644 index 00000000..45727ab4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":365.1857297519217,"upper_bound":366.80961815952793},"point_estimate":365.98174257595434,"standard_error":0.41344699148270575},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":363.30509953420943,"upper_bound":365.2229460182801},"point_estimate":364.32688356754494,"standard_error":0.5655051827868948},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1.7497713548392337,"upper_bound":4.258010953037179},"point_estimate":2.661486287404617,"standard_error":0.7457118265586513},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":364.2736079046247,"upper_bound":366.08291275065966},"point_estimate":365.0884763315286,"standard_error":0.45938402405680157},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3.645318643275399,"upper_bound":4.516315439518455},"point_estimate":4.148097211469255,"standard_error":0.22287570214174224}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/sample.json new file mode 100644 index 00000000..73b17e40 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[14145.0,28290.0,42435.0,56580.0,70725.0,84870.0,99015.0,113160.0,127305.0,141450.0,155595.0,169740.0,183885.0,198030.0,212175.0,226320.0,240465.0,254610.0,268755.0,282900.0,297045.0,311190.0,325335.0,339480.0,353625.0,367770.0,381915.0,396060.0,410205.0,424350.0,438495.0,452640.0,466785.0,480930.0,495075.0,509220.0,523365.0,537510.0,551655.0,565800.0,579945.0,594090.0,608235.0,622380.0,636525.0,650670.0,664815.0,678960.0,693105.0,707250.0,721395.0,735540.0,749685.0,763830.0,777975.0,792120.0,806265.0,820410.0,834555.0,848700.0,862845.0,876990.0,891135.0,905280.0,919425.0,933570.0,947715.0,961860.0,976005.0,990150.0,1004295.0,1018440.0,1032585.0,1046730.0,1060875.0,1075020.0,1089165.0,1103310.0,1117455.0,1131600.0,1145745.0,1159890.0,1174035.0,1188180.0,1202325.0,1216470.0,1230615.0,1244760.0,1258905.0,1273050.0,1287195.0,1301340.0,1315485.0,1329630.0,1343775.0,1357920.0,1372065.0,1386210.0,1400355.0,1414500.0],"times":[5124100.0,10345800.0,15498400.0,20665200.0,25836600.0,30985500.0,36155700.0,41315700.0,46521100.0,51652100.0,56880700.0,62012100.0,67156600.0,72325100.0,77533100.0,82647500.0,87975000.0,92418100.0,97406400.0,102575100.0,107749300.0,112870500.0,117955300.0,123063200.0,128235300.0,133327100.0,138456700.0,143616600.0,148780600.0,153879200.0,158973200.0,164095900.0,169268900.0,174418500.0,181391700.0,188704400.0,193873600.0,199182800.0,204424500.0,209664700.0,214967900.0,220126500.0,225349600.0,230540300.0,235810000.0,241048700.0,246413400.0,251654700.0,256870600.0,263950200.0,269184500.0,274371500.0,279722300.0,284988500.0,290737700.0,296052100.0,301220600.0,306601600.0,311917800.0,317238000.0,322664600.0,327756500.0,332824100.0,337927900.0,333016900.0,337730300.0,343201700.0,348197900.0,353469600.0,358721000.0,365874600.0,372935900.0,376879400.0,380655600.0,386076600.0,391678200.0,396830600.0,401860700.0,405977100.0,411370400.0,416999300.0,421355300.0,426374800.0,430691200.0,435981300.0,442870300.0,446988100.0,451298900.0,455639100.0,461918000.0,467370000.0,470934300.0,475597100.0,480799300.0,488349600.0,491611000.0,497464300.0,501683000.0,507428200.0,514725600.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/tukey.json new file mode 100644 index 00000000..30f8dcee --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/controlled-trivial-substitution/tera/new/tukey.json @@ -0,0 +1 @@ +[339.0054137909574,350.8057102283071,382.2731673945729,394.0734638319226] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/benchmark.json new file mode 100644 index 00000000..3fb40e51 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-composed-page","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-composed-page/askama","directory_name":"idiomatic-composed-page/askama","title":"idiomatic-composed-page/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/estimates.json new file mode 100644 index 00000000..516d62a2 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1527.6039224405708,"upper_bound":1529.5411657210575},"point_estimate":1528.5378459253222,"standard_error":0.4952166733828772},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1526.4343101148067,"upper_bound":1528.2523426957082},"point_estimate":1527.403171503733,"standard_error":0.44263918709158323},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2.7756832772680124,"upper_bound":4.872059042134256},"point_estimate":3.7698495181340075,"standard_error":0.522932417637724},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1526.604917884487,"upper_bound":1530.0028622512352},"point_estimate":1528.268406890057,"standard_error":0.8663465513281292},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4.215237393870155,"upper_bound":5.671129510365443},"point_estimate":5.0020077169038295,"standard_error":0.3725881917052577}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/sample.json new file mode 100644 index 00000000..456b680c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[3374.0,6748.0,10122.0,13496.0,16870.0,20244.0,23618.0,26992.0,30366.0,33740.0,37114.0,40488.0,43862.0,47236.0,50610.0,53984.0,57358.0,60732.0,64106.0,67480.0,70854.0,74228.0,77602.0,80976.0,84350.0,87724.0,91098.0,94472.0,97846.0,101220.0,104594.0,107968.0,111342.0,114716.0,118090.0,121464.0,124838.0,128212.0,131586.0,134960.0,138334.0,141708.0,145082.0,148456.0,151830.0,155204.0,158578.0,161952.0,165326.0,168700.0,172074.0,175448.0,178822.0,182196.0,185570.0,188944.0,192318.0,195692.0,199066.0,202440.0,205814.0,209188.0,212562.0,215936.0,219310.0,222684.0,226058.0,229432.0,232806.0,236180.0,239554.0,242928.0,246302.0,249676.0,253050.0,256424.0,259798.0,263172.0,266546.0,269920.0,273294.0,276668.0,280042.0,283416.0,286790.0,290164.0,293538.0,296912.0,300286.0,303660.0,307034.0,310408.0,313782.0,317156.0,320530.0,323904.0,327278.0,330652.0,334026.0,337400.0],"times":[5171400.0,10360400.0,15550100.0,20644800.0,25870000.0,30979900.0,36188300.0,41237300.0,46486100.0,51541400.0,56764800.0,62007000.0,67123300.0,72251500.0,77433500.0,82505000.0,87725700.0,92810100.0,97976300.0,103214300.0,108203000.0,113490300.0,118533700.0,123799900.0,128817000.0,134986200.0,139115500.0,144228500.0,149547500.0,154499900.0,159795900.0,165060600.0,170141800.0,175077600.0,180483200.0,185528800.0,190604700.0,195814200.0,200796200.0,206196300.0,211159600.0,216269600.0,221281000.0,226539800.0,231706600.0,236724700.0,242347200.0,246930300.0,252169500.0,257001600.0,262298600.0,267497200.0,272644300.0,277491800.0,283084900.0,288142000.0,293179700.0,298157500.0,303502000.0,308704500.0,313503300.0,318865500.0,323892700.0,329072100.0,334285200.0,339632600.0,344953700.0,349865600.0,355280100.0,361614600.0,368372300.0,373764000.0,379062400.0,384214500.0,389675700.0,395496400.0,400170600.0,405326900.0,409991500.0,414149900.0,419130100.0,425132300.0,427462000.0,432997700.0,438033800.0,442822900.0,450375400.0,455479900.0,460777200.0,464622200.0,468670100.0,472928300.0,479045500.0,482038000.0,487307900.0,492360100.0,497481200.0,503455300.0,508921100.0,514045300.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/tukey.json new file mode 100644 index 00000000..0b6eedac --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/base/tukey.json @@ -0,0 +1 @@ +[1509.5666078142367,1517.3514097046996,1538.1108814126005,1545.8956833030634] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/change/estimates.json new file mode 100644 index 00000000..418b31cd --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.34663836082841837,"upper_bound":0.34849342649287424},"point_estimate":0.347565387168677,"standard_error":0.0004770179808313658},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.3456317202405257,"upper_bound":0.34810975727086624},"point_estimate":0.34648383857862175,"standard_error":0.0006088877414048458}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/benchmark.json new file mode 100644 index 00000000..3fb40e51 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-composed-page","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-composed-page/askama","directory_name":"idiomatic-composed-page/askama","title":"idiomatic-composed-page/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/estimates.json new file mode 100644 index 00000000..516d62a2 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1527.6039224405708,"upper_bound":1529.5411657210575},"point_estimate":1528.5378459253222,"standard_error":0.4952166733828772},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1526.4343101148067,"upper_bound":1528.2523426957082},"point_estimate":1527.403171503733,"standard_error":0.44263918709158323},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2.7756832772680124,"upper_bound":4.872059042134256},"point_estimate":3.7698495181340075,"standard_error":0.522932417637724},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1526.604917884487,"upper_bound":1530.0028622512352},"point_estimate":1528.268406890057,"standard_error":0.8663465513281292},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4.215237393870155,"upper_bound":5.671129510365443},"point_estimate":5.0020077169038295,"standard_error":0.3725881917052577}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/sample.json new file mode 100644 index 00000000..456b680c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[3374.0,6748.0,10122.0,13496.0,16870.0,20244.0,23618.0,26992.0,30366.0,33740.0,37114.0,40488.0,43862.0,47236.0,50610.0,53984.0,57358.0,60732.0,64106.0,67480.0,70854.0,74228.0,77602.0,80976.0,84350.0,87724.0,91098.0,94472.0,97846.0,101220.0,104594.0,107968.0,111342.0,114716.0,118090.0,121464.0,124838.0,128212.0,131586.0,134960.0,138334.0,141708.0,145082.0,148456.0,151830.0,155204.0,158578.0,161952.0,165326.0,168700.0,172074.0,175448.0,178822.0,182196.0,185570.0,188944.0,192318.0,195692.0,199066.0,202440.0,205814.0,209188.0,212562.0,215936.0,219310.0,222684.0,226058.0,229432.0,232806.0,236180.0,239554.0,242928.0,246302.0,249676.0,253050.0,256424.0,259798.0,263172.0,266546.0,269920.0,273294.0,276668.0,280042.0,283416.0,286790.0,290164.0,293538.0,296912.0,300286.0,303660.0,307034.0,310408.0,313782.0,317156.0,320530.0,323904.0,327278.0,330652.0,334026.0,337400.0],"times":[5171400.0,10360400.0,15550100.0,20644800.0,25870000.0,30979900.0,36188300.0,41237300.0,46486100.0,51541400.0,56764800.0,62007000.0,67123300.0,72251500.0,77433500.0,82505000.0,87725700.0,92810100.0,97976300.0,103214300.0,108203000.0,113490300.0,118533700.0,123799900.0,128817000.0,134986200.0,139115500.0,144228500.0,149547500.0,154499900.0,159795900.0,165060600.0,170141800.0,175077600.0,180483200.0,185528800.0,190604700.0,195814200.0,200796200.0,206196300.0,211159600.0,216269600.0,221281000.0,226539800.0,231706600.0,236724700.0,242347200.0,246930300.0,252169500.0,257001600.0,262298600.0,267497200.0,272644300.0,277491800.0,283084900.0,288142000.0,293179700.0,298157500.0,303502000.0,308704500.0,313503300.0,318865500.0,323892700.0,329072100.0,334285200.0,339632600.0,344953700.0,349865600.0,355280100.0,361614600.0,368372300.0,373764000.0,379062400.0,384214500.0,389675700.0,395496400.0,400170600.0,405326900.0,409991500.0,414149900.0,419130100.0,425132300.0,427462000.0,432997700.0,438033800.0,442822900.0,450375400.0,455479900.0,460777200.0,464622200.0,468670100.0,472928300.0,479045500.0,482038000.0,487307900.0,492360100.0,497481200.0,503455300.0,508921100.0,514045300.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/tukey.json new file mode 100644 index 00000000..0b6eedac --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/askama/new/tukey.json @@ -0,0 +1 @@ +[1509.5666078142367,1517.3514097046996,1538.1108814126005,1545.8956833030634] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/benchmark.json new file mode 100644 index 00000000..43e5401d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-composed-page","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-composed-page/tera","directory_name":"idiomatic-composed-page/tera","title":"idiomatic-composed-page/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/estimates.json new file mode 100644 index 00000000..f102d318 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5592.95492325836,"upper_bound":5601.481241166236},"point_estimate":5597.215480901269,"standard_error":2.174584706661663},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5591.177305388327,"upper_bound":5604.978042382622},"point_estimate":5596.8110049229,"standard_error":3.365116001173825},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":17.3618965539292,"upper_bound":28.744622163663525},"point_estimate":22.117091421037852,"standard_error":2.9768687949469137},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5578.731691187519,"upper_bound":5587.231725705364},"point_estimate":5582.832978826781,"standard_error":2.175587306574596},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":18.928124717802003,"upper_bound":24.442699202805322},"point_estimate":21.83374834745645,"standard_error":1.4099303479234997}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/sample.json new file mode 100644 index 00000000..1e51cec2 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[917.0,1834.0,2751.0,3668.0,4585.0,5502.0,6419.0,7336.0,8253.0,9170.0,10087.0,11004.0,11921.0,12838.0,13755.0,14672.0,15589.0,16506.0,17423.0,18340.0,19257.0,20174.0,21091.0,22008.0,22925.0,23842.0,24759.0,25676.0,26593.0,27510.0,28427.0,29344.0,30261.0,31178.0,32095.0,33012.0,33929.0,34846.0,35763.0,36680.0,37597.0,38514.0,39431.0,40348.0,41265.0,42182.0,43099.0,44016.0,44933.0,45850.0,46767.0,47684.0,48601.0,49518.0,50435.0,51352.0,52269.0,53186.0,54103.0,55020.0,55937.0,56854.0,57771.0,58688.0,59605.0,60522.0,61439.0,62356.0,63273.0,64190.0,65107.0,66024.0,66941.0,67858.0,68775.0,69692.0,70609.0,71526.0,72443.0,73360.0,74277.0,75194.0,76111.0,77028.0,77945.0,78862.0,79779.0,80696.0,81613.0,82530.0,83447.0,84364.0,85281.0,86198.0,87115.0,88032.0,88949.0,89866.0,90783.0,91700.0],"times":[5105600.0,10280300.0,15444000.0,20633500.0,25776700.0,31054900.0,36210800.0,41476800.0,46505200.0,51792900.0,56743900.0,61807900.0,66889700.0,72093900.0,77410900.0,82526800.0,87751400.0,92164300.0,97363200.0,102528100.0,107599000.0,112993300.0,118185000.0,123474500.0,128654700.0,133928900.0,138794800.0,144035300.0,149117000.0,154638200.0,159517400.0,164711200.0,169942200.0,175127300.0,180051700.0,185371400.0,190171300.0,195465600.0,200600300.0,205530900.0,211264600.0,215643200.0,221289500.0,226469600.0,231718700.0,236484800.0,241936700.0,247066600.0,252180700.0,257180200.0,261828600.0,266943300.0,272340000.0,277148000.0,280697900.0,286465600.0,291791900.0,296438400.0,300950400.0,306085400.0,311038600.0,316494000.0,322671700.0,327844500.0,333006500.0,338099900.0,343378700.0,348765000.0,353989600.0,359226700.0,364260900.0,369332700.0,374279000.0,379090700.0,384347400.0,389358900.0,394954900.0,400327000.0,405442300.0,409444800.0,415026100.0,420343600.0,424983700.0,429166400.0,435564800.0,439346700.0,446099700.0,451418300.0,456311600.0,460152700.0,464600200.0,469571600.0,474765900.0,480050600.0,484945300.0,489534800.0,494903600.0,499086600.0,504162200.0,509990200.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/tukey.json new file mode 100644 index 00000000..2f28add7 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/base/tukey.json @@ -0,0 +1 @@ +[5502.2914903514575,5543.621834296193,5653.836084815486,5695.166428760221] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/change/estimates.json new file mode 100644 index 00000000..73ed67fe --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.015047679772638869,"upper_bound":-0.013491732896380271},"point_estimate":-0.014259998596554024,"standard_error":0.0003979930227986717},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.01549374150551397,"upper_bound":-0.012859493392685262},"point_estimate":-0.014440354819643675,"standard_error":0.0006513319851616628}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/benchmark.json new file mode 100644 index 00000000..43e5401d --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-composed-page","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-composed-page/tera","directory_name":"idiomatic-composed-page/tera","title":"idiomatic-composed-page/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/estimates.json new file mode 100644 index 00000000..f102d318 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5592.95492325836,"upper_bound":5601.481241166236},"point_estimate":5597.215480901269,"standard_error":2.174584706661663},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5591.177305388327,"upper_bound":5604.978042382622},"point_estimate":5596.8110049229,"standard_error":3.365116001173825},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":17.3618965539292,"upper_bound":28.744622163663525},"point_estimate":22.117091421037852,"standard_error":2.9768687949469137},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5578.731691187519,"upper_bound":5587.231725705364},"point_estimate":5582.832978826781,"standard_error":2.175587306574596},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":18.928124717802003,"upper_bound":24.442699202805322},"point_estimate":21.83374834745645,"standard_error":1.4099303479234997}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/sample.json new file mode 100644 index 00000000..1e51cec2 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[917.0,1834.0,2751.0,3668.0,4585.0,5502.0,6419.0,7336.0,8253.0,9170.0,10087.0,11004.0,11921.0,12838.0,13755.0,14672.0,15589.0,16506.0,17423.0,18340.0,19257.0,20174.0,21091.0,22008.0,22925.0,23842.0,24759.0,25676.0,26593.0,27510.0,28427.0,29344.0,30261.0,31178.0,32095.0,33012.0,33929.0,34846.0,35763.0,36680.0,37597.0,38514.0,39431.0,40348.0,41265.0,42182.0,43099.0,44016.0,44933.0,45850.0,46767.0,47684.0,48601.0,49518.0,50435.0,51352.0,52269.0,53186.0,54103.0,55020.0,55937.0,56854.0,57771.0,58688.0,59605.0,60522.0,61439.0,62356.0,63273.0,64190.0,65107.0,66024.0,66941.0,67858.0,68775.0,69692.0,70609.0,71526.0,72443.0,73360.0,74277.0,75194.0,76111.0,77028.0,77945.0,78862.0,79779.0,80696.0,81613.0,82530.0,83447.0,84364.0,85281.0,86198.0,87115.0,88032.0,88949.0,89866.0,90783.0,91700.0],"times":[5105600.0,10280300.0,15444000.0,20633500.0,25776700.0,31054900.0,36210800.0,41476800.0,46505200.0,51792900.0,56743900.0,61807900.0,66889700.0,72093900.0,77410900.0,82526800.0,87751400.0,92164300.0,97363200.0,102528100.0,107599000.0,112993300.0,118185000.0,123474500.0,128654700.0,133928900.0,138794800.0,144035300.0,149117000.0,154638200.0,159517400.0,164711200.0,169942200.0,175127300.0,180051700.0,185371400.0,190171300.0,195465600.0,200600300.0,205530900.0,211264600.0,215643200.0,221289500.0,226469600.0,231718700.0,236484800.0,241936700.0,247066600.0,252180700.0,257180200.0,261828600.0,266943300.0,272340000.0,277148000.0,280697900.0,286465600.0,291791900.0,296438400.0,300950400.0,306085400.0,311038600.0,316494000.0,322671700.0,327844500.0,333006500.0,338099900.0,343378700.0,348765000.0,353989600.0,359226700.0,364260900.0,369332700.0,374279000.0,379090700.0,384347400.0,389358900.0,394954900.0,400327000.0,405442300.0,409444800.0,415026100.0,420343600.0,424983700.0,429166400.0,435564800.0,439346700.0,446099700.0,451418300.0,456311600.0,460152700.0,464600200.0,469571600.0,474765900.0,480050600.0,484945300.0,489534800.0,494903600.0,499086600.0,504162200.0,509990200.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/tukey.json new file mode 100644 index 00000000..2f28add7 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-composed-page/tera/new/tukey.json @@ -0,0 +1 @@ +[5502.2914903514575,5543.621834296193,5653.836084815486,5695.166428760221] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/benchmark.json new file mode 100644 index 00000000..91e5068b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-conditional-heavy","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-conditional-heavy/askama","directory_name":"idiomatic-conditional-heavy/askama","title":"idiomatic-conditional-heavy/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/estimates.json new file mode 100644 index 00000000..2a78287b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5379.410155724858,"upper_bound":5405.518220270414},"point_estimate":5392.185254051123,"standard_error":6.6893482221509455},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5377.839188871173,"upper_bound":5383.282579940189},"point_estimate":5379.938800823894,"standard_error":2.119030550757696},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":51.74358425082373,"upper_bound":85.57930620847699},"point_estimate":57.62450842988438,"standard_error":7.830833182576843},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5398.84654850828,"upper_bound":5427.35012524106},"point_estimate":5412.640870428008,"standard_error":7.259951463972534},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":56.152382271524196,"upper_bound":76.85249979468523},"point_estimate":67.06037079354552,"standard_error":5.292134771517329}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/sample.json new file mode 100644 index 00000000..b8b50427 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[966.0,1932.0,2898.0,3864.0,4830.0,5796.0,6762.0,7728.0,8694.0,9660.0,10626.0,11592.0,12558.0,13524.0,14490.0,15456.0,16422.0,17388.0,18354.0,19320.0,20286.0,21252.0,22218.0,23184.0,24150.0,25116.0,26082.0,27048.0,28014.0,28980.0,29946.0,30912.0,31878.0,32844.0,33810.0,34776.0,35742.0,36708.0,37674.0,38640.0,39606.0,40572.0,41538.0,42504.0,43470.0,44436.0,45402.0,46368.0,47334.0,48300.0,49266.0,50232.0,51198.0,52164.0,53130.0,54096.0,55062.0,56028.0,56994.0,57960.0,58926.0,59892.0,60858.0,61824.0,62790.0,63756.0,64722.0,65688.0,66654.0,67620.0,68586.0,69552.0,70518.0,71484.0,72450.0,73416.0,74382.0,75348.0,76314.0,77280.0,78246.0,79212.0,80178.0,81144.0,82110.0,83076.0,84042.0,85008.0,85974.0,86940.0,87906.0,88872.0,89838.0,90804.0,91770.0,92736.0,93702.0,94668.0,95634.0,96600.0],"times":[5131400.0,10283200.0,15418000.0,20537200.0,25679500.0,30803500.0,35946800.0,41082700.0,46194800.0,51356900.0,56470600.0,61615700.0,66747900.0,71904600.0,77032100.0,82155500.0,87311700.0,92399600.0,97527100.0,102652700.0,107800800.0,112894000.0,119347100.0,124648600.0,129855300.0,135070500.0,140263300.0,145411600.0,150656400.0,155862800.0,159291700.0,164537300.0,170629300.0,176613100.0,181871300.0,187048000.0,192293100.0,197368100.0,202711900.0,207891000.0,213122900.0,218271100.0,223484000.0,228697700.0,233838700.0,239162500.0,244265700.0,249406400.0,254623300.0,260068500.0,266714800.0,276425800.0,281782100.0,287120500.0,292392100.0,297723700.0,303054100.0,307956200.0,313817800.0,319117300.0,324347900.0,329710400.0,335103200.0,340719800.0,352531100.0,355959400.0,355094100.0,360877700.0,359157800.0,363713500.0,369039600.0,374337500.0,378529200.0,385006100.0,392541600.0,397697600.0,403007400.0,408556400.0,413472800.0,418702100.0,423820100.0,429223700.0,434301000.0,439915700.0,444823900.0,450267700.0,455298000.0,460426600.0,465925400.0,471333800.0,476491600.0,481592200.0,484127700.0,485481100.0,493501800.0,498622300.0,497230700.0,507377600.0,512706500.0,514519700.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/tukey.json new file mode 100644 index 00000000..a85933b4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/base/tukey.json @@ -0,0 +1 @@ +[5046.901760465588,5186.155541852877,5557.498958885648,5696.752740272937] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/change/estimates.json new file mode 100644 index 00000000..21a9d9b9 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.006661252883594504,"upper_bound":-0.0005074165121612691},"point_estimate":-0.0036043602228430505,"standard_error":0.0015732870986005442},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.010591949531637668,"upper_bound":-0.0029950844554264},"point_estimate":-0.008545233822737641,"standard_error":0.0022505478346780843}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/benchmark.json new file mode 100644 index 00000000..91e5068b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-conditional-heavy","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-conditional-heavy/askama","directory_name":"idiomatic-conditional-heavy/askama","title":"idiomatic-conditional-heavy/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/estimates.json new file mode 100644 index 00000000..2a78287b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5379.410155724858,"upper_bound":5405.518220270414},"point_estimate":5392.185254051123,"standard_error":6.6893482221509455},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5377.839188871173,"upper_bound":5383.282579940189},"point_estimate":5379.938800823894,"standard_error":2.119030550757696},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":51.74358425082373,"upper_bound":85.57930620847699},"point_estimate":57.62450842988438,"standard_error":7.830833182576843},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5398.84654850828,"upper_bound":5427.35012524106},"point_estimate":5412.640870428008,"standard_error":7.259951463972534},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":56.152382271524196,"upper_bound":76.85249979468523},"point_estimate":67.06037079354552,"standard_error":5.292134771517329}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/sample.json new file mode 100644 index 00000000..b8b50427 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[966.0,1932.0,2898.0,3864.0,4830.0,5796.0,6762.0,7728.0,8694.0,9660.0,10626.0,11592.0,12558.0,13524.0,14490.0,15456.0,16422.0,17388.0,18354.0,19320.0,20286.0,21252.0,22218.0,23184.0,24150.0,25116.0,26082.0,27048.0,28014.0,28980.0,29946.0,30912.0,31878.0,32844.0,33810.0,34776.0,35742.0,36708.0,37674.0,38640.0,39606.0,40572.0,41538.0,42504.0,43470.0,44436.0,45402.0,46368.0,47334.0,48300.0,49266.0,50232.0,51198.0,52164.0,53130.0,54096.0,55062.0,56028.0,56994.0,57960.0,58926.0,59892.0,60858.0,61824.0,62790.0,63756.0,64722.0,65688.0,66654.0,67620.0,68586.0,69552.0,70518.0,71484.0,72450.0,73416.0,74382.0,75348.0,76314.0,77280.0,78246.0,79212.0,80178.0,81144.0,82110.0,83076.0,84042.0,85008.0,85974.0,86940.0,87906.0,88872.0,89838.0,90804.0,91770.0,92736.0,93702.0,94668.0,95634.0,96600.0],"times":[5131400.0,10283200.0,15418000.0,20537200.0,25679500.0,30803500.0,35946800.0,41082700.0,46194800.0,51356900.0,56470600.0,61615700.0,66747900.0,71904600.0,77032100.0,82155500.0,87311700.0,92399600.0,97527100.0,102652700.0,107800800.0,112894000.0,119347100.0,124648600.0,129855300.0,135070500.0,140263300.0,145411600.0,150656400.0,155862800.0,159291700.0,164537300.0,170629300.0,176613100.0,181871300.0,187048000.0,192293100.0,197368100.0,202711900.0,207891000.0,213122900.0,218271100.0,223484000.0,228697700.0,233838700.0,239162500.0,244265700.0,249406400.0,254623300.0,260068500.0,266714800.0,276425800.0,281782100.0,287120500.0,292392100.0,297723700.0,303054100.0,307956200.0,313817800.0,319117300.0,324347900.0,329710400.0,335103200.0,340719800.0,352531100.0,355959400.0,355094100.0,360877700.0,359157800.0,363713500.0,369039600.0,374337500.0,378529200.0,385006100.0,392541600.0,397697600.0,403007400.0,408556400.0,413472800.0,418702100.0,423820100.0,429223700.0,434301000.0,439915700.0,444823900.0,450267700.0,455298000.0,460426600.0,465925400.0,471333800.0,476491600.0,481592200.0,484127700.0,485481100.0,493501800.0,498622300.0,497230700.0,507377600.0,512706500.0,514519700.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/tukey.json new file mode 100644 index 00000000..a85933b4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/askama/new/tukey.json @@ -0,0 +1 @@ +[5046.901760465588,5186.155541852877,5557.498958885648,5696.752740272937] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/benchmark.json new file mode 100644 index 00000000..b1ef4075 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-conditional-heavy","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-conditional-heavy/tera","directory_name":"idiomatic-conditional-heavy/tera","title":"idiomatic-conditional-heavy/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/estimates.json new file mode 100644 index 00000000..86c6aa57 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":51369.23739741872,"upper_bound":51453.66619901497},"point_estimate":51412.08831844248,"standard_error":21.551031234680234},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":51481.36666666667,"upper_bound":51530.36842105263},"point_estimate":51499.174843889385,"standard_error":12.59981633064289},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":84.76641303324634,"upper_bound":223.45789777195262},"point_estimate":143.61374379981984,"standard_error":37.00644294732649},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":51372.059040632026,"upper_bound":51461.18833006984},"point_estimate":51418.477532141274,"standard_error":22.676263186049297},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":194.56235587852743,"upper_bound":233.7437581641552},"point_estimate":217.34536112928612,"standard_error":9.989451045580164}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/sample.json new file mode 100644 index 00000000..c2e48a79 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[100.0,200.0,300.0,400.0,500.0,600.0,700.0,800.0,900.0,1000.0,1100.0,1200.0,1300.0,1400.0,1500.0,1600.0,1700.0,1800.0,1900.0,2000.0,2100.0,2200.0,2300.0,2400.0,2500.0,2600.0,2700.0,2800.0,2900.0,3000.0,3100.0,3200.0,3300.0,3400.0,3500.0,3600.0,3700.0,3800.0,3900.0,4000.0,4100.0,4200.0,4300.0,4400.0,4500.0,4600.0,4700.0,4800.0,4900.0,5000.0,5100.0,5200.0,5300.0,5400.0,5500.0,5600.0,5700.0,5800.0,5900.0,6000.0,6100.0,6200.0,6300.0,6400.0,6500.0,6600.0,6700.0,6800.0,6900.0,7000.0,7100.0,7200.0,7300.0,7400.0,7500.0,7600.0,7700.0,7800.0,7900.0,8000.0,8100.0,8200.0,8300.0,8400.0,8500.0,8600.0,8700.0,8800.0,8900.0,9000.0,9100.0,9200.0,9300.0,9400.0,9500.0,9600.0,9700.0,9800.0,9900.0,10000.0],"times":[5171200.0,10211400.0,15324200.0,20428400.0,25541200.0,30646400.0,35759500.0,40884000.0,45976600.0,51069300.0,56191800.0,61277300.0,66403300.0,71529400.0,76619100.0,81730500.0,86800000.0,92847400.0,98043300.0,103254700.0,108400600.0,113525900.0,118753800.0,123905200.0,129121200.0,134370600.0,139427500.0,144627500.0,149844400.0,154976500.0,160036200.0,165266100.0,170416100.0,175429500.0,180595300.0,185550800.0,190605600.0,195815400.0,200929500.0,206194200.0,211498400.0,216597900.0,221747600.0,226837900.0,232110700.0,237250300.0,242497300.0,247508500.0,252673300.0,257401700.0,262650500.0,267753900.0,272877500.0,278062400.0,283225400.0,288442700.0,293540400.0,298702200.0,303850200.0,309413000.0,314388900.0,319648500.0,324867000.0,330049600.0,335297300.0,337955200.0,343149700.0,348343500.0,353489700.0,358344000.0,363562100.0,368693800.0,373984400.0,377938700.0,382482000.0,387732800.0,393493000.0,398756700.0,403904400.0,408661300.0,413503600.0,421943800.0,427166200.0,432352900.0,437492400.0,442734500.0,447916600.0,452839400.0,458218700.0,463332300.0,468441500.0,473679100.0,479110800.0,484319100.0,489642100.0,494609600.0,499876900.0,505308000.0,510205100.0,514977700.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/tukey.json new file mode 100644 index 00000000..e030e429 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/base/tukey.json @@ -0,0 +1 @@ +[50096.741071428565,50649.37053571428,52123.04910714286,52675.67857142858] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/change/estimates.json new file mode 100644 index 00000000..1089a5a3 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.008116045773608966,"upper_bound":0.011437005768663999},"point_estimate":0.009831850981075307,"standard_error":0.0008521149900856829},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.011768373608676663,"upper_bound":0.013943128060006416},"point_estimate":0.012723673781957823,"standard_error":0.0005492098464920286}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/benchmark.json new file mode 100644 index 00000000..b1ef4075 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-conditional-heavy","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-conditional-heavy/tera","directory_name":"idiomatic-conditional-heavy/tera","title":"idiomatic-conditional-heavy/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/estimates.json new file mode 100644 index 00000000..86c6aa57 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":51369.23739741872,"upper_bound":51453.66619901497},"point_estimate":51412.08831844248,"standard_error":21.551031234680234},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":51481.36666666667,"upper_bound":51530.36842105263},"point_estimate":51499.174843889385,"standard_error":12.59981633064289},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":84.76641303324634,"upper_bound":223.45789777195262},"point_estimate":143.61374379981984,"standard_error":37.00644294732649},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":51372.059040632026,"upper_bound":51461.18833006984},"point_estimate":51418.477532141274,"standard_error":22.676263186049297},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":194.56235587852743,"upper_bound":233.7437581641552},"point_estimate":217.34536112928612,"standard_error":9.989451045580164}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/sample.json new file mode 100644 index 00000000..c2e48a79 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[100.0,200.0,300.0,400.0,500.0,600.0,700.0,800.0,900.0,1000.0,1100.0,1200.0,1300.0,1400.0,1500.0,1600.0,1700.0,1800.0,1900.0,2000.0,2100.0,2200.0,2300.0,2400.0,2500.0,2600.0,2700.0,2800.0,2900.0,3000.0,3100.0,3200.0,3300.0,3400.0,3500.0,3600.0,3700.0,3800.0,3900.0,4000.0,4100.0,4200.0,4300.0,4400.0,4500.0,4600.0,4700.0,4800.0,4900.0,5000.0,5100.0,5200.0,5300.0,5400.0,5500.0,5600.0,5700.0,5800.0,5900.0,6000.0,6100.0,6200.0,6300.0,6400.0,6500.0,6600.0,6700.0,6800.0,6900.0,7000.0,7100.0,7200.0,7300.0,7400.0,7500.0,7600.0,7700.0,7800.0,7900.0,8000.0,8100.0,8200.0,8300.0,8400.0,8500.0,8600.0,8700.0,8800.0,8900.0,9000.0,9100.0,9200.0,9300.0,9400.0,9500.0,9600.0,9700.0,9800.0,9900.0,10000.0],"times":[5171200.0,10211400.0,15324200.0,20428400.0,25541200.0,30646400.0,35759500.0,40884000.0,45976600.0,51069300.0,56191800.0,61277300.0,66403300.0,71529400.0,76619100.0,81730500.0,86800000.0,92847400.0,98043300.0,103254700.0,108400600.0,113525900.0,118753800.0,123905200.0,129121200.0,134370600.0,139427500.0,144627500.0,149844400.0,154976500.0,160036200.0,165266100.0,170416100.0,175429500.0,180595300.0,185550800.0,190605600.0,195815400.0,200929500.0,206194200.0,211498400.0,216597900.0,221747600.0,226837900.0,232110700.0,237250300.0,242497300.0,247508500.0,252673300.0,257401700.0,262650500.0,267753900.0,272877500.0,278062400.0,283225400.0,288442700.0,293540400.0,298702200.0,303850200.0,309413000.0,314388900.0,319648500.0,324867000.0,330049600.0,335297300.0,337955200.0,343149700.0,348343500.0,353489700.0,358344000.0,363562100.0,368693800.0,373984400.0,377938700.0,382482000.0,387732800.0,393493000.0,398756700.0,403904400.0,408661300.0,413503600.0,421943800.0,427166200.0,432352900.0,437492400.0,442734500.0,447916600.0,452839400.0,458218700.0,463332300.0,468441500.0,473679100.0,479110800.0,484319100.0,489642100.0,494609600.0,499876900.0,505308000.0,510205100.0,514977700.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/tukey.json new file mode 100644 index 00000000..e030e429 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-conditional-heavy/tera/new/tukey.json @@ -0,0 +1 @@ +[50096.741071428565,50649.37053571428,52123.04910714286,52675.67857142858] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/benchmark.json new file mode 100644 index 00000000..81e5df5f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-encoded-loop","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-encoded-loop/askama","directory_name":"idiomatic-encoded-loop/askama","title":"idiomatic-encoded-loop/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/estimates.json new file mode 100644 index 00000000..20fb9c73 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":589512.3635625748,"upper_bound":594200.7769934165},"point_estimate":591805.9913744237,"standard_error":1196.559795875794},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":588667.1497584541,"upper_bound":592038.8528138527},"point_estimate":590768.6868686869,"standard_error":867.3793866342038},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4788.667862352639,"upper_bound":10291.612815459865},"point_estimate":7598.954125961232,"standard_error":1440.9557472784415},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":588570.7712371228,"upper_bound":595298.8733955487},"point_estimate":591803.3664023118,"standard_error":1727.2205180159358},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":9661.48768118648,"upper_bound":13886.77552041112},"point_estimate":11962.296116957905,"standard_error":1080.3609102421347}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/sample.json new file mode 100644 index 00000000..5b005abf --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[9.0,18.0,27.0,36.0,45.0,54.0,63.0,72.0,81.0,90.0,99.0,108.0,117.0,126.0,135.0,144.0,153.0,162.0,171.0,180.0,189.0,198.0,207.0,216.0,225.0,234.0,243.0,252.0,261.0,270.0,279.0,288.0,297.0,306.0,315.0,324.0,333.0,342.0,351.0,360.0,369.0,378.0,387.0,396.0,405.0,414.0,423.0,432.0,441.0,450.0,459.0,468.0,477.0,486.0,495.0,504.0,513.0,522.0,531.0,540.0,549.0,558.0,567.0,576.0,585.0,594.0,603.0,612.0,621.0,630.0,639.0,648.0,657.0,666.0,675.0,684.0,693.0,702.0,711.0,720.0,729.0,738.0,747.0,756.0,765.0,774.0,783.0,792.0,801.0,810.0,819.0,828.0,837.0,846.0,855.0,864.0,873.0,882.0,891.0,900.0],"times":[5294700.0,10612600.0,15955700.0,21292400.0,26747500.0,31899000.0,37251100.0,42766900.0,47805900.0,53464600.0,58471800.0,64016500.0,69041100.0,74617900.0,79920900.0,85197900.0,90426600.0,96192200.0,100731200.0,106684000.0,112141000.0,117578000.0,122985100.0,128255300.0,133626100.0,141790600.0,143683700.0,155862300.0,162967200.0,167419400.0,167893800.0,169555300.0,174134900.0,179977300.0,187730300.0,192459700.0,195700400.0,196698400.0,199690800.0,206621000.0,212168000.0,218989800.0,223411400.0,229625700.0,234806600.0,242487400.0,246512200.0,248164900.0,252999400.0,272985000.0,268328000.0,280372300.0,297269400.0,303727300.0,289548500.0,296788500.0,301795200.0,307048200.0,315533900.0,317863800.0,330870800.0,333342100.0,333206700.0,341631400.0,362881800.0,355447200.0,357504800.0,356727200.0,362379600.0,364924400.0,378042900.0,380416300.0,379006300.0,385204300.0,395226300.0,407046000.0,410167400.0,411040300.0,419925300.0,423278600.0,426773300.0,428986900.0,448978300.0,449977600.0,462049300.0,478893100.0,453141200.0,460337600.0,467065000.0,491124000.0,502204300.0,487416400.0,497198800.0,529213500.0,490966200.0,500383500.0,510725600.0,516004700.0,526416300.0,541010900.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/tukey.json new file mode 100644 index 00000000..7705ffac --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/base/tukey.json @@ -0,0 +1 @@ +[557677.7085036762,571356.5572522823,607833.4872485651,621512.3359971711] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/change/estimates.json new file mode 100644 index 00000000..eedba796 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.0198491700122165,"upper_bound":-0.006421378550003801},"point_estimate":-0.012950519509207892,"standard_error":0.0034339719929861725},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.01652065496815658,"upper_bound":-0.002471743593769782},"point_estimate":-0.009462277775448613,"standard_error":0.0036810517336913384}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/benchmark.json new file mode 100644 index 00000000..81e5df5f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-encoded-loop","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-encoded-loop/askama","directory_name":"idiomatic-encoded-loop/askama","title":"idiomatic-encoded-loop/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/estimates.json new file mode 100644 index 00000000..20fb9c73 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":589512.3635625748,"upper_bound":594200.7769934165},"point_estimate":591805.9913744237,"standard_error":1196.559795875794},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":588667.1497584541,"upper_bound":592038.8528138527},"point_estimate":590768.6868686869,"standard_error":867.3793866342038},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4788.667862352639,"upper_bound":10291.612815459865},"point_estimate":7598.954125961232,"standard_error":1440.9557472784415},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":588570.7712371228,"upper_bound":595298.8733955487},"point_estimate":591803.3664023118,"standard_error":1727.2205180159358},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":9661.48768118648,"upper_bound":13886.77552041112},"point_estimate":11962.296116957905,"standard_error":1080.3609102421347}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/sample.json new file mode 100644 index 00000000..5b005abf --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[9.0,18.0,27.0,36.0,45.0,54.0,63.0,72.0,81.0,90.0,99.0,108.0,117.0,126.0,135.0,144.0,153.0,162.0,171.0,180.0,189.0,198.0,207.0,216.0,225.0,234.0,243.0,252.0,261.0,270.0,279.0,288.0,297.0,306.0,315.0,324.0,333.0,342.0,351.0,360.0,369.0,378.0,387.0,396.0,405.0,414.0,423.0,432.0,441.0,450.0,459.0,468.0,477.0,486.0,495.0,504.0,513.0,522.0,531.0,540.0,549.0,558.0,567.0,576.0,585.0,594.0,603.0,612.0,621.0,630.0,639.0,648.0,657.0,666.0,675.0,684.0,693.0,702.0,711.0,720.0,729.0,738.0,747.0,756.0,765.0,774.0,783.0,792.0,801.0,810.0,819.0,828.0,837.0,846.0,855.0,864.0,873.0,882.0,891.0,900.0],"times":[5294700.0,10612600.0,15955700.0,21292400.0,26747500.0,31899000.0,37251100.0,42766900.0,47805900.0,53464600.0,58471800.0,64016500.0,69041100.0,74617900.0,79920900.0,85197900.0,90426600.0,96192200.0,100731200.0,106684000.0,112141000.0,117578000.0,122985100.0,128255300.0,133626100.0,141790600.0,143683700.0,155862300.0,162967200.0,167419400.0,167893800.0,169555300.0,174134900.0,179977300.0,187730300.0,192459700.0,195700400.0,196698400.0,199690800.0,206621000.0,212168000.0,218989800.0,223411400.0,229625700.0,234806600.0,242487400.0,246512200.0,248164900.0,252999400.0,272985000.0,268328000.0,280372300.0,297269400.0,303727300.0,289548500.0,296788500.0,301795200.0,307048200.0,315533900.0,317863800.0,330870800.0,333342100.0,333206700.0,341631400.0,362881800.0,355447200.0,357504800.0,356727200.0,362379600.0,364924400.0,378042900.0,380416300.0,379006300.0,385204300.0,395226300.0,407046000.0,410167400.0,411040300.0,419925300.0,423278600.0,426773300.0,428986900.0,448978300.0,449977600.0,462049300.0,478893100.0,453141200.0,460337600.0,467065000.0,491124000.0,502204300.0,487416400.0,497198800.0,529213500.0,490966200.0,500383500.0,510725600.0,516004700.0,526416300.0,541010900.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/tukey.json new file mode 100644 index 00000000..7705ffac --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/askama/new/tukey.json @@ -0,0 +1 @@ +[557677.7085036762,571356.5572522823,607833.4872485651,621512.3359971711] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/benchmark.json new file mode 100644 index 00000000..40fadb35 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-encoded-loop","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-encoded-loop/tera","directory_name":"idiomatic-encoded-loop/tera","title":"idiomatic-encoded-loop/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/estimates.json new file mode 100644 index 00000000..3769a0a5 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1721363.0496276317,"upper_bound":1724733.543487789},"point_estimate":1723011.488306616,"standard_error":859.8048918771871},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1719904.856254856,"upper_bound":1722845.6140350876},"point_estimate":1721448.9329805998,"standard_error":707.0395779597013},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4535.282593023239,"upper_bound":7439.658825666248},"point_estimate":5464.630294187406,"standard_error":745.0640491388958},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1721243.505978439,"upper_bound":1724592.3675082077},"point_estimate":1722795.8142948623,"standard_error":854.6887262111147},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":7251.640106430205,"upper_bound":9814.778267493975},"point_estimate":8652.698774824605,"standard_error":655.8130487986845}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/sample.json new file mode 100644 index 00000000..9b303523 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[3.0,6.0,9.0,12.0,15.0,18.0,21.0,24.0,27.0,30.0,33.0,36.0,39.0,42.0,45.0,48.0,51.0,54.0,57.0,60.0,63.0,66.0,69.0,72.0,75.0,78.0,81.0,84.0,87.0,90.0,93.0,96.0,99.0,102.0,105.0,108.0,111.0,114.0,117.0,120.0,123.0,126.0,129.0,132.0,135.0,138.0,141.0,144.0,147.0,150.0,153.0,156.0,159.0,162.0,165.0,168.0,171.0,174.0,177.0,180.0,183.0,186.0,189.0,192.0,195.0,198.0,201.0,204.0,207.0,210.0,213.0,216.0,219.0,222.0,225.0,228.0,231.0,234.0,237.0,240.0,243.0,246.0,249.0,252.0,255.0,258.0,261.0,264.0,267.0,270.0,273.0,276.0,279.0,282.0,285.0,288.0,291.0,294.0,297.0,300.0],"times":[5221100.0,10310700.0,15494700.0,20671900.0,25925300.0,31327400.0,36690500.0,40965500.0,46206200.0,51338900.0,56449900.0,61680100.0,66996200.0,71892900.0,77189700.0,82469100.0,87963700.0,92824100.0,98142300.0,103275300.0,108605900.0,112892500.0,118092400.0,123752200.0,128828500.0,134591900.0,139437200.0,144917200.0,149748300.0,153937200.0,159645600.0,164919600.0,170575900.0,175750000.0,180767700.0,184820100.0,190747500.0,196404400.0,201203200.0,206934100.0,210230300.0,216219700.0,222038100.0,227455200.0,232226300.0,236920000.0,243028300.0,248063200.0,253399700.0,259671700.0,265782600.0,271158900.0,275606600.0,280703800.0,287187500.0,292946600.0,295974400.0,302314100.0,308491700.0,311898500.0,317869600.0,323995500.0,328566100.0,333242200.0,339485200.0,340772600.0,345945600.0,352019200.0,356400500.0,361504700.0,368010600.0,371138100.0,377580200.0,382896300.0,386773200.0,393159100.0,397348700.0,403542100.0,409196300.0,412181500.0,419353600.0,423251100.0,429366800.0,434009600.0,438607000.0,444900300.0,448463200.0,454783000.0,457413100.0,464121700.0,468446600.0,474182600.0,479014800.0,484602400.0,489286200.0,494730100.0,499621700.0,504924800.0,510109800.0,515481900.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/tukey.json new file mode 100644 index 00000000..f30f78eb --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/base/tukey.json @@ -0,0 +1 @@ +[1695503.094474969,1706672.383909493,1736457.1557348904,1747626.4451694144] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/change/estimates.json new file mode 100644 index 00000000..1ba55a50 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.0056281569300802746,"upper_bound":0.008978689242570918},"point_estimate":0.007326753926007568,"standard_error":0.0008555557388002014},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.006466091181285427,"upper_bound":0.009549642489162569},"point_estimate":0.008324737793005577,"standard_error":0.0007834558212070103}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/benchmark.json new file mode 100644 index 00000000..40fadb35 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-encoded-loop","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-encoded-loop/tera","directory_name":"idiomatic-encoded-loop/tera","title":"idiomatic-encoded-loop/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/estimates.json new file mode 100644 index 00000000..3769a0a5 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1721363.0496276317,"upper_bound":1724733.543487789},"point_estimate":1723011.488306616,"standard_error":859.8048918771871},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1719904.856254856,"upper_bound":1722845.6140350876},"point_estimate":1721448.9329805998,"standard_error":707.0395779597013},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4535.282593023239,"upper_bound":7439.658825666248},"point_estimate":5464.630294187406,"standard_error":745.0640491388958},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1721243.505978439,"upper_bound":1724592.3675082077},"point_estimate":1722795.8142948623,"standard_error":854.6887262111147},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":7251.640106430205,"upper_bound":9814.778267493975},"point_estimate":8652.698774824605,"standard_error":655.8130487986845}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/sample.json new file mode 100644 index 00000000..9b303523 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[3.0,6.0,9.0,12.0,15.0,18.0,21.0,24.0,27.0,30.0,33.0,36.0,39.0,42.0,45.0,48.0,51.0,54.0,57.0,60.0,63.0,66.0,69.0,72.0,75.0,78.0,81.0,84.0,87.0,90.0,93.0,96.0,99.0,102.0,105.0,108.0,111.0,114.0,117.0,120.0,123.0,126.0,129.0,132.0,135.0,138.0,141.0,144.0,147.0,150.0,153.0,156.0,159.0,162.0,165.0,168.0,171.0,174.0,177.0,180.0,183.0,186.0,189.0,192.0,195.0,198.0,201.0,204.0,207.0,210.0,213.0,216.0,219.0,222.0,225.0,228.0,231.0,234.0,237.0,240.0,243.0,246.0,249.0,252.0,255.0,258.0,261.0,264.0,267.0,270.0,273.0,276.0,279.0,282.0,285.0,288.0,291.0,294.0,297.0,300.0],"times":[5221100.0,10310700.0,15494700.0,20671900.0,25925300.0,31327400.0,36690500.0,40965500.0,46206200.0,51338900.0,56449900.0,61680100.0,66996200.0,71892900.0,77189700.0,82469100.0,87963700.0,92824100.0,98142300.0,103275300.0,108605900.0,112892500.0,118092400.0,123752200.0,128828500.0,134591900.0,139437200.0,144917200.0,149748300.0,153937200.0,159645600.0,164919600.0,170575900.0,175750000.0,180767700.0,184820100.0,190747500.0,196404400.0,201203200.0,206934100.0,210230300.0,216219700.0,222038100.0,227455200.0,232226300.0,236920000.0,243028300.0,248063200.0,253399700.0,259671700.0,265782600.0,271158900.0,275606600.0,280703800.0,287187500.0,292946600.0,295974400.0,302314100.0,308491700.0,311898500.0,317869600.0,323995500.0,328566100.0,333242200.0,339485200.0,340772600.0,345945600.0,352019200.0,356400500.0,361504700.0,368010600.0,371138100.0,377580200.0,382896300.0,386773200.0,393159100.0,397348700.0,403542100.0,409196300.0,412181500.0,419353600.0,423251100.0,429366800.0,434009600.0,438607000.0,444900300.0,448463200.0,454783000.0,457413100.0,464121700.0,468446600.0,474182600.0,479014800.0,484602400.0,489286200.0,494730100.0,499621700.0,504924800.0,510109800.0,515481900.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/tukey.json new file mode 100644 index 00000000..f30f78eb --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-encoded-loop/tera/new/tukey.json @@ -0,0 +1 @@ +[1695503.094474969,1706672.383909493,1736457.1557348904,1747626.4451694144] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/benchmark.json new file mode 100644 index 00000000..86ad67f4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-fortunes-encoded","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-fortunes-encoded/askama","directory_name":"idiomatic-fortunes-encoded/askama","title":"idiomatic-fortunes-encoded/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/estimates.json new file mode 100644 index 00000000..d598d6fb --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":433.5254913240876,"upper_bound":436.6869735886901},"point_estimate":435.08670726462833,"standard_error":0.8084277744823563},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":430.24837160848466,"upper_bound":435.166959567031},"point_estimate":431.12580525813985,"standard_error":1.2864811785207373},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4.509057508205993,"upper_bound":10.42297362594262},"point_estimate":6.41454022043186,"standard_error":1.6357878839724695},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":432.29694781698146,"upper_bound":435.245902366586},"point_estimate":433.774956317132,"standard_error":0.751989927370491},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":7.316649078021114,"upper_bound":8.723760382711188},"point_estimate":8.125575467030435,"standard_error":0.3593903447104667}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/sample.json new file mode 100644 index 00000000..63c5042a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[11994.0,23988.0,35982.0,47976.0,59970.0,71964.0,83958.0,95952.0,107946.0,119940.0,131934.0,143928.0,155922.0,167916.0,179910.0,191904.0,203898.0,215892.0,227886.0,239880.0,251874.0,263868.0,275862.0,287856.0,299850.0,311844.0,323838.0,335832.0,347826.0,359820.0,371814.0,383808.0,395802.0,407796.0,419790.0,431784.0,443778.0,455772.0,467766.0,479760.0,491754.0,503748.0,515742.0,527736.0,539730.0,551724.0,563718.0,575712.0,587706.0,599700.0,611694.0,623688.0,635682.0,647676.0,659670.0,671664.0,683658.0,695652.0,707646.0,719640.0,731634.0,743628.0,755622.0,767616.0,779610.0,791604.0,803598.0,815592.0,827586.0,839580.0,851574.0,863568.0,875562.0,887556.0,899550.0,911544.0,923538.0,935532.0,947526.0,959520.0,971514.0,983508.0,995502.0,1007496.0,1019490.0,1031484.0,1043478.0,1055472.0,1067466.0,1079460.0,1091454.0,1103448.0,1115442.0,1127436.0,1139430.0,1151424.0,1163418.0,1175412.0,1187406.0,1199400.0],"times":[5380000.0,10737200.0,16094000.0,21469700.0,26830500.0,32219600.0,37575800.0,42936200.0,48338000.0,53694300.0,59036800.0,64403300.0,69789500.0,75058000.0,80157300.0,85777600.0,90991700.0,96899300.0,102232600.0,107751300.0,112959500.0,118195100.0,120882000.0,123057600.0,128262100.0,133168900.0,138047100.0,143635100.0,149046200.0,153892600.0,158624000.0,163610100.0,169473700.0,174137500.0,179955000.0,186038400.0,190416400.0,194723100.0,199379000.0,205228700.0,210115500.0,215937700.0,220520300.0,225124900.0,231659400.0,235712800.0,240938200.0,246288200.0,251514400.0,257774800.0,262358700.0,267986200.0,275845600.0,279151500.0,284811400.0,289045800.0,294378700.0,299336300.0,304149100.0,309453200.0,313514400.0,320609200.0,325643900.0,330926700.0,334797900.0,342463200.0,341841600.0,348238700.0,352505300.0,357678400.0,362462600.0,367106300.0,374490100.0,389536900.0,397025400.0,398016300.0,406167900.0,410539500.0,414939200.0,419641100.0,427112400.0,432691300.0,437109700.0,441693000.0,457219000.0,447526600.0,453190700.0,454402900.0,462321800.0,467147400.0,478707300.0,489196500.0,491461200.0,492010200.0,490190400.0,496857500.0,500558700.0,506259300.0,514436900.0,532430800.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/tukey.json new file mode 100644 index 00000000..19bdd376 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/base/tukey.json @@ -0,0 +1 @@ +[386.11539414215645,407.01722874309337,462.75545434559183,483.65728894652875] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/change/estimates.json new file mode 100644 index 00000000..66df3a98 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.0181824014390754,"upper_bound":0.027296608134970025},"point_estimate":0.022886730524704024,"standard_error":0.0023231679478814943},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.009396074745963042,"upper_bound":0.01961761267832185},"point_estimate":0.012310000898788642,"standard_error":0.0028937162118560186}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/benchmark.json new file mode 100644 index 00000000..86ad67f4 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-fortunes-encoded","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-fortunes-encoded/askama","directory_name":"idiomatic-fortunes-encoded/askama","title":"idiomatic-fortunes-encoded/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/estimates.json new file mode 100644 index 00000000..d598d6fb --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":433.5254913240876,"upper_bound":436.6869735886901},"point_estimate":435.08670726462833,"standard_error":0.8084277744823563},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":430.24837160848466,"upper_bound":435.166959567031},"point_estimate":431.12580525813985,"standard_error":1.2864811785207373},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4.509057508205993,"upper_bound":10.42297362594262},"point_estimate":6.41454022043186,"standard_error":1.6357878839724695},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":432.29694781698146,"upper_bound":435.245902366586},"point_estimate":433.774956317132,"standard_error":0.751989927370491},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":7.316649078021114,"upper_bound":8.723760382711188},"point_estimate":8.125575467030435,"standard_error":0.3593903447104667}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/sample.json new file mode 100644 index 00000000..63c5042a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[11994.0,23988.0,35982.0,47976.0,59970.0,71964.0,83958.0,95952.0,107946.0,119940.0,131934.0,143928.0,155922.0,167916.0,179910.0,191904.0,203898.0,215892.0,227886.0,239880.0,251874.0,263868.0,275862.0,287856.0,299850.0,311844.0,323838.0,335832.0,347826.0,359820.0,371814.0,383808.0,395802.0,407796.0,419790.0,431784.0,443778.0,455772.0,467766.0,479760.0,491754.0,503748.0,515742.0,527736.0,539730.0,551724.0,563718.0,575712.0,587706.0,599700.0,611694.0,623688.0,635682.0,647676.0,659670.0,671664.0,683658.0,695652.0,707646.0,719640.0,731634.0,743628.0,755622.0,767616.0,779610.0,791604.0,803598.0,815592.0,827586.0,839580.0,851574.0,863568.0,875562.0,887556.0,899550.0,911544.0,923538.0,935532.0,947526.0,959520.0,971514.0,983508.0,995502.0,1007496.0,1019490.0,1031484.0,1043478.0,1055472.0,1067466.0,1079460.0,1091454.0,1103448.0,1115442.0,1127436.0,1139430.0,1151424.0,1163418.0,1175412.0,1187406.0,1199400.0],"times":[5380000.0,10737200.0,16094000.0,21469700.0,26830500.0,32219600.0,37575800.0,42936200.0,48338000.0,53694300.0,59036800.0,64403300.0,69789500.0,75058000.0,80157300.0,85777600.0,90991700.0,96899300.0,102232600.0,107751300.0,112959500.0,118195100.0,120882000.0,123057600.0,128262100.0,133168900.0,138047100.0,143635100.0,149046200.0,153892600.0,158624000.0,163610100.0,169473700.0,174137500.0,179955000.0,186038400.0,190416400.0,194723100.0,199379000.0,205228700.0,210115500.0,215937700.0,220520300.0,225124900.0,231659400.0,235712800.0,240938200.0,246288200.0,251514400.0,257774800.0,262358700.0,267986200.0,275845600.0,279151500.0,284811400.0,289045800.0,294378700.0,299336300.0,304149100.0,309453200.0,313514400.0,320609200.0,325643900.0,330926700.0,334797900.0,342463200.0,341841600.0,348238700.0,352505300.0,357678400.0,362462600.0,367106300.0,374490100.0,389536900.0,397025400.0,398016300.0,406167900.0,410539500.0,414939200.0,419641100.0,427112400.0,432691300.0,437109700.0,441693000.0,457219000.0,447526600.0,453190700.0,454402900.0,462321800.0,467147400.0,478707300.0,489196500.0,491461200.0,492010200.0,490190400.0,496857500.0,500558700.0,506259300.0,514436900.0,532430800.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/tukey.json new file mode 100644 index 00000000..19bdd376 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/askama/new/tukey.json @@ -0,0 +1 @@ +[386.11539414215645,407.01722874309337,462.75545434559183,483.65728894652875] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/benchmark.json new file mode 100644 index 00000000..b19d384a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-fortunes-encoded","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-fortunes-encoded/tera","directory_name":"idiomatic-fortunes-encoded/tera","title":"idiomatic-fortunes-encoded/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/estimates.json new file mode 100644 index 00000000..ff5750c3 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3453.3479369222227,"upper_bound":3455.296502242793},"point_estimate":3454.323422696599,"standard_error":0.49670136517297814},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3453.044925257976,"upper_bound":3456.079040624957},"point_estimate":3454.4364845931577,"standard_error":0.8688527301887526},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5.582898128978405,"upper_bound":8.014197262298767},"point_estimate":7.496365740756635,"standard_error":0.6314136289476945},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3455.8036303718404,"upper_bound":3457.7110073146696},"point_estimate":3456.821555218872,"standard_error":0.487264097375286},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4.541587885120078,"upper_bound":5.335822468180175},"point_estimate":4.977017291827083,"standard_error":0.20301462412899846}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/sample.json new file mode 100644 index 00000000..3925c775 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[1493.0,2986.0,4479.0,5972.0,7465.0,8958.0,10451.0,11944.0,13437.0,14930.0,16423.0,17916.0,19409.0,20902.0,22395.0,23888.0,25381.0,26874.0,28367.0,29860.0,31353.0,32846.0,34339.0,35832.0,37325.0,38818.0,40311.0,41804.0,43297.0,44790.0,46283.0,47776.0,49269.0,50762.0,52255.0,53748.0,55241.0,56734.0,58227.0,59720.0,61213.0,62706.0,64199.0,65692.0,67185.0,68678.0,70171.0,71664.0,73157.0,74650.0,76143.0,77636.0,79129.0,80622.0,82115.0,83608.0,85101.0,86594.0,88087.0,89580.0,91073.0,92566.0,94059.0,95552.0,97045.0,98538.0,100031.0,101524.0,103017.0,104510.0,106003.0,107496.0,108989.0,110482.0,111975.0,113468.0,114961.0,116454.0,117947.0,119440.0,120933.0,122426.0,123919.0,125412.0,126905.0,128398.0,129891.0,131384.0,132877.0,134370.0,135863.0,137356.0,138849.0,140342.0,141835.0,143328.0,144821.0,146314.0,147807.0,149300.0],"times":[5169200.0,10298400.0,15468900.0,20624300.0,25784800.0,30885700.0,36046300.0,41247600.0,46342600.0,51516300.0,56629100.0,61765900.0,66935600.0,72072200.0,77267600.0,82462900.0,87560800.0,92806100.0,98006700.0,103192000.0,108247900.0,113475000.0,118614900.0,123698100.0,128771000.0,134040600.0,139227300.0,144418300.0,149432200.0,154793100.0,159777700.0,164981800.0,170129800.0,175042800.0,180100500.0,185265400.0,190498800.0,195532300.0,200759800.0,205950100.0,211144500.0,216036200.0,221206900.0,226346600.0,231674900.0,236796000.0,241938400.0,247154800.0,252338400.0,258208700.0,263437000.0,268591700.0,273859200.0,278802200.0,284015600.0,289288300.0,294345800.0,299646300.0,304833200.0,309952900.0,315122700.0,320404500.0,325470100.0,330683100.0,335868000.0,339801200.0,345173900.0,350103300.0,355368400.0,360654300.0,366029400.0,371360000.0,376680100.0,382067900.0,386991200.0,392400900.0,397352800.0,402711000.0,407682700.0,412799100.0,417835800.0,423628300.0,428918800.0,434151000.0,439193900.0,444196500.0,449384100.0,454334300.0,459682300.0,464771900.0,469809900.0,475125200.0,480394500.0,485693300.0,490866800.0,496012600.0,501155000.0,505666600.0,510271800.0,515870400.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/tukey.json new file mode 100644 index 00000000..6504c096 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/base/tukey.json @@ -0,0 +1 @@ +[3419.7748134507865,3434.5492307610375,3473.9476769217063,3488.722094231957] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/change/estimates.json new file mode 100644 index 00000000..fde39599 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.008506651273459237,"upper_bound":0.009644230734587384},"point_estimate":0.009077703044635177,"standard_error":0.0002902163649665998},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.00891729985905676,"upper_bound":0.010408880240533325},"point_estimate":0.009756439853892518,"standard_error":0.00038765067579093804}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/benchmark.json new file mode 100644 index 00000000..b19d384a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-fortunes-encoded","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-fortunes-encoded/tera","directory_name":"idiomatic-fortunes-encoded/tera","title":"idiomatic-fortunes-encoded/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/estimates.json new file mode 100644 index 00000000..ff5750c3 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3453.3479369222227,"upper_bound":3455.296502242793},"point_estimate":3454.323422696599,"standard_error":0.49670136517297814},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3453.044925257976,"upper_bound":3456.079040624957},"point_estimate":3454.4364845931577,"standard_error":0.8688527301887526},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5.582898128978405,"upper_bound":8.014197262298767},"point_estimate":7.496365740756635,"standard_error":0.6314136289476945},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3455.8036303718404,"upper_bound":3457.7110073146696},"point_estimate":3456.821555218872,"standard_error":0.487264097375286},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4.541587885120078,"upper_bound":5.335822468180175},"point_estimate":4.977017291827083,"standard_error":0.20301462412899846}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/sample.json new file mode 100644 index 00000000..3925c775 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[1493.0,2986.0,4479.0,5972.0,7465.0,8958.0,10451.0,11944.0,13437.0,14930.0,16423.0,17916.0,19409.0,20902.0,22395.0,23888.0,25381.0,26874.0,28367.0,29860.0,31353.0,32846.0,34339.0,35832.0,37325.0,38818.0,40311.0,41804.0,43297.0,44790.0,46283.0,47776.0,49269.0,50762.0,52255.0,53748.0,55241.0,56734.0,58227.0,59720.0,61213.0,62706.0,64199.0,65692.0,67185.0,68678.0,70171.0,71664.0,73157.0,74650.0,76143.0,77636.0,79129.0,80622.0,82115.0,83608.0,85101.0,86594.0,88087.0,89580.0,91073.0,92566.0,94059.0,95552.0,97045.0,98538.0,100031.0,101524.0,103017.0,104510.0,106003.0,107496.0,108989.0,110482.0,111975.0,113468.0,114961.0,116454.0,117947.0,119440.0,120933.0,122426.0,123919.0,125412.0,126905.0,128398.0,129891.0,131384.0,132877.0,134370.0,135863.0,137356.0,138849.0,140342.0,141835.0,143328.0,144821.0,146314.0,147807.0,149300.0],"times":[5169200.0,10298400.0,15468900.0,20624300.0,25784800.0,30885700.0,36046300.0,41247600.0,46342600.0,51516300.0,56629100.0,61765900.0,66935600.0,72072200.0,77267600.0,82462900.0,87560800.0,92806100.0,98006700.0,103192000.0,108247900.0,113475000.0,118614900.0,123698100.0,128771000.0,134040600.0,139227300.0,144418300.0,149432200.0,154793100.0,159777700.0,164981800.0,170129800.0,175042800.0,180100500.0,185265400.0,190498800.0,195532300.0,200759800.0,205950100.0,211144500.0,216036200.0,221206900.0,226346600.0,231674900.0,236796000.0,241938400.0,247154800.0,252338400.0,258208700.0,263437000.0,268591700.0,273859200.0,278802200.0,284015600.0,289288300.0,294345800.0,299646300.0,304833200.0,309952900.0,315122700.0,320404500.0,325470100.0,330683100.0,335868000.0,339801200.0,345173900.0,350103300.0,355368400.0,360654300.0,366029400.0,371360000.0,376680100.0,382067900.0,386991200.0,392400900.0,397352800.0,402711000.0,407682700.0,412799100.0,417835800.0,423628300.0,428918800.0,434151000.0,439193900.0,444196500.0,449384100.0,454334300.0,459682300.0,464771900.0,469809900.0,475125200.0,480394500.0,485693300.0,490866800.0,496012600.0,501155000.0,505666600.0,510271800.0,515870400.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/tukey.json new file mode 100644 index 00000000..6504c096 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fortunes-encoded/tera/new/tukey.json @@ -0,0 +1 @@ +[3419.7748134507865,3434.5492307610375,3473.9476769217063,3488.722094231957] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/benchmark.json new file mode 100644 index 00000000..e7982750 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-fragment-heavy","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-fragment-heavy/askama","directory_name":"idiomatic-fragment-heavy/askama","title":"idiomatic-fragment-heavy/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/estimates.json new file mode 100644 index 00000000..2c1610ba --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1181.431634036709,"upper_bound":1185.9857346169251},"point_estimate":1183.6834507017581,"standard_error":1.1619592181346712},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1179.8184449958644,"upper_bound":1185.3302611367128},"point_estimate":1182.040384702268,"standard_error":1.611778450580066},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5.641609729063367,"upper_bound":18.601206338989403},"point_estimate":9.30854476561597,"standard_error":3.7861847071060892},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1175.7074835633566,"upper_bound":1180.846590830718},"point_estimate":1178.1421474095962,"standard_error":1.316174039603452},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":10.13424717666085,"upper_bound":12.953606892370743},"point_estimate":11.653675970658526,"standard_error":0.7157498288060663}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/sample.json new file mode 100644 index 00000000..a488e241 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[4340.0,8680.0,13020.0,17360.0,21700.0,26040.0,30380.0,34720.0,39060.0,43400.0,47740.0,52080.0,56420.0,60760.0,65100.0,69440.0,73780.0,78120.0,82460.0,86800.0,91140.0,95480.0,99820.0,104160.0,108500.0,112840.0,117180.0,121520.0,125860.0,130200.0,134540.0,138880.0,143220.0,147560.0,151900.0,156240.0,160580.0,164920.0,169260.0,173600.0,177940.0,182280.0,186620.0,190960.0,195300.0,199640.0,203980.0,208320.0,212660.0,217000.0,221340.0,225680.0,230020.0,234360.0,238700.0,243040.0,247380.0,251720.0,256060.0,260400.0,264740.0,269080.0,273420.0,277760.0,282100.0,286440.0,290780.0,295120.0,299460.0,303800.0,308140.0,312480.0,316820.0,321160.0,325500.0,329840.0,334180.0,338520.0,342860.0,347200.0,351540.0,355880.0,360220.0,364560.0,368900.0,373240.0,377580.0,381920.0,386260.0,390600.0,394940.0,399280.0,403620.0,407960.0,412300.0,416640.0,420980.0,425320.0,429660.0,434000.0],"times":[5150000.0,10281800.0,15436600.0,20577800.0,25719300.0,30866000.0,36006200.0,41143000.0,46305600.0,51428700.0,56588200.0,61754000.0,66866200.0,72000100.0,77178000.0,82313500.0,87471600.0,92643400.0,97793300.0,102966800.0,108096100.0,113247000.0,118417100.0,123531300.0,128674800.0,134836800.0,141013900.0,146173500.0,151401100.0,156658500.0,161856700.0,167063000.0,172319100.0,177553500.0,182711300.0,187888600.0,193192900.0,198510500.0,203714400.0,208971300.0,214167900.0,219320600.0,224548900.0,229839900.0,232759600.0,233271900.0,238818800.0,244181400.0,249260700.0,254240400.0,259334900.0,264356500.0,269473500.0,274774600.0,281563900.0,286704200.0,291859000.0,296937800.0,302078500.0,307230800.0,312314800.0,317439900.0,322568300.0,327708700.0,332831900.0,337815900.0,342983000.0,348844400.0,353994300.0,359069600.0,364208100.0,369363300.0,374492000.0,379609500.0,384685300.0,389835100.0,391800300.0,393917400.0,399655800.0,405521400.0,414084300.0,419505400.0,424566800.0,428022200.0,426993200.0,432085300.0,440967100.0,447604600.0,452760100.0,457885600.0,462906200.0,475613200.0,483393100.0,488264400.0,483188900.0,488224800.0,493345800.0,498434400.0,503597800.0,508749600.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/tukey.json new file mode 100644 index 00000000..a87ea89e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/base/tukey.json @@ -0,0 +1 @@ +[1130.9628954050922,1151.7018146371988,1207.0055992561497,1227.7445184882563] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/change/estimates.json new file mode 100644 index 00000000..461372cf --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.006410549526159803,"upper_bound":-0.0010293839923635546},"point_estimate":-0.0037254403952902138,"standard_error":0.0013752740130626691},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.005254539381098655,"upper_bound":0.0013080462032346585},"point_estimate":-0.002536989119744426,"standard_error":0.0017389047851537561}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/benchmark.json new file mode 100644 index 00000000..e7982750 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-fragment-heavy","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-fragment-heavy/askama","directory_name":"idiomatic-fragment-heavy/askama","title":"idiomatic-fragment-heavy/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/estimates.json new file mode 100644 index 00000000..2c1610ba --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1181.431634036709,"upper_bound":1185.9857346169251},"point_estimate":1183.6834507017581,"standard_error":1.1619592181346712},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1179.8184449958644,"upper_bound":1185.3302611367128},"point_estimate":1182.040384702268,"standard_error":1.611778450580066},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":5.641609729063367,"upper_bound":18.601206338989403},"point_estimate":9.30854476561597,"standard_error":3.7861847071060892},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1175.7074835633566,"upper_bound":1180.846590830718},"point_estimate":1178.1421474095962,"standard_error":1.316174039603452},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":10.13424717666085,"upper_bound":12.953606892370743},"point_estimate":11.653675970658526,"standard_error":0.7157498288060663}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/sample.json new file mode 100644 index 00000000..a488e241 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[4340.0,8680.0,13020.0,17360.0,21700.0,26040.0,30380.0,34720.0,39060.0,43400.0,47740.0,52080.0,56420.0,60760.0,65100.0,69440.0,73780.0,78120.0,82460.0,86800.0,91140.0,95480.0,99820.0,104160.0,108500.0,112840.0,117180.0,121520.0,125860.0,130200.0,134540.0,138880.0,143220.0,147560.0,151900.0,156240.0,160580.0,164920.0,169260.0,173600.0,177940.0,182280.0,186620.0,190960.0,195300.0,199640.0,203980.0,208320.0,212660.0,217000.0,221340.0,225680.0,230020.0,234360.0,238700.0,243040.0,247380.0,251720.0,256060.0,260400.0,264740.0,269080.0,273420.0,277760.0,282100.0,286440.0,290780.0,295120.0,299460.0,303800.0,308140.0,312480.0,316820.0,321160.0,325500.0,329840.0,334180.0,338520.0,342860.0,347200.0,351540.0,355880.0,360220.0,364560.0,368900.0,373240.0,377580.0,381920.0,386260.0,390600.0,394940.0,399280.0,403620.0,407960.0,412300.0,416640.0,420980.0,425320.0,429660.0,434000.0],"times":[5150000.0,10281800.0,15436600.0,20577800.0,25719300.0,30866000.0,36006200.0,41143000.0,46305600.0,51428700.0,56588200.0,61754000.0,66866200.0,72000100.0,77178000.0,82313500.0,87471600.0,92643400.0,97793300.0,102966800.0,108096100.0,113247000.0,118417100.0,123531300.0,128674800.0,134836800.0,141013900.0,146173500.0,151401100.0,156658500.0,161856700.0,167063000.0,172319100.0,177553500.0,182711300.0,187888600.0,193192900.0,198510500.0,203714400.0,208971300.0,214167900.0,219320600.0,224548900.0,229839900.0,232759600.0,233271900.0,238818800.0,244181400.0,249260700.0,254240400.0,259334900.0,264356500.0,269473500.0,274774600.0,281563900.0,286704200.0,291859000.0,296937800.0,302078500.0,307230800.0,312314800.0,317439900.0,322568300.0,327708700.0,332831900.0,337815900.0,342983000.0,348844400.0,353994300.0,359069600.0,364208100.0,369363300.0,374492000.0,379609500.0,384685300.0,389835100.0,391800300.0,393917400.0,399655800.0,405521400.0,414084300.0,419505400.0,424566800.0,428022200.0,426993200.0,432085300.0,440967100.0,447604600.0,452760100.0,457885600.0,462906200.0,475613200.0,483393100.0,488264400.0,483188900.0,488224800.0,493345800.0,498434400.0,503597800.0,508749600.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/tukey.json new file mode 100644 index 00000000..a87ea89e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/askama/new/tukey.json @@ -0,0 +1 @@ +[1130.9628954050922,1151.7018146371988,1207.0055992561497,1227.7445184882563] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/benchmark.json new file mode 100644 index 00000000..2d8159f0 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-fragment-heavy","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-fragment-heavy/tera","directory_name":"idiomatic-fragment-heavy/tera","title":"idiomatic-fragment-heavy/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/estimates.json new file mode 100644 index 00000000..06f8d65a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":14511.12719481238,"upper_bound":14538.293110172512},"point_estimate":14524.690194284682,"standard_error":6.947542897455837},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":14506.04189237992,"upper_bound":14550.123772940675},"point_estimate":14516.474605207,"standard_error":13.959853977379026},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":46.80076494898276,"upper_bound":102.04758071785832},"point_estimate":64.17233865885932,"standard_error":12.807111917970316},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":14497.36208204086,"upper_bound":14531.130394092806},"point_estimate":14513.516009965511,"standard_error":8.59704889191526},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":61.88453153482129,"upper_bound":76.7912003387596},"point_estimate":69.99882020990225,"standard_error":3.8148320983852755}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/sample.json new file mode 100644 index 00000000..67557611 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[355.0,710.0,1065.0,1420.0,1775.0,2130.0,2485.0,2840.0,3195.0,3550.0,3905.0,4260.0,4615.0,4970.0,5325.0,5680.0,6035.0,6390.0,6745.0,7100.0,7455.0,7810.0,8165.0,8520.0,8875.0,9230.0,9585.0,9940.0,10295.0,10650.0,11005.0,11360.0,11715.0,12070.0,12425.0,12780.0,13135.0,13490.0,13845.0,14200.0,14555.0,14910.0,15265.0,15620.0,15975.0,16330.0,16685.0,17040.0,17395.0,17750.0,18105.0,18460.0,18815.0,19170.0,19525.0,19880.0,20235.0,20590.0,20945.0,21300.0,21655.0,22010.0,22365.0,22720.0,23075.0,23430.0,23785.0,24140.0,24495.0,24850.0,25205.0,25560.0,25915.0,26270.0,26625.0,26980.0,27335.0,27690.0,28045.0,28400.0,28755.0,29110.0,29465.0,29820.0,30175.0,30530.0,30885.0,31240.0,31595.0,31950.0,32305.0,32660.0,33015.0,33370.0,33725.0,34080.0,34435.0,34790.0,35145.0,35500.0],"times":[5186200.0,10330200.0,15529400.0,20678300.0,25836000.0,30999200.0,36164600.0,41326700.0,46495400.0,51699300.0,56828700.0,62019400.0,67199400.0,72336600.0,77478100.0,82634900.0,87832800.0,92640400.0,97891300.0,102978500.0,108113900.0,113320200.0,118455000.0,123639500.0,128837500.0,133903200.0,139027500.0,144210400.0,149340300.0,154519800.0,159725500.0,164767200.0,170055500.0,174128600.0,179237900.0,184379500.0,189480200.0,194643100.0,199844200.0,204965300.0,210020000.0,215195700.0,220281200.0,225419000.0,230496300.0,235686000.0,240730400.0,245904600.0,250919100.0,259814600.0,265124200.0,270269600.0,275522100.0,280759000.0,285912800.0,291112100.0,296182300.0,301588700.0,306676200.0,311913800.0,317038200.0,322252800.0,327542900.0,332760800.0,337885600.0,340922200.0,346182600.0,351460900.0,356479900.0,361822000.0,366991600.0,372222700.0,377340800.0,382499100.0,387748900.0,392349600.0,397341800.0,402576100.0,407958400.0,412659900.0,417789500.0,421252900.0,426499400.0,431639200.0,436836900.0,441918600.0,446974000.0,452024100.0,457263800.0,462592900.0,467631800.0,472994300.0,478045300.0,483162800.0,488314200.0,493515200.0,498583700.0,501471800.0,506632900.0,511556400.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/tukey.json new file mode 100644 index 00000000..09694e1a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/base/tukey.json @@ -0,0 +1 @@ +[14218.680170466647,14346.77917714916,14688.376528302526,14816.475534985038] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/change/estimates.json new file mode 100644 index 00000000..1706c3ee --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.029501243406243525,"upper_bound":-0.026664771770371642},"point_estimate":-0.02809977466862379,"standard_error":0.0007226761959775459},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.0314873788457957,"upper_bound":-0.023398335898229705},"point_estimate":-0.03063330911085116,"standard_error":0.002678932043641114}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/benchmark.json new file mode 100644 index 00000000..2d8159f0 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-fragment-heavy","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-fragment-heavy/tera","directory_name":"idiomatic-fragment-heavy/tera","title":"idiomatic-fragment-heavy/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/estimates.json new file mode 100644 index 00000000..06f8d65a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":14511.12719481238,"upper_bound":14538.293110172512},"point_estimate":14524.690194284682,"standard_error":6.947542897455837},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":14506.04189237992,"upper_bound":14550.123772940675},"point_estimate":14516.474605207,"standard_error":13.959853977379026},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":46.80076494898276,"upper_bound":102.04758071785832},"point_estimate":64.17233865885932,"standard_error":12.807111917970316},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":14497.36208204086,"upper_bound":14531.130394092806},"point_estimate":14513.516009965511,"standard_error":8.59704889191526},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":61.88453153482129,"upper_bound":76.7912003387596},"point_estimate":69.99882020990225,"standard_error":3.8148320983852755}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/sample.json new file mode 100644 index 00000000..67557611 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[355.0,710.0,1065.0,1420.0,1775.0,2130.0,2485.0,2840.0,3195.0,3550.0,3905.0,4260.0,4615.0,4970.0,5325.0,5680.0,6035.0,6390.0,6745.0,7100.0,7455.0,7810.0,8165.0,8520.0,8875.0,9230.0,9585.0,9940.0,10295.0,10650.0,11005.0,11360.0,11715.0,12070.0,12425.0,12780.0,13135.0,13490.0,13845.0,14200.0,14555.0,14910.0,15265.0,15620.0,15975.0,16330.0,16685.0,17040.0,17395.0,17750.0,18105.0,18460.0,18815.0,19170.0,19525.0,19880.0,20235.0,20590.0,20945.0,21300.0,21655.0,22010.0,22365.0,22720.0,23075.0,23430.0,23785.0,24140.0,24495.0,24850.0,25205.0,25560.0,25915.0,26270.0,26625.0,26980.0,27335.0,27690.0,28045.0,28400.0,28755.0,29110.0,29465.0,29820.0,30175.0,30530.0,30885.0,31240.0,31595.0,31950.0,32305.0,32660.0,33015.0,33370.0,33725.0,34080.0,34435.0,34790.0,35145.0,35500.0],"times":[5186200.0,10330200.0,15529400.0,20678300.0,25836000.0,30999200.0,36164600.0,41326700.0,46495400.0,51699300.0,56828700.0,62019400.0,67199400.0,72336600.0,77478100.0,82634900.0,87832800.0,92640400.0,97891300.0,102978500.0,108113900.0,113320200.0,118455000.0,123639500.0,128837500.0,133903200.0,139027500.0,144210400.0,149340300.0,154519800.0,159725500.0,164767200.0,170055500.0,174128600.0,179237900.0,184379500.0,189480200.0,194643100.0,199844200.0,204965300.0,210020000.0,215195700.0,220281200.0,225419000.0,230496300.0,235686000.0,240730400.0,245904600.0,250919100.0,259814600.0,265124200.0,270269600.0,275522100.0,280759000.0,285912800.0,291112100.0,296182300.0,301588700.0,306676200.0,311913800.0,317038200.0,322252800.0,327542900.0,332760800.0,337885600.0,340922200.0,346182600.0,351460900.0,356479900.0,361822000.0,366991600.0,372222700.0,377340800.0,382499100.0,387748900.0,392349600.0,397341800.0,402576100.0,407958400.0,412659900.0,417789500.0,421252900.0,426499400.0,431639200.0,436836900.0,441918600.0,446974000.0,452024100.0,457263800.0,462592900.0,467631800.0,472994300.0,478045300.0,483162800.0,488314200.0,493515200.0,498583700.0,501471800.0,506632900.0,511556400.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/tukey.json new file mode 100644 index 00000000..09694e1a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-fragment-heavy/tera/new/tukey.json @@ -0,0 +1 @@ +[14218.680170466647,14346.77917714916,14688.376528302526,14816.475534985038] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/benchmark.json new file mode 100644 index 00000000..6c412663 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-large-loop","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-large-loop/askama","directory_name":"idiomatic-large-loop/askama","title":"idiomatic-large-loop/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/estimates.json new file mode 100644 index 00000000..a5e9ec38 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":77759.62177591068,"upper_bound":78598.556716374},"point_estimate":78188.92028561461,"standard_error":213.7775908289984},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":78312.49421147414,"upper_bound":79273.61538461539},"point_estimate":78368.23330515638,"standard_error":324.2684158626302},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1369.9060833716132,"upper_bound":2719.7868844064415},"point_estimate":1700.5302638924072,"standard_error":441.46594684342864},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":77133.08260375464,"upper_bound":78373.19752408215},"point_estimate":77752.71770015119,"standard_error":317.1238614940342},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1845.6383041755896,"upper_bound":2395.9498148070697},"point_estimate":2149.0751301680257,"standard_error":140.34580730395766}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/sample.json new file mode 100644 index 00000000..030ce4ac --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[65.0,130.0,195.0,260.0,325.0,390.0,455.0,520.0,585.0,650.0,715.0,780.0,845.0,910.0,975.0,1040.0,1105.0,1170.0,1235.0,1300.0,1365.0,1430.0,1495.0,1560.0,1625.0,1690.0,1755.0,1820.0,1885.0,1950.0,2015.0,2080.0,2145.0,2210.0,2275.0,2340.0,2405.0,2470.0,2535.0,2600.0,2665.0,2730.0,2795.0,2860.0,2925.0,2990.0,3055.0,3120.0,3185.0,3250.0,3315.0,3380.0,3445.0,3510.0,3575.0,3640.0,3705.0,3770.0,3835.0,3900.0,3965.0,4030.0,4095.0,4160.0,4225.0,4290.0,4355.0,4420.0,4485.0,4550.0,4615.0,4680.0,4745.0,4810.0,4875.0,4940.0,5005.0,5070.0,5135.0,5200.0,5265.0,5330.0,5395.0,5460.0,5525.0,5590.0,5655.0,5720.0,5785.0,5850.0,5915.0,5980.0,6045.0,6110.0,6175.0,6240.0,6305.0,6370.0,6435.0,6500.0],"times":[5094000.0,10181700.0,15278300.0,20383200.0,25480800.0,30551800.0,35468100.0,40285100.0,45305500.0,50359400.0,55403300.0,60419400.0,65457300.0,70468000.0,75524400.0,80551300.0,85575300.0,90599700.0,96638600.0,101815800.0,106884900.0,112001500.0,117075600.0,122179000.0,127234100.0,132349900.0,137441400.0,142624300.0,150419900.0,157041200.0,162333400.0,167584700.0,172765400.0,178055400.0,183272900.0,188538000.0,193779100.0,198924800.0,204079400.0,209408500.0,214628900.0,220008100.0,225236200.0,230476500.0,235747100.0,240999300.0,246212800.0,251402700.0,256500200.0,261809600.0,267094000.0,256473200.0,252408700.0,257473200.0,262253600.0,267143800.0,272201700.0,279860400.0,286687100.0,291522000.0,296414900.0,302211700.0,313675100.0,318384600.0,323423800.0,335269400.0,347855800.0,352723900.0,348924900.0,358855900.0,365908300.0,370877800.0,375905500.0,381121200.0,386212600.0,391660900.0,396823500.0,401999700.0,407143300.0,412222800.0,417463000.0,422781300.0,427945700.0,433107300.0,438118500.0,443193000.0,448540500.0,458428100.0,463426600.0,466284600.0,463542200.0,470384900.0,463301700.0,453900800.0,462192200.0,464000200.0,470303400.0,473585300.0,480653900.0,484140300.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/tukey.json new file mode 100644 index 00000000..417bc0a6 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/base/tukey.json @@ -0,0 +1 @@ +[70319.30621215187,73882.10408646808,83382.898417978,86945.69629229422] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/change/estimates.json new file mode 100644 index 00000000..424069da --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.03140826318150882,"upper_bound":0.04993351346693909},"point_estimate":0.040491923975916055,"standard_error":0.0047188545770870975},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.05509803038619232,"upper_bound":0.07907850160265621},"point_estimate":0.06325858265708151,"standard_error":0.005949823458041756}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/benchmark.json new file mode 100644 index 00000000..6c412663 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-large-loop","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-large-loop/askama","directory_name":"idiomatic-large-loop/askama","title":"idiomatic-large-loop/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/estimates.json new file mode 100644 index 00000000..a5e9ec38 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":77759.62177591068,"upper_bound":78598.556716374},"point_estimate":78188.92028561461,"standard_error":213.7775908289984},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":78312.49421147414,"upper_bound":79273.61538461539},"point_estimate":78368.23330515638,"standard_error":324.2684158626302},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1369.9060833716132,"upper_bound":2719.7868844064415},"point_estimate":1700.5302638924072,"standard_error":441.46594684342864},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":77133.08260375464,"upper_bound":78373.19752408215},"point_estimate":77752.71770015119,"standard_error":317.1238614940342},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":1845.6383041755896,"upper_bound":2395.9498148070697},"point_estimate":2149.0751301680257,"standard_error":140.34580730395766}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/sample.json new file mode 100644 index 00000000..030ce4ac --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[65.0,130.0,195.0,260.0,325.0,390.0,455.0,520.0,585.0,650.0,715.0,780.0,845.0,910.0,975.0,1040.0,1105.0,1170.0,1235.0,1300.0,1365.0,1430.0,1495.0,1560.0,1625.0,1690.0,1755.0,1820.0,1885.0,1950.0,2015.0,2080.0,2145.0,2210.0,2275.0,2340.0,2405.0,2470.0,2535.0,2600.0,2665.0,2730.0,2795.0,2860.0,2925.0,2990.0,3055.0,3120.0,3185.0,3250.0,3315.0,3380.0,3445.0,3510.0,3575.0,3640.0,3705.0,3770.0,3835.0,3900.0,3965.0,4030.0,4095.0,4160.0,4225.0,4290.0,4355.0,4420.0,4485.0,4550.0,4615.0,4680.0,4745.0,4810.0,4875.0,4940.0,5005.0,5070.0,5135.0,5200.0,5265.0,5330.0,5395.0,5460.0,5525.0,5590.0,5655.0,5720.0,5785.0,5850.0,5915.0,5980.0,6045.0,6110.0,6175.0,6240.0,6305.0,6370.0,6435.0,6500.0],"times":[5094000.0,10181700.0,15278300.0,20383200.0,25480800.0,30551800.0,35468100.0,40285100.0,45305500.0,50359400.0,55403300.0,60419400.0,65457300.0,70468000.0,75524400.0,80551300.0,85575300.0,90599700.0,96638600.0,101815800.0,106884900.0,112001500.0,117075600.0,122179000.0,127234100.0,132349900.0,137441400.0,142624300.0,150419900.0,157041200.0,162333400.0,167584700.0,172765400.0,178055400.0,183272900.0,188538000.0,193779100.0,198924800.0,204079400.0,209408500.0,214628900.0,220008100.0,225236200.0,230476500.0,235747100.0,240999300.0,246212800.0,251402700.0,256500200.0,261809600.0,267094000.0,256473200.0,252408700.0,257473200.0,262253600.0,267143800.0,272201700.0,279860400.0,286687100.0,291522000.0,296414900.0,302211700.0,313675100.0,318384600.0,323423800.0,335269400.0,347855800.0,352723900.0,348924900.0,358855900.0,365908300.0,370877800.0,375905500.0,381121200.0,386212600.0,391660900.0,396823500.0,401999700.0,407143300.0,412222800.0,417463000.0,422781300.0,427945700.0,433107300.0,438118500.0,443193000.0,448540500.0,458428100.0,463426600.0,466284600.0,463542200.0,470384900.0,463301700.0,453900800.0,462192200.0,464000200.0,470303400.0,473585300.0,480653900.0,484140300.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/tukey.json new file mode 100644 index 00000000..417bc0a6 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/askama/new/tukey.json @@ -0,0 +1 @@ +[70319.30621215187,73882.10408646808,83382.898417978,86945.69629229422] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/benchmark.json new file mode 100644 index 00000000..bbd8fea1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-large-loop","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-large-loop/tera","directory_name":"idiomatic-large-loop/tera","title":"idiomatic-large-loop/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/estimates.json new file mode 100644 index 00000000..bbcefcd7 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":492805.9797903666,"upper_bound":493765.0569384772},"point_estimate":493281.871772118,"standard_error":244.43662758201197},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":491926.4462809917,"upper_bound":493898.54545454547},"point_estimate":492395.5126262626,"standard_error":759.8689319153169},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2155.938671605796,"upper_bound":4082.0547740024213},"point_estimate":2479.4436690137027,"standard_error":586.4022763205418},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":493533.7342765517,"upper_bound":494587.77584321453},"point_estimate":494068.11333073606,"standard_error":268.99603569816657},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2233.3073896333435,"upper_bound":2635.9825147916035},"point_estimate":2455.839550037119,"standard_error":102.77133064517804}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/sample.json new file mode 100644 index 00000000..d5bd597b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[11.0,22.0,33.0,44.0,55.0,66.0,77.0,88.0,99.0,110.0,121.0,132.0,143.0,154.0,165.0,176.0,187.0,198.0,209.0,220.0,231.0,242.0,253.0,264.0,275.0,286.0,297.0,308.0,319.0,330.0,341.0,352.0,363.0,374.0,385.0,396.0,407.0,418.0,429.0,440.0,451.0,462.0,473.0,484.0,495.0,506.0,517.0,528.0,539.0,550.0,561.0,572.0,583.0,594.0,605.0,616.0,627.0,638.0,649.0,660.0,671.0,682.0,693.0,704.0,715.0,726.0,737.0,748.0,759.0,770.0,781.0,792.0,803.0,814.0,825.0,836.0,847.0,858.0,869.0,880.0,891.0,902.0,913.0,924.0,935.0,946.0,957.0,968.0,979.0,990.0,1001.0,1012.0,1023.0,1034.0,1045.0,1056.0,1067.0,1078.0,1089.0,1100.0],"times":[5459900.0,10814300.0,16210600.0,21616900.0,26995000.0,32408600.0,37762000.0,43111900.0,48527400.0,53965000.0,59338500.0,64697300.0,70093100.0,75480200.0,80879500.0,86276800.0,91673200.0,97844700.0,103214000.0,108669600.0,114064700.0,119541000.0,124910000.0,130349400.0,135822100.0,141241500.0,146709900.0,152148100.0,157522000.0,162997700.0,168392900.0,173809500.0,179321700.0,183599300.0,189060800.0,194425500.0,199771000.0,205245500.0,210624200.0,216129500.0,221505600.0,226807100.0,232295600.0,237905900.0,242973500.0,248245400.0,253690700.0,259075600.0,264466200.0,272770300.0,278362600.0,284497800.0,289885800.0,295377500.0,301093900.0,306223100.0,311592400.0,316993600.0,322402400.0,328158600.0,333701500.0,339042500.0,344496800.0,349998200.0,355457100.0,356283500.0,361697500.0,367026400.0,372490100.0,378419700.0,384439000.0,390010700.0,395219900.0,400307300.0,405942400.0,411326900.0,416661700.0,422068100.0,427580800.0,432995800.0,438294100.0,447289000.0,453866300.0,459328800.0,463731400.0,468796200.0,473980500.0,479643100.0,484958400.0,490261100.0,495317600.0,500980900.0,506851700.0,512134200.0,517537200.0,523134600.0,528524700.0,530707000.0,536119100.0,541588600.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/tukey.json new file mode 100644 index 00000000..a6c18bca --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/base/tukey.json @@ -0,0 +1 @@ +[477779.2891506902,484375.3890392146,501964.9887419463,508561.0886304707] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/change/estimates.json new file mode 100644 index 00000000..0d1202cb --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.008410241366334238,"upper_bound":0.011087389670734936},"point_estimate":0.009753844171062953,"standard_error":0.0006807881844670552},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.005585444994761657,"upper_bound":0.01455024835294827},"point_estimate":0.009807062582921189,"standard_error":0.0027545210505544497}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/benchmark.json new file mode 100644 index 00000000..bbd8fea1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-large-loop","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-large-loop/tera","directory_name":"idiomatic-large-loop/tera","title":"idiomatic-large-loop/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/estimates.json new file mode 100644 index 00000000..bbcefcd7 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":492805.9797903666,"upper_bound":493765.0569384772},"point_estimate":493281.871772118,"standard_error":244.43662758201197},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":491926.4462809917,"upper_bound":493898.54545454547},"point_estimate":492395.5126262626,"standard_error":759.8689319153169},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2155.938671605796,"upper_bound":4082.0547740024213},"point_estimate":2479.4436690137027,"standard_error":586.4022763205418},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":493533.7342765517,"upper_bound":494587.77584321453},"point_estimate":494068.11333073606,"standard_error":268.99603569816657},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2233.3073896333435,"upper_bound":2635.9825147916035},"point_estimate":2455.839550037119,"standard_error":102.77133064517804}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/sample.json new file mode 100644 index 00000000..d5bd597b --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[11.0,22.0,33.0,44.0,55.0,66.0,77.0,88.0,99.0,110.0,121.0,132.0,143.0,154.0,165.0,176.0,187.0,198.0,209.0,220.0,231.0,242.0,253.0,264.0,275.0,286.0,297.0,308.0,319.0,330.0,341.0,352.0,363.0,374.0,385.0,396.0,407.0,418.0,429.0,440.0,451.0,462.0,473.0,484.0,495.0,506.0,517.0,528.0,539.0,550.0,561.0,572.0,583.0,594.0,605.0,616.0,627.0,638.0,649.0,660.0,671.0,682.0,693.0,704.0,715.0,726.0,737.0,748.0,759.0,770.0,781.0,792.0,803.0,814.0,825.0,836.0,847.0,858.0,869.0,880.0,891.0,902.0,913.0,924.0,935.0,946.0,957.0,968.0,979.0,990.0,1001.0,1012.0,1023.0,1034.0,1045.0,1056.0,1067.0,1078.0,1089.0,1100.0],"times":[5459900.0,10814300.0,16210600.0,21616900.0,26995000.0,32408600.0,37762000.0,43111900.0,48527400.0,53965000.0,59338500.0,64697300.0,70093100.0,75480200.0,80879500.0,86276800.0,91673200.0,97844700.0,103214000.0,108669600.0,114064700.0,119541000.0,124910000.0,130349400.0,135822100.0,141241500.0,146709900.0,152148100.0,157522000.0,162997700.0,168392900.0,173809500.0,179321700.0,183599300.0,189060800.0,194425500.0,199771000.0,205245500.0,210624200.0,216129500.0,221505600.0,226807100.0,232295600.0,237905900.0,242973500.0,248245400.0,253690700.0,259075600.0,264466200.0,272770300.0,278362600.0,284497800.0,289885800.0,295377500.0,301093900.0,306223100.0,311592400.0,316993600.0,322402400.0,328158600.0,333701500.0,339042500.0,344496800.0,349998200.0,355457100.0,356283500.0,361697500.0,367026400.0,372490100.0,378419700.0,384439000.0,390010700.0,395219900.0,400307300.0,405942400.0,411326900.0,416661700.0,422068100.0,427580800.0,432995800.0,438294100.0,447289000.0,453866300.0,459328800.0,463731400.0,468796200.0,473980500.0,479643100.0,484958400.0,490261100.0,495317600.0,500980900.0,506851700.0,512134200.0,517537200.0,523134600.0,528524700.0,530707000.0,536119100.0,541588600.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/tukey.json new file mode 100644 index 00000000..a6c18bca --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-large-loop/tera/new/tukey.json @@ -0,0 +1 @@ +[477779.2891506902,484375.3890392146,501964.9887419463,508561.0886304707] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/benchmark.json new file mode 100644 index 00000000..013f23b1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-mixed-page","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-mixed-page/askama","directory_name":"idiomatic-mixed-page/askama","title":"idiomatic-mixed-page/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/estimates.json new file mode 100644 index 00000000..42d3ba3c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2296.108813453572,"upper_bound":2304.07543776052},"point_estimate":2299.9976485722505,"standard_error":2.031859918874237},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2297.3573373106083,"upper_bound":2299.5061515712705},"point_estimate":2298.3963095072036,"standard_error":0.5631349245718448},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3.258353200316907,"upper_bound":7.930288970998341},"point_estimate":5.73075145589116,"standard_error":1.2586146372781084},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2292.0018295331893,"upper_bound":2308.5300136319593},"point_estimate":2300.013244199497,"standard_error":4.2271452773850955},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":15.84675303409643,"upper_bound":24.02052777788626},"point_estimate":20.32280971282236,"standard_error":2.0893190072955354}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/sample.json new file mode 100644 index 00000000..33b13618 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[2247.0,4494.0,6741.0,8988.0,11235.0,13482.0,15729.0,17976.0,20223.0,22470.0,24717.0,26964.0,29211.0,31458.0,33705.0,35952.0,38199.0,40446.0,42693.0,44940.0,47187.0,49434.0,51681.0,53928.0,56175.0,58422.0,60669.0,62916.0,65163.0,67410.0,69657.0,71904.0,74151.0,76398.0,78645.0,80892.0,83139.0,85386.0,87633.0,89880.0,92127.0,94374.0,96621.0,98868.0,101115.0,103362.0,105609.0,107856.0,110103.0,112350.0,114597.0,116844.0,119091.0,121338.0,123585.0,125832.0,128079.0,130326.0,132573.0,134820.0,137067.0,139314.0,141561.0,143808.0,146055.0,148302.0,150549.0,152796.0,155043.0,157290.0,159537.0,161784.0,164031.0,166278.0,168525.0,170772.0,173019.0,175266.0,177513.0,179760.0,182007.0,184254.0,186501.0,188748.0,190995.0,193242.0,195489.0,197736.0,199983.0,202230.0,204477.0,206724.0,208971.0,211218.0,213465.0,215712.0,217959.0,220206.0,222453.0,224700.0],"times":[5194300.0,10327000.0,15457600.0,20586500.0,25716400.0,30914900.0,36012300.0,41136800.0,46385300.0,51415500.0,56667200.0,61838700.0,66946800.0,72153300.0,77170000.0,82435400.0,87514300.0,92815900.0,97890200.0,103068100.0,108229200.0,113321200.0,118502000.0,124079700.0,129117400.0,134580100.0,139429900.0,144553700.0,149867800.0,154685000.0,160176700.0,165553200.0,170566100.0,175475000.0,180861300.0,185771900.0,190977000.0,195963900.0,201638500.0,206679400.0,211957500.0,217128500.0,222153100.0,227284500.0,232840400.0,237527700.0,242925600.0,248222400.0,253194000.0,258504000.0,263687000.0,268734100.0,273824900.0,278906800.0,284031400.0,289173200.0,294918500.0,299844700.0,304968200.0,310296700.0,315218100.0,320292900.0,325300400.0,330983100.0,335834600.0,340743700.0,346007900.0,351475000.0,356621600.0,361852700.0,366645900.0,371884200.0,382024300.0,391379000.0,396421200.0,401562900.0,406796000.0,412146400.0,416980100.0,422494100.0,427894900.0,433047200.0,438519400.0,433504300.0,436224900.0,442810200.0,447813300.0,455158700.0,461597300.0,465269200.0,461094300.0,470074300.0,475520100.0,480519100.0,485605000.0,490549100.0,492985900.0,497645800.0,502680700.0,507736300.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/tukey.json new file mode 100644 index 00000000..580810ee --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/base/tukey.json @@ -0,0 +1 @@ +[2269.5140267816682,2281.229816500294,2312.4719224166292,2324.187712135255] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/change/estimates.json new file mode 100644 index 00000000..fc492b0e --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.0003682649090975598,"upper_bound":0.003922270371614433},"point_estimate":0.001763078469446011,"standard_error":0.0011088550933990705},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.0010384498652412217,"upper_bound":0.0005169636381747722},"point_estimate":-0.0003165120599473159,"standard_error":0.00039191463001003035}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/benchmark.json new file mode 100644 index 00000000..013f23b1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-mixed-page","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-mixed-page/askama","directory_name":"idiomatic-mixed-page/askama","title":"idiomatic-mixed-page/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/estimates.json new file mode 100644 index 00000000..42d3ba3c --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2296.108813453572,"upper_bound":2304.07543776052},"point_estimate":2299.9976485722505,"standard_error":2.031859918874237},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2297.3573373106083,"upper_bound":2299.5061515712705},"point_estimate":2298.3963095072036,"standard_error":0.5631349245718448},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":3.258353200316907,"upper_bound":7.930288970998341},"point_estimate":5.73075145589116,"standard_error":1.2586146372781084},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":2292.0018295331893,"upper_bound":2308.5300136319593},"point_estimate":2300.013244199497,"standard_error":4.2271452773850955},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":15.84675303409643,"upper_bound":24.02052777788626},"point_estimate":20.32280971282236,"standard_error":2.0893190072955354}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/sample.json new file mode 100644 index 00000000..33b13618 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[2247.0,4494.0,6741.0,8988.0,11235.0,13482.0,15729.0,17976.0,20223.0,22470.0,24717.0,26964.0,29211.0,31458.0,33705.0,35952.0,38199.0,40446.0,42693.0,44940.0,47187.0,49434.0,51681.0,53928.0,56175.0,58422.0,60669.0,62916.0,65163.0,67410.0,69657.0,71904.0,74151.0,76398.0,78645.0,80892.0,83139.0,85386.0,87633.0,89880.0,92127.0,94374.0,96621.0,98868.0,101115.0,103362.0,105609.0,107856.0,110103.0,112350.0,114597.0,116844.0,119091.0,121338.0,123585.0,125832.0,128079.0,130326.0,132573.0,134820.0,137067.0,139314.0,141561.0,143808.0,146055.0,148302.0,150549.0,152796.0,155043.0,157290.0,159537.0,161784.0,164031.0,166278.0,168525.0,170772.0,173019.0,175266.0,177513.0,179760.0,182007.0,184254.0,186501.0,188748.0,190995.0,193242.0,195489.0,197736.0,199983.0,202230.0,204477.0,206724.0,208971.0,211218.0,213465.0,215712.0,217959.0,220206.0,222453.0,224700.0],"times":[5194300.0,10327000.0,15457600.0,20586500.0,25716400.0,30914900.0,36012300.0,41136800.0,46385300.0,51415500.0,56667200.0,61838700.0,66946800.0,72153300.0,77170000.0,82435400.0,87514300.0,92815900.0,97890200.0,103068100.0,108229200.0,113321200.0,118502000.0,124079700.0,129117400.0,134580100.0,139429900.0,144553700.0,149867800.0,154685000.0,160176700.0,165553200.0,170566100.0,175475000.0,180861300.0,185771900.0,190977000.0,195963900.0,201638500.0,206679400.0,211957500.0,217128500.0,222153100.0,227284500.0,232840400.0,237527700.0,242925600.0,248222400.0,253194000.0,258504000.0,263687000.0,268734100.0,273824900.0,278906800.0,284031400.0,289173200.0,294918500.0,299844700.0,304968200.0,310296700.0,315218100.0,320292900.0,325300400.0,330983100.0,335834600.0,340743700.0,346007900.0,351475000.0,356621600.0,361852700.0,366645900.0,371884200.0,382024300.0,391379000.0,396421200.0,401562900.0,406796000.0,412146400.0,416980100.0,422494100.0,427894900.0,433047200.0,438519400.0,433504300.0,436224900.0,442810200.0,447813300.0,455158700.0,461597300.0,465269200.0,461094300.0,470074300.0,475520100.0,480519100.0,485605000.0,490549100.0,492985900.0,497645800.0,502680700.0,507736300.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/tukey.json new file mode 100644 index 00000000..580810ee --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/askama/new/tukey.json @@ -0,0 +1 @@ +[2269.5140267816682,2281.229816500294,2312.4719224166292,2324.187712135255] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/benchmark.json new file mode 100644 index 00000000..aa41bb57 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-mixed-page","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-mixed-page/tera","directory_name":"idiomatic-mixed-page/tera","title":"idiomatic-mixed-page/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/estimates.json new file mode 100644 index 00000000..af0f441f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":22632.92577857962,"upper_bound":22658.557975264066},"point_estimate":22646.019027752947,"standard_error":6.545756256816075},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":22662.174776010885,"upper_bound":22679.739671760046},"point_estimate":22673.43271878825,"standard_error":5.424962911218037},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":22.608545796645167,"upper_bound":58.669288034967764},"point_estimate":41.792507692583904,"standard_error":9.321148605660667},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":22611.77724815979,"upper_bound":22642.565567359034},"point_estimate":22627.65817214086,"standard_error":7.868785340583375},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":57.24479887796216,"upper_bound":72.55891881342204},"point_estimate":65.65239129405171,"standard_error":3.889818853940489}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/sample.json new file mode 100644 index 00000000..c7351b01 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[228.0,456.0,684.0,912.0,1140.0,1368.0,1596.0,1824.0,2052.0,2280.0,2508.0,2736.0,2964.0,3192.0,3420.0,3648.0,3876.0,4104.0,4332.0,4560.0,4788.0,5016.0,5244.0,5472.0,5700.0,5928.0,6156.0,6384.0,6612.0,6840.0,7068.0,7296.0,7524.0,7752.0,7980.0,8208.0,8436.0,8664.0,8892.0,9120.0,9348.0,9576.0,9804.0,10032.0,10260.0,10488.0,10716.0,10944.0,11172.0,11400.0,11628.0,11856.0,12084.0,12312.0,12540.0,12768.0,12996.0,13224.0,13452.0,13680.0,13908.0,14136.0,14364.0,14592.0,14820.0,15048.0,15276.0,15504.0,15732.0,15960.0,16188.0,16416.0,16644.0,16872.0,17100.0,17328.0,17556.0,17784.0,18012.0,18240.0,18468.0,18696.0,18924.0,19152.0,19380.0,19608.0,19836.0,20064.0,20292.0,20520.0,20748.0,20976.0,21204.0,21432.0,21660.0,21888.0,22116.0,22344.0,22572.0,22800.0],"times":[5200000.0,10359800.0,15556000.0,20728300.0,25888200.0,31067600.0,36248000.0,41380100.0,46600100.0,51735000.0,56889000.0,62068800.0,67211100.0,72417600.0,77674200.0,82881900.0,88008900.0,93117700.0,98232200.0,103443100.0,108629600.0,113834400.0,118922600.0,124072700.0,129335500.0,134563600.0,139812300.0,144793900.0,149963500.0,154958100.0,160300400.0,165427400.0,170512100.0,175798600.0,181177100.0,186241100.0,191672700.0,196713000.0,201721400.0,206441300.0,210612300.0,215874700.0,221076100.0,226091200.0,231372800.0,236458500.0,241555300.0,246903100.0,252024000.0,258428600.0,263549800.0,268936700.0,274079600.0,279270500.0,284310800.0,289392900.0,294546100.0,299541200.0,304669300.0,310038400.0,315225300.0,319883000.0,325122500.0,330367600.0,335541000.0,338721000.0,343998500.0,349269000.0,354472600.0,359687900.0,364729000.0,369778600.0,374892300.0,380506400.0,385561000.0,390777100.0,395748600.0,400901700.0,406524200.0,412214500.0,416937500.0,423236800.0,428297800.0,433664200.0,439170900.0,444575200.0,449439700.0,454716700.0,460114800.0,465541500.0,470681100.0,475951200.0,481064100.0,486445000.0,491488000.0,496640600.0,501579300.0,506733100.0,510047500.0,515079900.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/tukey.json new file mode 100644 index 00000000..0ce0c8fb --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/base/tukey.json @@ -0,0 +1 @@ +[22315.763015493274,22455.460372047542,22827.986656192254,22967.68401274652] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/change/estimates.json new file mode 100644 index 00000000..1dcdf710 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.012837292449144,"upper_bound":0.014759216444304191},"point_estimate":0.013802427840948761,"standard_error":0.0004890444055035239},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.014220584728451113,"upper_bound":0.016729504358134584},"point_estimate":0.015237560847974452,"standard_error":0.0007709012974941107}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/benchmark.json new file mode 100644 index 00000000..aa41bb57 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-mixed-page","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-mixed-page/tera","directory_name":"idiomatic-mixed-page/tera","title":"idiomatic-mixed-page/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/estimates.json new file mode 100644 index 00000000..af0f441f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":22632.92577857962,"upper_bound":22658.557975264066},"point_estimate":22646.019027752947,"standard_error":6.545756256816075},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":22662.174776010885,"upper_bound":22679.739671760046},"point_estimate":22673.43271878825,"standard_error":5.424962911218037},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":22.608545796645167,"upper_bound":58.669288034967764},"point_estimate":41.792507692583904,"standard_error":9.321148605660667},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":22611.77724815979,"upper_bound":22642.565567359034},"point_estimate":22627.65817214086,"standard_error":7.868785340583375},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":57.24479887796216,"upper_bound":72.55891881342204},"point_estimate":65.65239129405171,"standard_error":3.889818853940489}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/sample.json new file mode 100644 index 00000000..c7351b01 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[228.0,456.0,684.0,912.0,1140.0,1368.0,1596.0,1824.0,2052.0,2280.0,2508.0,2736.0,2964.0,3192.0,3420.0,3648.0,3876.0,4104.0,4332.0,4560.0,4788.0,5016.0,5244.0,5472.0,5700.0,5928.0,6156.0,6384.0,6612.0,6840.0,7068.0,7296.0,7524.0,7752.0,7980.0,8208.0,8436.0,8664.0,8892.0,9120.0,9348.0,9576.0,9804.0,10032.0,10260.0,10488.0,10716.0,10944.0,11172.0,11400.0,11628.0,11856.0,12084.0,12312.0,12540.0,12768.0,12996.0,13224.0,13452.0,13680.0,13908.0,14136.0,14364.0,14592.0,14820.0,15048.0,15276.0,15504.0,15732.0,15960.0,16188.0,16416.0,16644.0,16872.0,17100.0,17328.0,17556.0,17784.0,18012.0,18240.0,18468.0,18696.0,18924.0,19152.0,19380.0,19608.0,19836.0,20064.0,20292.0,20520.0,20748.0,20976.0,21204.0,21432.0,21660.0,21888.0,22116.0,22344.0,22572.0,22800.0],"times":[5200000.0,10359800.0,15556000.0,20728300.0,25888200.0,31067600.0,36248000.0,41380100.0,46600100.0,51735000.0,56889000.0,62068800.0,67211100.0,72417600.0,77674200.0,82881900.0,88008900.0,93117700.0,98232200.0,103443100.0,108629600.0,113834400.0,118922600.0,124072700.0,129335500.0,134563600.0,139812300.0,144793900.0,149963500.0,154958100.0,160300400.0,165427400.0,170512100.0,175798600.0,181177100.0,186241100.0,191672700.0,196713000.0,201721400.0,206441300.0,210612300.0,215874700.0,221076100.0,226091200.0,231372800.0,236458500.0,241555300.0,246903100.0,252024000.0,258428600.0,263549800.0,268936700.0,274079600.0,279270500.0,284310800.0,289392900.0,294546100.0,299541200.0,304669300.0,310038400.0,315225300.0,319883000.0,325122500.0,330367600.0,335541000.0,338721000.0,343998500.0,349269000.0,354472600.0,359687900.0,364729000.0,369778600.0,374892300.0,380506400.0,385561000.0,390777100.0,395748600.0,400901700.0,406524200.0,412214500.0,416937500.0,423236800.0,428297800.0,433664200.0,439170900.0,444575200.0,449439700.0,454716700.0,460114800.0,465541500.0,470681100.0,475951200.0,481064100.0,486445000.0,491488000.0,496640600.0,501579300.0,506733100.0,510047500.0,515079900.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/tukey.json new file mode 100644 index 00000000..0ce0c8fb --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-mixed-page/tera/new/tukey.json @@ -0,0 +1 @@ +[22315.763015493274,22455.460372047542,22827.986656192254,22967.68401274652] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/benchmark.json new file mode 100644 index 00000000..475d3c24 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-trivial-substitution","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-trivial-substitution/askama","directory_name":"idiomatic-trivial-substitution/askama","title":"idiomatic-trivial-substitution/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/estimates.json new file mode 100644 index 00000000..c3568215 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":130.22360581082765,"upper_bound":130.65428561709155},"point_estimate":130.41656830842845,"standard_error":0.11052908356303433},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":130.14104959884844,"upper_bound":130.381919945346},"point_estimate":130.24573707315477,"standard_error":0.05702424097928324},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.44422226093309203,"upper_bound":0.817118859401034},"point_estimate":0.5908210419822831,"standard_error":0.10050733063082778},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":130.15695953569002,"upper_bound":130.4345947380103},"point_estimate":130.29444053269833,"standard_error":0.07119336226310044},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.5792843053588964,"upper_bound":1.6381937642901552},"point_estimate":1.1063827258408407,"standard_error":0.29673567703815346}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/sample.json new file mode 100644 index 00000000..16e92fb8 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[39684.0,79368.0,119052.0,158736.0,198420.0,238104.0,277788.0,317472.0,357156.0,396840.0,436524.0,476208.0,515892.0,555576.0,595260.0,634944.0,674628.0,714312.0,753996.0,793680.0,833364.0,873048.0,912732.0,952416.0,992100.0,1031784.0,1071468.0,1111152.0,1150836.0,1190520.0,1230204.0,1269888.0,1309572.0,1349256.0,1388940.0,1428624.0,1468308.0,1507992.0,1547676.0,1587360.0,1627044.0,1666728.0,1706412.0,1746096.0,1785780.0,1825464.0,1865148.0,1904832.0,1944516.0,1984200.0,2023884.0,2063568.0,2103252.0,2142936.0,2182620.0,2222304.0,2261988.0,2301672.0,2341356.0,2381040.0,2420724.0,2460408.0,2500092.0,2539776.0,2579460.0,2619144.0,2658828.0,2698512.0,2738196.0,2777880.0,2817564.0,2857248.0,2896932.0,2936616.0,2976300.0,3015984.0,3055668.0,3095352.0,3135036.0,3174720.0,3214404.0,3254088.0,3293772.0,3333456.0,3373140.0,3412824.0,3452508.0,3492192.0,3531876.0,3571560.0,3611244.0,3650928.0,3690612.0,3730296.0,3769980.0,3809664.0,3849348.0,3889032.0,3928716.0,3968400.0],"times":[5169100.0,10485400.0,16001100.0,21978200.0,26323900.0,31218700.0,36236800.0,41495900.0,46802100.0,51900300.0,57437300.0,62404400.0,67542800.0,72737800.0,78186100.0,83028500.0,88465700.0,92590700.0,97707100.0,102713300.0,107801200.0,112991700.0,118292900.0,123053800.0,128597300.0,133513600.0,138875600.0,143929800.0,149199800.0,154087100.0,159195400.0,164228900.0,169421300.0,175435100.0,180878000.0,186505100.0,191136200.0,195852900.0,202134500.0,207000300.0,212774100.0,216475700.0,222250500.0,227181800.0,233067700.0,237592400.0,242429800.0,250356500.0,252567200.0,258488600.0,264571200.0,268930800.0,273325500.0,279433500.0,285383200.0,290166000.0,294534400.0,298939100.0,304539800.0,309794800.0,314889200.0,319400500.0,324791900.0,330188300.0,335335200.0,341464200.0,346609800.0,352017300.0,358505200.0,362514800.0,367684200.0,372248200.0,379915200.0,382856700.0,390089900.0,392599900.0,397789200.0,402961000.0,408355200.0,413315900.0,420606500.0,422845400.0,428134900.0,434173100.0,436676500.0,442559700.0,449574000.0,453327300.0,458827400.0,465700700.0,470376800.0,477880700.0,484759800.0,487297300.0,488075900.0,494629000.0,499310900.0,507414600.0,515493900.0,520737100.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/tukey.json new file mode 100644 index 00000000..d954215f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/base/tukey.json @@ -0,0 +1 @@ +[127.32649176883888,128.60337419114603,132.0083939839651,133.28527640627226] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/change/estimates.json new file mode 100644 index 00000000..a11624b0 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.012329623112254976,"upper_bound":-0.007932027826482807},"point_estimate":-0.010163290566236993,"standard_error":0.0011194150708356129},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":-0.01276714247241284,"upper_bound":-0.009160120577390463},"point_estimate":-0.010688982039960937,"standard_error":0.0008973648253928413}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/benchmark.json new file mode 100644 index 00000000..475d3c24 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-trivial-substitution","function_id":"askama","value_str":null,"throughput":null,"full_id":"idiomatic-trivial-substitution/askama","directory_name":"idiomatic-trivial-substitution/askama","title":"idiomatic-trivial-substitution/askama"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/estimates.json new file mode 100644 index 00000000..c3568215 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":130.22360581082765,"upper_bound":130.65428561709155},"point_estimate":130.41656830842845,"standard_error":0.11052908356303433},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":130.14104959884844,"upper_bound":130.381919945346},"point_estimate":130.24573707315477,"standard_error":0.05702424097928324},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.44422226093309203,"upper_bound":0.817118859401034},"point_estimate":0.5908210419822831,"standard_error":0.10050733063082778},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":130.15695953569002,"upper_bound":130.4345947380103},"point_estimate":130.29444053269833,"standard_error":0.07119336226310044},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.5792843053588964,"upper_bound":1.6381937642901552},"point_estimate":1.1063827258408407,"standard_error":0.29673567703815346}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/sample.json new file mode 100644 index 00000000..16e92fb8 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[39684.0,79368.0,119052.0,158736.0,198420.0,238104.0,277788.0,317472.0,357156.0,396840.0,436524.0,476208.0,515892.0,555576.0,595260.0,634944.0,674628.0,714312.0,753996.0,793680.0,833364.0,873048.0,912732.0,952416.0,992100.0,1031784.0,1071468.0,1111152.0,1150836.0,1190520.0,1230204.0,1269888.0,1309572.0,1349256.0,1388940.0,1428624.0,1468308.0,1507992.0,1547676.0,1587360.0,1627044.0,1666728.0,1706412.0,1746096.0,1785780.0,1825464.0,1865148.0,1904832.0,1944516.0,1984200.0,2023884.0,2063568.0,2103252.0,2142936.0,2182620.0,2222304.0,2261988.0,2301672.0,2341356.0,2381040.0,2420724.0,2460408.0,2500092.0,2539776.0,2579460.0,2619144.0,2658828.0,2698512.0,2738196.0,2777880.0,2817564.0,2857248.0,2896932.0,2936616.0,2976300.0,3015984.0,3055668.0,3095352.0,3135036.0,3174720.0,3214404.0,3254088.0,3293772.0,3333456.0,3373140.0,3412824.0,3452508.0,3492192.0,3531876.0,3571560.0,3611244.0,3650928.0,3690612.0,3730296.0,3769980.0,3809664.0,3849348.0,3889032.0,3928716.0,3968400.0],"times":[5169100.0,10485400.0,16001100.0,21978200.0,26323900.0,31218700.0,36236800.0,41495900.0,46802100.0,51900300.0,57437300.0,62404400.0,67542800.0,72737800.0,78186100.0,83028500.0,88465700.0,92590700.0,97707100.0,102713300.0,107801200.0,112991700.0,118292900.0,123053800.0,128597300.0,133513600.0,138875600.0,143929800.0,149199800.0,154087100.0,159195400.0,164228900.0,169421300.0,175435100.0,180878000.0,186505100.0,191136200.0,195852900.0,202134500.0,207000300.0,212774100.0,216475700.0,222250500.0,227181800.0,233067700.0,237592400.0,242429800.0,250356500.0,252567200.0,258488600.0,264571200.0,268930800.0,273325500.0,279433500.0,285383200.0,290166000.0,294534400.0,298939100.0,304539800.0,309794800.0,314889200.0,319400500.0,324791900.0,330188300.0,335335200.0,341464200.0,346609800.0,352017300.0,358505200.0,362514800.0,367684200.0,372248200.0,379915200.0,382856700.0,390089900.0,392599900.0,397789200.0,402961000.0,408355200.0,413315900.0,420606500.0,422845400.0,428134900.0,434173100.0,436676500.0,442559700.0,449574000.0,453327300.0,458827400.0,465700700.0,470376800.0,477880700.0,484759800.0,487297300.0,488075900.0,494629000.0,499310900.0,507414600.0,515493900.0,520737100.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/tukey.json new file mode 100644 index 00000000..d954215f --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/askama/new/tukey.json @@ -0,0 +1 @@ +[127.32649176883888,128.60337419114603,132.0083939839651,133.28527640627226] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/benchmark.json new file mode 100644 index 00000000..77dd57b1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-trivial-substitution","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-trivial-substitution/tera","directory_name":"idiomatic-trivial-substitution/tera","title":"idiomatic-trivial-substitution/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/estimates.json new file mode 100644 index 00000000..20d98889 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":802.7082877881559,"upper_bound":805.6368620420466},"point_estimate":804.1453552654046,"standard_error":0.7491472550435174},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":800.135252947455,"upper_bound":801.3948567096219},"point_estimate":801.1730300043625,"standard_error":0.5601408565124217},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4.977692020054466,"upper_bound":7.458377468238189},"point_estimate":6.8384726744031115,"standard_error":0.8260875100750161},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":808.436481498925,"upper_bound":811.1215581540708},"point_estimate":809.882387607029,"standard_error":0.6858272888716384},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":6.896830024093468,"upper_bound":8.006869609197341},"point_estimate":7.554544515401678,"standard_error":0.28455324601120763}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/sample.json new file mode 100644 index 00000000..6300e450 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[6294.0,12588.0,18882.0,25176.0,31470.0,37764.0,44058.0,50352.0,56646.0,62940.0,69234.0,75528.0,81822.0,88116.0,94410.0,100704.0,106998.0,113292.0,119586.0,125880.0,132174.0,138468.0,144762.0,151056.0,157350.0,163644.0,169938.0,176232.0,182526.0,188820.0,195114.0,201408.0,207702.0,213996.0,220290.0,226584.0,232878.0,239172.0,245466.0,251760.0,258054.0,264348.0,270642.0,276936.0,283230.0,289524.0,295818.0,302112.0,308406.0,314700.0,320994.0,327288.0,333582.0,339876.0,346170.0,352464.0,358758.0,365052.0,371346.0,377640.0,383934.0,390228.0,396522.0,402816.0,409110.0,415404.0,421698.0,427992.0,434286.0,440580.0,446874.0,453168.0,459462.0,465756.0,472050.0,478344.0,484638.0,490932.0,497226.0,503520.0,509814.0,516108.0,522402.0,528696.0,534990.0,541284.0,547578.0,553872.0,560166.0,566460.0,572754.0,579048.0,585342.0,591636.0,597930.0,604224.0,610518.0,616812.0,623106.0,629400.0],"times":[5028300.0,10026800.0,15038400.0,20055400.0,25092900.0,30071900.0,35120100.0,40131000.0,45155300.0,50169600.0,55207700.0,60200100.0,65222600.0,70246500.0,75243400.0,80295400.0,85343800.0,90249000.0,95256000.0,100291200.0,105275900.0,110271000.0,115313500.0,120272300.0,125285900.0,130297300.0,135327900.0,140358200.0,145377800.0,150354600.0,155396600.0,160441200.0,165436800.0,171204100.0,176241400.0,181308100.0,186302400.0,191330500.0,196406000.0,201363000.0,206431100.0,211539600.0,216527300.0,221619200.0,226697300.0,231757800.0,236817800.0,241797800.0,246845300.0,252207100.0,257224400.0,262285100.0,267327100.0,272309300.0,277422800.0,282457300.0,287442600.0,292465000.0,297517300.0,302606400.0,307651300.0,312648600.0,318690100.0,326168100.0,331187300.0,337857800.0,343463200.0,348710900.0,353936800.0,358980400.0,364168100.0,369438200.0,374644500.0,379673000.0,384729800.0,389859800.0,395097600.0,400296300.0,405415300.0,410674800.0,415688100.0,420440300.0,425600300.0,430713400.0,435660100.0,440834500.0,446024300.0,451174900.0,456313200.0,461506800.0,466640200.0,471768700.0,476859800.0,481903100.0,484469400.0,486010000.0,490881000.0,499355600.0,504447500.0,509660500.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/tukey.json new file mode 100644 index 00000000..11f2d80a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/base/tukey.json @@ -0,0 +1 @@ +[745.0605374392765,771.0962542911052,840.5248325626485,866.5605494144772] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/change/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/change/estimates.json new file mode 100644 index 00000000..295b1756 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/change/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.010878191950375222,"upper_bound":0.015275405927101292},"point_estimate":0.013090448195695936,"standard_error":0.001128437714842322},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":0.0095063989584596,"upper_bound":0.011737506581831036},"point_estimate":0.011038274737427134,"standard_error":0.0006481436639480676}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/benchmark.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/benchmark.json new file mode 100644 index 00000000..77dd57b1 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/benchmark.json @@ -0,0 +1 @@ +{"group_id":"idiomatic-trivial-substitution","function_id":"tera","value_str":null,"throughput":null,"full_id":"idiomatic-trivial-substitution/tera","directory_name":"idiomatic-trivial-substitution/tera","title":"idiomatic-trivial-substitution/tera"} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/estimates.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/estimates.json new file mode 100644 index 00000000..20d98889 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/estimates.json @@ -0,0 +1 @@ +{"mean":{"confidence_interval":{"confidence_level":0.95,"lower_bound":802.7082877881559,"upper_bound":805.6368620420466},"point_estimate":804.1453552654046,"standard_error":0.7491472550435174},"median":{"confidence_interval":{"confidence_level":0.95,"lower_bound":800.135252947455,"upper_bound":801.3948567096219},"point_estimate":801.1730300043625,"standard_error":0.5601408565124217},"median_abs_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":4.977692020054466,"upper_bound":7.458377468238189},"point_estimate":6.8384726744031115,"standard_error":0.8260875100750161},"slope":{"confidence_interval":{"confidence_level":0.95,"lower_bound":808.436481498925,"upper_bound":811.1215581540708},"point_estimate":809.882387607029,"standard_error":0.6858272888716384},"std_dev":{"confidence_interval":{"confidence_level":0.95,"lower_bound":6.896830024093468,"upper_bound":8.006869609197341},"point_estimate":7.554544515401678,"standard_error":0.28455324601120763}} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/sample.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/sample.json new file mode 100644 index 00000000..6300e450 --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/sample.json @@ -0,0 +1 @@ +{"sampling_mode":"Linear","iters":[6294.0,12588.0,18882.0,25176.0,31470.0,37764.0,44058.0,50352.0,56646.0,62940.0,69234.0,75528.0,81822.0,88116.0,94410.0,100704.0,106998.0,113292.0,119586.0,125880.0,132174.0,138468.0,144762.0,151056.0,157350.0,163644.0,169938.0,176232.0,182526.0,188820.0,195114.0,201408.0,207702.0,213996.0,220290.0,226584.0,232878.0,239172.0,245466.0,251760.0,258054.0,264348.0,270642.0,276936.0,283230.0,289524.0,295818.0,302112.0,308406.0,314700.0,320994.0,327288.0,333582.0,339876.0,346170.0,352464.0,358758.0,365052.0,371346.0,377640.0,383934.0,390228.0,396522.0,402816.0,409110.0,415404.0,421698.0,427992.0,434286.0,440580.0,446874.0,453168.0,459462.0,465756.0,472050.0,478344.0,484638.0,490932.0,497226.0,503520.0,509814.0,516108.0,522402.0,528696.0,534990.0,541284.0,547578.0,553872.0,560166.0,566460.0,572754.0,579048.0,585342.0,591636.0,597930.0,604224.0,610518.0,616812.0,623106.0,629400.0],"times":[5028300.0,10026800.0,15038400.0,20055400.0,25092900.0,30071900.0,35120100.0,40131000.0,45155300.0,50169600.0,55207700.0,60200100.0,65222600.0,70246500.0,75243400.0,80295400.0,85343800.0,90249000.0,95256000.0,100291200.0,105275900.0,110271000.0,115313500.0,120272300.0,125285900.0,130297300.0,135327900.0,140358200.0,145377800.0,150354600.0,155396600.0,160441200.0,165436800.0,171204100.0,176241400.0,181308100.0,186302400.0,191330500.0,196406000.0,201363000.0,206431100.0,211539600.0,216527300.0,221619200.0,226697300.0,231757800.0,236817800.0,241797800.0,246845300.0,252207100.0,257224400.0,262285100.0,267327100.0,272309300.0,277422800.0,282457300.0,287442600.0,292465000.0,297517300.0,302606400.0,307651300.0,312648600.0,318690100.0,326168100.0,331187300.0,337857800.0,343463200.0,348710900.0,353936800.0,358980400.0,364168100.0,369438200.0,374644500.0,379673000.0,384729800.0,389859800.0,395097600.0,400296300.0,405415300.0,410674800.0,415688100.0,420440300.0,425600300.0,430713400.0,435660100.0,440834500.0,446024300.0,451174900.0,456313200.0,461506800.0,466640200.0,471768700.0,476859800.0,481903100.0,484469400.0,486010000.0,490881000.0,499355600.0,504447500.0,509660500.0]} \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/tukey.json b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/tukey.json new file mode 100644 index 00000000..11f2d80a --- /dev/null +++ b/docs/benchmarks/2026-08-08/rust/criterion/idiomatic-trivial-substitution/tera/new/tukey.json @@ -0,0 +1 @@ +[745.0605374392765,771.0962542911052,840.5248325626485,866.5605494144772] \ No newline at end of file diff --git a/docs/benchmarks/2026-08-08/summary-tables.md b/docs/benchmarks/2026-08-08/summary-tables.md new file mode 100644 index 00000000..2bf02ee8 --- /dev/null +++ b/docs/benchmarks/2026-08-08/summary-tables.md @@ -0,0 +1,46 @@ +. --> + +### Tier 1 — realistic sizing — .NET field + +Outputs that fit the size of a real page, partial or fragment, and stay clear of the 85,000-byte Large Object Heap threshold once materialised as UTF-16. **These are the primary results.** + +| Workload | Golden | Heddle | Next .NET engine | Margin | +| --- | ---: | ---: | --- | ---: | +| trivial-substitution | 338 B | 149 ns | Handlebars.Net 2.1.6 — 385.8 ns | **2.59×** | +| fortunes-encoded | 1,156 B | 739.1 ns | Handlebars.Net 2.1.6 — 1.66 μs | **2.25×** | +| fragment-heavy | 4,730 B | 3.081 μs | Fluid.Core 2.31.0 — 11.22 μs | **3.64×** | +| mixed-page | 9,712 B | 2.636 μs | Handlebars.Net 2.1.6 — 7.247 μs | **2.75×** | +| conditional-heavy | 15,549 B | 15.02 μs | Handlebars.Net 2.1.6 — 34.51 μs | **2.30×** | + +### Tier 1 — realistic sizing — cross-stack rank + +| Workload | Golden | Heddle rank | Ahead of it | +| --- | ---: | ---: | --- | +| trivial-substitution | 338 B | **#3** of 16 | Askama 0.16.0 (Rust), eta 4.6.0 (JS) | +| fortunes-encoded | 1,156 B | **#2** of 16 | Askama 0.16.0 (Rust) | +| fragment-heavy | 4,730 B | **#3** of 16 | Askama 0.16.0 (Rust), JTE 3.2.4 (JVM) | +| mixed-page | 9,712 B | **#2** of 16 | Askama 0.16.0 (Rust) | +| conditional-heavy | 15,549 B | **#4** of 16 | Askama 0.16.0 (Rust), JTE 3.2.4 (JVM), eta 4.6.0 (JS) | + +### Tier 2 — edge-case sizing — .NET field + +Outputs that exceed the 85,000-byte Large Object Heap threshold as UTF-16, so every .NET render allocates on the LOH and drives a full Gen2 collection — a cost structural to the runtime and absent in the other five ecosystems. These are stress tests, not page renders; read them with that caveat attached. + +| Workload | Golden | Heddle | Next .NET engine | Margin | +| --- | ---: | ---: | --- | ---: | +| composed-page | 34,847 B | 34.07 μs | Fluid.Core 2.31.0 — 60.23 μs | **1.77×** | +| large-loop | 192,780 B | 492.1 μs | Handlebars.Net 2.1.6 — 742.2 μs | **1.51×** | +| encoded-loop | 831,685 B | 1.766 ms | Handlebars.Net 2.1.6 — 1.72 ms | **0.97× — Heddle loses** | + +### Tier 2 — edge-case sizing — cross-stack rank + +| Workload | Golden | Heddle rank | Ahead of it | +| --- | ---: | ---: | --- | +| composed-page | 34,847 B | **#11** of 16 | Askama 0.16.0 (Rust), Tera 2.0.0 (Rust), templ v0.3.1020 (Go), eta 4.6.0 (JS), handlebars 4.7.9 (JS), text/template (go1.26) (Go), JTE 3.2.4 (JVM), Mako 1.3.12 (Python), Jinja2 3.1.6 (Python), Thymeleaf 3.1.5 (JVM) | +| large-loop | 192,780 B | **#6** of 16 | Askama 0.16.0 (Rust), JTE 3.2.4 (JVM), eta 4.6.0 (JS), Tera 2.0.0 (Rust), handlebars 4.7.9 (JS) | +| encoded-loop | 831,685 B | **#7** of 16 | Askama 0.16.0 (Rust), templ v0.3.1020 (Go), JTE 3.2.4 (JVM), Tera 2.0.0 (Rust), Handlebars.Net 2.1.6 (.NET), Razor (ASP.NET Core MVC) (.NET) | + +*Source: docs/benchmarks/2026-08-08, controlled track. Tier is derived from rendered output size against the 85,000-byte Large Object Heap threshold; see [Sizing regimes](consolidated-tables.md#sizing-regimes).* diff --git a/docs/benchmarks/2026-08-08/summary.txt b/docs/benchmarks/2026-08-08/summary.txt new file mode 100644 index 00000000..94b36f78 --- /dev/null +++ b/docs/benchmarks/2026-08-08/summary.txt @@ -0,0 +1,54 @@ +mode: MEASUREMENT (spec protocol shapes) +budget: short (E6 measurement budget) +ecosystems: dotnet, rust, jvm, js, python, go +finished: 2026-08-08 04:45:52 + + +Ecosystem Phase Step ExitCode Seconds Status +--------- ----- ---- -------- ------- ------ +dotnet gate gate 0 19.1 OK +dotnet gate gate-selftest 0 3.4 OK +dotnet gate gate-verify-corpus 0 2.8 OK +rust gate gate 0 2.6 OK +jvm gate gate-build-verify 0 4.8 OK +js gate npm-ci 0 0.6 OK +js gate selftest 0 0.3 OK +js gate gate 0 0.6 OK +python gate venv-create 0 7.3 OK +python gate pip-install 0 4.4 OK +python gate selftest 0 0.3 OK +python gate gate-all 0 0.4 OK +go gate gate 0 1 OK +dotnet measure suite-ComposedPageBenchmarks 0 475.6 OK +dotnet measure suite-TrivialSubstitutionBenchmarks 0 509 OK +dotnet measure suite-LargeLoopBenchmarks 0 624.8 OK +dotnet measure suite-MixedPageBenchmarks 0 558.2 OK +dotnet measure suite-ConditionalHeavyBenchmarks 0 588.2 OK +dotnet measure suite-FragmentHeavyBenchmarks 0 493.8 OK +dotnet measure suite-FortunesEncodedBenchmarks 0 610.9 OK +dotnet measure suite-EncodedLoopBenchmarks 0 663.3 OK +dotnet measure bench-techniques 0 885.3 OK +dotnet measure bench-cold 0 139.3 OK +dotnet measure bench-internal 0 239.2 OK +dotnet copy copy-bdn-artifacts 0 0 OK +rust measure criterion-bench 0 1109.4 OK +rust measure alloc-report 0 0.3 OK +rust measure summarize 0 0.7 OK +rust copy copy-criterion 0 0 OK +jvm measure jmh-full 0 1191 OK +js measure bench-controlled-x38 0 588.5 OK +js measure bench-idiomatic-x38 0 587.6 OK +js measure bench-cold-compile 0 15.8 OK +js copy copy-artifacts 0 0 OK +python measure bench_jinja2_controlled 0 216.7 OK +python measure bench_jinja2_idiomatic 0 219.9 OK +python measure bench_mako_controlled 0 221.3 OK +python measure bench_mako_idiomatic 0 222.6 OK +python measure bench_cold_compile 0 115.3 OK +python measure mem-tracemalloc 0 24.5 OK +go measure run-benchmarks 0 1151.3 OK +go copy copy-results 0 0 OK +report measure consolidate 0 0.5 OK + + + diff --git a/docs/benchmarks/2026-08-08/toolchain.json b/docs/benchmarks/2026-08-08/toolchain.json new file mode 100644 index 00000000..9a833b55 --- /dev/null +++ b/docs/benchmarks/2026-08-08/toolchain.json @@ -0,0 +1,37 @@ +{ + ".NET SDK": { + "pin": "(protocol records the observed line)", + "actual": "10.0.302", + "drift": false + }, + "Rust": { + "pin": "1.97.1", + "actual": "rustc 1.97.1 (8bab26f4f 2026-07-14)", + "drift": false + }, + "JDK": { + "pin": "Temurin 25", + "actual": "java version \"25.0.4\" 2026-07-21 LTS", + "drift": false + }, + "Node.js": { + "pin": "v24.x", + "actual": "v24.19.0", + "drift": false + }, + "CPython": { + "pin": "3.14.x", + "actual": "Python 3.14.7", + "drift": false + }, + "Go": { + "pin": "go1.26.x", + "actual": "go version go1.26.5 windows/amd64", + "drift": false + }, + "templ": { + "pin": "v0.3.1020", + "actual": "v0.3.1020", + "drift": false + } +} \ No newline at end of file diff --git a/docs/building.md b/docs/building.md index 5d71dab7..f543c929 100644 --- a/docs/building.md +++ b/docs/building.md @@ -22,48 +22,52 @@ From the repository root (the commands pick up [Heddle.sln](../Heddle.sln)): ```bash dotnet restore dotnet build -c Release -dotnet test # runs all test projects, as CI does +dotnet test # runs all test projects ``` ## Target frameworks | Project | Targets | | --- | --- | -| `Heddle` ([csproj](../src/Heddle/Heddle.csproj)) | `netstandard2.0; net6.0; net8.0; net10.0` | -| `Heddle.Language` ([csproj](../src/Heddle.Language/Heddle.Language.csproj)) | `netstandard2.0; net6.0; net8.0; net10.0` | -| `Heddle.Tests` | `net48` (Windows only); `net6.0; net8.0; net10.0` | +| `Heddle` ([csproj](../src/Heddle/Heddle.csproj)) | `netstandard2.0; net8.0; net10.0` | +| `Heddle.Language` ([csproj](../src/Heddle.Language/Heddle.Language.csproj)) | `netstandard2.0; net8.0; net10.0` | +| `Heddle.Tests` | `net48` (Windows only); `net8.0; net10.0` | All shipping projects use `LangVersion=latest` and are **strong‑name signed** with `heddle.snk` (`SignAssembly=true`, `AssemblyOriginatorKeyFile=..\..\heddle.snk`). -The current release line is **2.0.0**; the published version is set from the release tag +The current release line is **2.1.0**; the published version is set from the release tag (`vX.Y.Z`) at publish time, so the version in the source tree is just a placeholder. ### Key dependencies - `Antlr4.Runtime.Standard` 4.13.1 — runtime for the generated parser. - `Microsoft.CodeAnalysis.CSharp` (Roslyn) — compiles embedded C# expressions; the version is - pinned per target framework (4.1.0 on netstandard2.0, 4.9.2 on net6.0, 4.11.0 on net8.0, - 5.3.0 on net10.0). -- `Microsoft.Extensions.DependencyModel` / `Microsoft.Extensions.FileProviders.Embedded` — - assembly discovery and embedded resources. + pinned per target framework (4.1.0 on netstandard2.0, 4.11.0 on net8.0, 5.3.0 on net10.0). +- `Microsoft.Extensions.FileProviders.Embedded` — embedded resources (the C#‑tier class + template). ## Testing -Tests use **xUnit**. The core engine suite lives in [src/Heddle.Tests](../src/Heddle.Tests) — its +Tests use **xUnit v3** on Microsoft.Testing.Platform — each suite builds as a self‑contained +test executable, and `dotnet test` drives them per project or per solution. The core engine +suite lives in [src/Heddle.Tests](../src/Heddle.Tests) — its key file is [HeddleTemplateTests.cs](../src/Heddle.Tests/HeddleTemplateTests.cs), with other suites covering the compiler, reflection helpers, and string builders. Four more test projects cover the rest of the toolchain: `Heddle.Generator.Tests` and `Heddle.Generator.IntegrationTests` (the source generator), `Heddle.Tool.Tests` (the `heddle` CLI), and `Heddle.LanguageServices.Tests` (the editor language services). -Run the whole solution — this is what CI does -([dotnet.yml](../.github/workflows/dotnet.yml) runs `dotnet test -c Debug --no-restore`): +Run the whole solution: ```bash dotnet test ``` -Or scope to a single project, e.g. `dotnet test src/Heddle.Tests`. +Or scope to a single project, e.g. `dotnet test src/Heddle.Tests`. CI +([dotnet.yml](../.github/workflows/dotnet.yml)) runs each suite as its own step through a +guarded wrapper that fails the run unless the suite's expected number of tests actually +executed — a whole‑solution run would report one aggregate count, which would let a single +suite going quiet pass unnoticed. Many tests are **golden‑file** comparisons: a `.heddle` template under [TestTemplate/](../src/Heddle.Tests/TestTemplate) is rendered and compared against an @@ -74,38 +78,57 @@ authoritative examples used throughout this documentation. ## Performance benchmarks -[src/Heddle.Performance](../src/Heddle.Performance) contains a **BenchmarkDotNet** suite -that compares Heddle against four other .NET template engines (Fluid, Scriban, DotLiquid, -Handlebars.Net) on byte‑identical parity‑checked output, plus ASP.NET Core **Razor** on a -comparable — but larger and not parity‑checked — page. Run it in Release: +[benchmarks/dotnet](../benchmarks/dotnet) is the **BenchmarkDotNet** harness: the .NET leg of the +cross-stack benchmark program, structured like the five other ecosystem harnesses under +[benchmarks/](../benchmarks/README.md). It compares Heddle against five other .NET engines — Fluid, +Scriban, DotLiquid, Handlebars.Net and ASP.NET Core **Razor** — across eight workloads and two +fairness tracks. It is deliberately **not** in `Heddle.sln`, and it reaches the engine through its +public surface only. + +**Nothing is timed until it is gated.** Run the gates first; each verb exits non-zero on failure: + +```bash +cd benchmarks/dotnet +dotnet run -c Release -- gate # every registered cell: byte gate, verifier, security floor +dotnet run -c Release -- selftest # the gate's own checks, incl. the six-technique differential +dotnet run -c Release -- verify-corpus # corpus freshness + verifier calibration +``` + +Then measure. Remaining arguments pass straight through to BenchmarkDotNet, so a single workload or +a shorter job is one flag away: ```bash -dotnet run -c Release --project src/Heddle.Performance +dotnet run -c Release -- bench-crossstack # all eight suites, both tracks +dotnet run -c Release -- bench-crossstack --filter *MixedPageBenchmarks* +dotnet run -c Release -- bench-techniques # Heddle's six render techniques against each other +dotnet run -c Release -- bench-cold # cold parse/compile, per engine +dotnet run -c Release -- bench-internal # props, branching, language-service metadata ``` -What it measures -([TextRenderBenchmarks.cs](../src/Heddle.Performance/TextRenderBenchmarks.cs), -`[MemoryDiagnoser]` enabled): - -- **`RenderHeddle`** (published in the linked 2026‑07‑11 report under its former name, - `RenderTemplateEngine`) renders the Heddle home page - ([TestTemplates/home.heddle](../src/Heddle.Performance/TestTemplates/home.heddle) + - [layout.heddle](../src/Heddle.Performance/TestTemplates/layout.heddle)) through - [`HeddleTest`](../src/Heddle.Performance/Runners/HeddleTest.cs). -- **`RenderRazor`** renders a comparable Razor page - ([Views/home.cshtml](../src/Heddle.Performance/Views) + `layout.cshtml`) with runtime - compilation through [`RazorTest`](../src/Heddle.Performance/Runners/RazorTest.cs). Razor's page is - larger and renders different bytes, so — unlike the four Liquid/Handlebars twins — it is **not** - held to the byte‑identical parity assertion; treat its row as indicative rather than - apples‑to‑apples. - -Both pages are shaped alike: one layout, several reusable templates/sections, and a dozen -component invocations — the Heddle components live in -[TestSuite/Extensions](../src/Heddle.Performance/TestSuite/Extensions) and their Razor -counterparts in [TestSuite/RazorExtensions](../src/Heddle.Performance/TestSuite/RazorExtensions). -In the published run of 2026‑07‑11 **Heddle rendered faster than Razor and allocated less memory** -(and led the four parity‑checked engines too); for the numbers see the -[README Performance section](../README.md#performance), and for *why*, see +What the cross-stack suites measure, with `[MemoryDiagnoser]` enabled: one `[Benchmark]` per engine +per workload, on the **controlled** track (every engine authored to produce byte-identical output) +and the **idiomatic** track (every engine authored the way its own documentation teaches). Heddle is +the ratio baseline. The controlled track's byte gate runs in `[GlobalSetup]`, so a twin that drifted +fails the run rather than contributing a number for different work. + +Two things about Heddle's own row are worth knowing before quoting it. It is the **UTF-8 sink**, +because that is the path comparable with the other five ecosystems — they all emit UTF-8 or Latin-1, +while a .NET `string` is UTF-16 and crosses the CLR's Large Object Heap threshold on the three +largest workloads, an allocator cliff no other ecosystem pays. And every technique is measured +through a checksum folded from the bytes the engine actually wrote, never a materialised string, so +a sink cannot win by eliding work. + +The fixtures every engine renders from live in [`src/Models/`](../benchmarks/dotnet/src/Models); the +templates are files under [`templates/`](../benchmarks/dotnet/templates), one directory per track per +engine, so the idiomatic track is reviewable as templates instead of as escaped literals. No engine +carries its own copy of the data, so no twin can drift from the engine it is compared against. + +In the published cross‑stack run of 2026‑07‑25 **Heddle rendered the composed page 1.37× faster +than ASP.NET Core Razor (30.52 μs vs 41.66 μs) and allocated less memory**, on byte‑identical +output under the same parity gate — and led all five other .NET engines on seven of the eight +protocol workloads. For the numbers see the +[README Performance section](../README.md#performance) and the +full report; for *why*, see [Architecture → Performance characteristics](architecture.md#performance-characteristics). > Benchmark numbers are hardware‑ and workload‑specific — run the suite on your target machine @@ -113,9 +136,6 @@ In the published run of 2026‑07‑11 **Heddle rendered faster than Razor and a > benchmark is a representative, component‑heavy page where the compiled document's advantage > is most visible. -There are extra runners (compilation cost, memory) in -[src/Heddle.Performance/Runners](../src/Heddle.Performance/Runners). - ## Packaging Pack all six shipping packages (`Heddle`, `Heddle.Language`, `Heddle.Generator`, diff --git a/docs/built-in-extensions.md b/docs/built-in-extensions.md index ad30bbbf..c90b1105 100644 --- a/docs/built-in-extensions.md +++ b/docs/built-in-extensions.md @@ -167,6 +167,10 @@ one `@else`. Only the winning branch's body renders. its branch sets and its compile‑time scan. - **Isolation.** Each `@list`/`@for` iteration, each nested body, and each `@partial` gets its own set state — an inner set can never satisfy or clear an outer one. +- **A custom continuation or terminal must declare `[ScopeChannel]`** to read the state an opener + publishes. One that does not draws `HED3005` (and `HED7016` at build time) and then misses every + read at render, so it behaves as though no opener ran — see + [building your own branch set](custom-extensions.md#building-your-own-branch-set). These four are the engine's own **role‑carrying** extensions: each declares its position in a set with `[BranchRole]` (opener / continuation / terminal). Nothing about the classification is @@ -217,6 +221,13 @@ common cases need no embedded C# at all: A negative or zero count renders empty (the loop condition is false immediately), matching a data‑driven `Count = 0`. +A `Range` and an `int` are the **only** values `@for` accepts. Anything else with a static type is +refused when the template is compiled (**HED0004**, naming the type it got and the two it wanted) — a +`long`, a `decimal`, a `string`. That includes the *chained* forms, which is the surprising one: +`@for((Count))` and `@for(len(Name))` hand `@for` the chain's rendered **text**, not the number, so both +are refused. Write the expression without the chain — `@for(Count)`, `@for(len(Name) + 0)` — or wrap it +in `range`. + **`range(start, last[, step])`.** The default [function registry](native-expressions.md) includes `range`, which builds a `Heddle.Models.Range` — so `@for(range(...))` gives start/step control with no new syntax: @@ -228,6 +239,10 @@ control with no new syntax: `step` must be positive: a zero or negative literal step is a compile error (**HED4001**), and a non‑positive step known only at render throws. See [native expressions](native-expressions.md#range). +Calling a definition that carries a default output (`-> chain`) by name renders it **twice** — once +where the call is, once at document end — and the compiler warns with **HED4002**. See +[default output](language-reference.md#default-output---chain). + The C# tier still works for computed models: ```heddle @@ -539,6 +554,39 @@ resolve unqualified identifiers. @using(){{MyBlog.Models}} ``` +The body is the **header of a C# `using` directive**, and all three of its forms work — the +engine writes each one into the C# it compiles for an embedded expression, and type names are +resolved through them too: + +```heddle +@using(){{Models = MyBlog.Models}} @* namespace alias → @model(){{Models.Post}} *@ +@using(){{Post = MyBlog.Models.Post}} @* type alias → @model(){{Post}} *@ +@using(){{static MyBlog.Models.Catalog}} @* nested types of Catalog answer to their own name *@ +``` + +A type name may also carry the `global::` qualifier, which names the global namespace and +consults no import and no alias — `@model(){{global::MyBlog.Models.Post}}`. + +Where a name answers to both an alias and an ordinary import, the **alias wins**, as it does in +C#, whichever order the directives appear in; and an alias that claims the leading name commits to +it, so the import is not consulted as a fallback when the alias reaches nothing. + +A plain namespace import brings in the types **declared in** that namespace, and not the +namespaces nested inside it — the same rule C# follows. So `@using(){{MyBlog}}` lets you write +`@model(){{Post}}` if `MyBlog.Post` is a type, and lets you reach a type nested inside it +(`@model(){{Post.Draft}}`), but it does **not** let you write `@model(){{Models.Post}}` for a +`MyBlog.Models.Post`: import `MyBlog.Models`, alias it (`@using(){{Models = MyBlog.Models}}`, which +names the namespace itself and does reach through it), or spell the type in full. + +Three limits, each because the spelling means something the resolver does not model rather than +because it was overlooked: an alias target carrying type arguments (`X = List`), an alias +target with whitespace inside it (`X = My . Ns`), and an extern-alias qualifier (`A::B`). Each is +treated as an ordinary namespace body, so a spelling that needs it does not resolve. + +For **static members** — `using static System.Math;` then `Max(a, b)` — the directive contributes +nothing: `@using(){{static …}}` reaches that type's nested *types* only. Register a +[function](custom-extensions.md) instead. + ### `import` — removed [ImportExtension.cs](../src/Heddle/Extensions/Archived/ImportExtension.cs) · name: `import` diff --git a/docs/coming-from-liquid.md b/docs/coming-from-liquid.md index 1f877292..17491cb1 100644 --- a/docs/coming-from-liquid.md +++ b/docs/coming-from-liquid.md @@ -5,7 +5,7 @@ Heddle looks close enough to be misleading. The delimiters that matter most mean here. This page maps the habits that trip people up to their Heddle equivalents; for the full picture read the [Language Reference](language-reference.md). -> Every Heddle snippet below is a complete template, verified to compile against **Heddle 2.0.0** +> Every Heddle snippet below is a complete template, verified to compile against **Heddle 2.1.0** > under default options — **except the `@partial(){{ sidebar }}` snippet**, which additionally > requires a configured `RootPath`/`FileNamePostfix` and an existing `sidebar` template on disk at > compile time (see [that section](#include--render---vs-partial)). @@ -33,6 +33,11 @@ This is the number-one misread. In Liquid and Jinja `{{ x }}` interpolates a val `{{ Title }}` in text emits the literal braces, not the value. To output a value, use the `@(…)` [output block](language-reference.md#output-blocks). +The compiler warns rather than letting it pass silently: a bare `{{ identifier }}` or +`{{ dotted.path }}` in literal text raises **HED4005**, positioned at the braces and suggesting +`@(…)`. It is a warning, not an error — the literal braces are legal output, so the template still +compiles and renders them. + ## Filters → chains, composed right-to-left ```text diff --git a/docs/coming-from-razor.md b/docs/coming-from-razor.md index 098fe269..c087dcb5 100644 --- a/docs/coming-from-razor.md +++ b/docs/coming-from-razor.md @@ -5,7 +5,7 @@ markup is just text — but a handful of core ideas are deliberately different. Razor habits that trip people up to their Heddle equivalents. For the full picture read the [Language Reference](language-reference.md). -> Every Heddle snippet below is a complete template, verified to compile against **Heddle 2.0.0** +> Every Heddle snippet below is a complete template, verified to compile against **Heddle 2.1.0** > under the default `ExpressionMode` — with one exception: the embedded‑C# line in > [Where C# runs](#where-c-runs-three-tiers-not-everywhere) (`@(@model.Title.ToUpper())`) requires > `ExpressionMode.FullCSharp`, as noted inline. Where a snippet reads model members it declares a diff --git a/docs/csharp-api.md b/docs/csharp-api.md index 68d8f60b..e3d2bede 100644 --- a/docs/csharp-api.md +++ b/docs/csharp-api.md @@ -11,7 +11,7 @@ namespaces: - [`HeddleCompileResult`](../src/Heddle/Data/HeddleCompileResult.cs) — success/errors with source positions. - [`Scope`](../src/Heddle/Data/Scope.cs) — the data view extensions see while rendering. -The library targets `netstandard2.0;net6.0;net8.0;net10.0` +The library targets `netstandard2.0;net8.0;net10.0` ([Heddle.csproj](../src/Heddle/Heddle.csproj)). --- @@ -22,20 +22,47 @@ The concrete engine entry point ([HeddleTemplate.cs](../src/Heddle/HeddleTemplat `sealed` and implements `IDisposable`. A single instance is compiled once and can be rendered many times, including concurrently. -### Registration: `Configure` +### Registration: `Register` ```csharp -public static void Configure(Assembly startupAssembly); +public static void Register(Assembly assembly); +public static void Configure(Assembly startupAssembly); // the same call, older name ``` -Scans `startupAssembly` (and its references) for extensions and registers them. Call once at -startup, passing your application's assembly so custom extensions are discovered. The built‑in -extensions are registered automatically. +Reads `assembly`'s `[ExportExtensions]` and registers what it names, and makes its types visible to +`@model`/type resolution. The engine loads and scans nothing on its own, so registration is **per +assembly and not transitive** — call it for your application assembly and for every extension library +you use. Built‑in extensions are always present. + +Idempotent per assembly and repeatable, so registration order is the host's to choose. Throws +`ArgumentNullException` on null, and `TemplateOverrideException` when two unrelated types claim one +extension name. + +```csharp +HeddleTemplate.Register(typeof(Program).GetTypeInfo().Assembly); +HeddleTemplate.Register(typeof(SomeLibrary.WidgetExtension).GetTypeInfo().Assembly); +``` + +#### Declaring model assemblies: `[HeddleModelAssembly]` + +`Register` also reads the registering assembly's assembly‑level +`Heddle.Attributes.HeddleModelAssemblyAttribute` and registers each named type's **assembly**: ```csharp -HeddleTemplate.Configure(typeof(Program).GetTypeInfo().Assembly); +[assembly: Heddle.Attributes.HeddleModelAssembly(typeof(Acme.Models.Invoice))] ``` +The `typeof` is what makes this stronger than the equivalent `Register` call. A type cannot be named +from a project that does not reference its assembly, so a missing reference is **CS0246 in your own +source** rather than a model that fails to resolve at first render — and the reference it forces is +exactly what the [build tier](precompilation.md#assemblies-the-build-must-see) needs to resolve the +same `@model` spelling. One declaration configures both tiers; there is no `HED` id for it because +the C# compiler already owns the diagnostic. + +`AllowMultiple`, so declare as many as you have. Only the assembly each type comes from is used, so +any public type in it will do. A declared assembly is registered for the life of the process and is +never removed by an editor‑style workspace reload, which withdraws only what the workspace loaded. + ### Constructors | Constructor | Use | @@ -65,8 +92,14 @@ Behavior notes: - Throws `TemplateInitException` if you never compiled, or `TemplateCompileException` if compilation failed — guard with `CompileResult.Success`. -- In **`DEBUG`** builds, `Generate` validates that `data`'s type matches the compiled model - type and throws `TemplateProcessingException` on a mismatch. Release builds skip this check. +- Every top‑level render validates that `data`'s type matches the compiled model type and + throws `TemplateProcessingException` on a mismatch — once per `Generate` call, in every build + configuration. Without the check a wrong‑typed model would escape as a raw + `InvalidCastException` from the compiled accessor. A `null` model is legal and skips the + check. **A precompiled template resolved from the registry is checked the same way**, against + the model type its manifest entry records (`PrecompiledTemplateInfo.ModelType`); an untyped + entry records `object` and so admits every value. The fault, and its message, are the same on + both tiers. - The output buffer auto‑sizes: each call grows an internal capacity estimate (with ~10 % margin) so repeated renders avoid reallocations. @@ -134,14 +167,15 @@ don't flush the partial output as if it were complete. | `HeddleCompileResult Compile(string document, ExType modelType = null)` | Compile an inline string. | | `HeddleCompileResult Recompile(string newDocument, CompileContext context = null)` | Replace the current template with a new string. | | `HeddleCompileResult Recompile(ExType newModelType)` | Recompile the current source against a new model type. | -| `HeddleCompileResult TryCompilation(CompileContext context)` | **Dry run**: runs the parse and extension/type‑check passes but discards the compiled output. | +| `HeddleCompileResult TryCompilation(CompileContext context)` | **Dry run**: runs the full compile pipeline but publishes nothing onto the instance. | | `HeddleCompileResult TryCompilation(string document, TemplateOptions options = null, ExType modelType = null)` | Dry run for an inline string. | -`TryCompilation` is useful for CI/linting — it tells you whether a template's parse and -extension/type‑check passes succeed, without producing a renderer. Note it does **not** run -the deferred‑finalization or embedded‑C# (Roslyn) steps, so a `FullCSharp` template (or one -whose delayed subtemplate fails finalization) can pass the dry run and still fail a real -`Compile`. A template can only be compiled once per instance; compiling an +`TryCompilation` is useful for CI/linting — it runs the **same pipeline as a real `Compile`**, +including deferred‑extension finalization and the embedded‑C# (Roslyn) compile, so its result +reports exactly what a real `Compile` of the same input would. The difference is that nothing +is published: the compiled output is discarded, the instance stays uncompiled (`Compiled` +remains `false`), and `CompileResult` is not set — the outcome is only the returned result. A +template can only be compiled once per instance; compiling (or dry‑running) an already‑compiled instance throws `TemplateInitException`. ### State properties @@ -189,9 +223,11 @@ superseded document is released once no render holds it. ### Disposal `HeddleTemplate` owns its compiled runtime document and any file watcher. Dispose it when done. -Disposal is **best‑effort deferred** while a render is in progress (it aims to dispose once the -last in‑flight `Generate` returns); the in‑flight counter is not fully synchronized, so avoid -disposing an instance that is still being rendered concurrently on other threads. +`Dispose()` is **non‑blocking, idempotent, and safe to call concurrently with active renders**: +it marks the template disposed immediately — a `Generate` that starts afterwards throws +`ObjectDisposedException` — and the actual teardown (watcher, compiled documents) is deferred +until the last in‑flight render exits, so renders already running complete normally. Teardown +runs exactly once across the `Dispose`, deferred‑last‑exit, and finalizer paths. --- @@ -213,15 +249,17 @@ Controls where templates are read from and which features are enabled | `AllowCSharp` | `false` | **Obsolete** bridge over `ExpressionMode` (use `ExpressionMode` directly): `true` == `FullCSharp`. Enables embedded C# (`@( @expr )`, `@new`, LINQ, typed `@model()`). Setting `false` leaves `MemberPathsOnly` untouched, otherwise selects `Native`. Reads and writes keep working; new code sets `ExpressionMode`. | | `MaxRecursionCount` | `100` | Upper bound on definition recursion depth. | | `RenderBudget` | `null` (unlimited) | Per‑render resource caps for untrusted templates: `RenderBudget.MaxOutputChars`, `MaxRenderOps`, and `MaxRenderTime` (each nullable — a null limit is unbounded). `null` (the default) is today's unlimited behavior with **zero render‑path cost** (no wrapper is created). A breach throws `TemplateRenderBudgetException`. Does **not** participate in `Equals`/`GetHashCode` (it changes no bytes of a successful render — same rule as `MaxRecursionCount`). See [Render budgets](#render-budgets). | +| `ValidateModelType` | `false` | **No longer read.** It once opted renders into the model‑type check; that check is now always on — every top‑level `Generate` validates the model against the compiled model type and throws `TemplateProcessingException` on a mismatch, whatever this property says (see [Rendering](#rendering-generate)). The property is retained so existing code keeps compiling. Does not participate in `Equals`/`GetHashCode`. | | `EnableFileChangeCheck` | `false` | Install an armed `FileSystemWatcher` on the source file and recompile on change/create/rename‑onto‑target (see [File watching](#file-watching)). | | `ProvideLanguageFeatures` | `false` | Parse in a tooling mode that emits a token list for editors/highlighters (used by the IDE integrations). | | `Data` | `null` | Optional ambient data carried on the options. | -The file actually read is `Path.Combine(RootPath, TemplateName + FileNamePostfix)`. The -`FullPath` property is a plain string concatenation (`RootPath + TemplateName + FileNamePostfix`, -with no path separator) and is not the resolved read path. A non‑empty `FileNamePostfix` is -**required** for a file compile — `FileReader` throws if it is empty, so the `""` default cannot -be used to compile from a file. +The file actually read is `Path.Combine(RootPath, TemplateName + FileNamePostfix)`, and `FullPath` +now composes exactly that — the same `Path.Combine`, so it **is** the resolved read path. It +previously concatenated the three parts with no separator and was therefore not the path anything +opened; both halves of that description were corrected when the property was fixed. A non‑empty +`FileNamePostfix` is **required** for a file compile — `FileReader` throws if it is empty, so the +`""` default cannot be used to compile from a file. ```csharp var options = new TemplateOptions("home") @@ -419,7 +457,7 @@ to descend into elements or swap model/chained values. See `ParseContext.Warnings` (reachable via `CompileResult.Context.Warnings`), not `CompileContext.CompileWarnings` (see [Architecture](architecture.md#2-parsing)). - **Render errors** surface as exceptions from `Generate` - (`TemplateInitException`, `TemplateCompileException`, and — in DEBUG — + (`TemplateInitException`, `TemplateCompileException`, and `TemplateProcessingException` for a model‑type mismatch). ## End‑to‑end example @@ -430,7 +468,7 @@ using Heddle; using Heddle.Data; using Heddle.Runtime; // CompileContext -HeddleTemplate.Configure(typeof(Program).GetTypeInfo().Assembly); +HeddleTemplate.Register(typeof(Program).GetTypeInfo().Assembly); var options = new TemplateOptions("home") { diff --git a/docs/custom-extensions.md b/docs/custom-extensions.md index e2b6aaf9..0eae99c8 100644 --- a/docs/custom-extensions.md +++ b/docs/custom-extensions.md @@ -64,8 +64,14 @@ public interface IExtension : IDisposable > document (the `@using`/`@model`/`@profile` pattern). Such blocks automatically participate in > [directive‑line trimming](language-reference.md#whitespace-trimming-): when > `TemplateOptions.TrimDirectiveLines` is on and the block occupies its line by itself, the -> whole line is swallowed. You get this for free — trimming keys on the removal mechanism, not -> on a name list, so there is nothing extra to implement. +> whole line is swallowed. Trimming keys on the removal mechanism, not on a name list, so no +> registration or name list needs updating. +> +> On the **dynamic tier** that is all it takes. For the block to be removed when the template is +> **precompiled**, declare [`[ZeroOutput]`](#precompiled-mode): a build-time generator reads symbols +> and cannot observe that your `InitStart` returns `null`, so without the attribute the block is +> removed dynamically and kept as output precompiled — the two tiers disagree on bytes, which is the +> one thing pre-compilation may never do. Declare it whenever `InitStart` returns `null`. ### Helpers from the base class @@ -126,7 +132,7 @@ using Heddle.Data; // Span write — dispatches to the sink's native span path when available, else materializes a string. scope.Renderer.Render(mySpan); -// Value format — no intermediate string on the span/UTF-8 tiers (net6+): +// Value format — no intermediate string on the span/UTF-8 tiers (net8+): // IUtf8SpanFormattable straight to bytes on a UTF-8 sink (net8+), else ISpanFormattable into a // stackalloc char span, else ToString(format, provider). Identical characters on every tier. scope.Renderer.Render(count, "N0", CultureInfo.InvariantCulture); // where count : struct, ISpanFormattable @@ -179,8 +185,10 @@ mismatch (HED5003), duplicate argument (HED5004). Named arguments on an extensio **no** `[Prop]` remain an error (HED5005). `[Prop]` is inherited by subclasses; a subclass may re‑declare an inherited parameter with an assignable (narrowing) type and a new default. Values are bound once at compile — an all‑constant call site shares one frozen array across renders (no -per‑render allocation). Parameter‑declaring extensions precompile on the bodiless path exactly as -definitions with props do; bodied calls fall back to the dynamic tier as all bodied custom calls do. +per‑render allocation). Parameter‑declaring extensions precompile exactly as definitions with props do, on the bodiless and +the bodied path alike: the `[Prop]` layout is frozen at build and the carrier that installs it wraps +the extension *after* its own hook has run, which is the order the engine's compiler uses — see +[Precompiled mode](#precompiled-mode). --- @@ -312,7 +320,8 @@ There are three roles: **`[ScopeChannel]` goes on Continuation and Terminal, not on the Opener** (R11). Continuation and terminal extensions *read* the channel (`TryRead`), and locals‑frame provisioning keys off `[ScopeChannel]`; omit it and their read always misses at render time (the engine warns — -**HED3005** at runtime, **HED7016** at build time — but cannot fix it for you). An opener publishes +**HED3005** at the call on both tiers, plus **HED7016** once per drifting type at build time — but +cannot fix it for you). An opener publishes *opportunistically*: it carries no `[ScopeChannel]`, so a set with no continuation/terminal sibling provisions no frame and the publish is a harmless no‑op — this is exactly what keeps templates that use no branch allocation‑identical. @@ -432,12 +441,86 @@ Because a custom terminal's render‑time orphan message is yours to phrase, thr `TemplateProcessingException` when the read misses (as `@finish` does) — the engine's HED3003 covers only the statically visible case. -**Precompilation.** Custom branch sets are fully functional on the runtime (dynamic) tier — the -set‑*structuring* rules above apply on both tiers because classification is role‑based everywhere. -Only the pinned branch *emission* is reserved for the engine's own built‑ins; a bodied call to a -custom branch extension simply falls back quietly to the dynamic tier (no `HED7015` error — the -`InitStart` override is the canonical shape here, not a mistake), and renders identically with full -role semantics. +**Precompilation.** Custom branch sets are fully functional on both tiers, and they **precompile**: the +set‑*structuring* rules above apply everywhere because classification is role‑based, and your +`InitStart` override — the canonical shape for a branch extension — runs for real inside your own +assembly when the generated template's type initializer runs. Nothing about it has to be predicted, so +nothing about it costs a tier. + +--- + +## Building your own slot projection + +A definition that declares a slot parameter — `` — does not pre‑render the content +its call site passed it. The engine installs that content on the scope as an +[`ISlotContent`](../src/Heddle/Data/ISlotContent.cs) and lets each `[SlotProjection]` extension in the +body render it, once per projection, against a model the projection chooses. That is what lets one +caller body be rendered per element of a loop. + +Everything the built‑in `@out` reads to do this is public, so a projection of your own is a normal +extension: + +```csharp +using Heddle.Attributes; +using Heddle.Core; +using Heddle.Data; +using Heddle.Exceptions; + +[ExtensionName("project")] +[SlotProjection] +public class ProjectExtension : AbstractExtension +{ + private bool _slotMode; + private bool _composed; + + public override ExType InitStart(InitContext initContext, ExType dataType, ExType chainedType, ExType parent) + { + // The slot type of the definition body being compiled — null anywhere else. + var slotType = initContext.CompileScope.CompileContext.SlotParameterType; + if (slotType != null) + { + _slotMode = true; + _composed = initContext.IsChainedConsumer; + if (!initContext.CallCarriesValue) + initContext.CompileScope.CompileErrors.Add(/* your own positioned diagnostic */); + base.InitStart(initContext, chainedType, parent, null); + return typeof(string); + } + + base.InitStart(initContext, chainedType, parent, null); + return chainedType; + } + + public override void RenderData(in Scope scope) + { + if (!_slotMode) { RenderInnerResult(scope); return; } + var carrier = scope.SlotCarrier; + if (_composed || carrier == null) + throw new TemplateProcessingException("'@project' has no caller content to project here."); + carrier.RenderCallerContentInto(carrier.InvocationScope.Model(scope.ModelData)); + } +} +``` + +Three things are load‑bearing: + +- **Re‑model the invocation scope, don't render against it.** `InvocationScope.Model(value)` pairs the + value the projection was passed with the props and caller frame of the definition's *invocation + site*, which is what lets the caller's content see the value it was written for while its `::`‑rooted + and prop references still resolve where it was written. +- **Prefer `RenderCallerContentInto`.** It writes straight into the scope's renderer; + `RenderCallerContent` materialises a string and is only worth it when `ProcessData` needs the content + as a value. +- **Refuse composition.** `InitContext.IsChainedConsumer` is true when the call has a producer to its + right (`@wrap():project()`), which means the content arrived on the chained channel and there is no + caller content to project. + +`ISlotContent` and `Scope` are both confined to one render lineage — consume them in the call that +received them and never store them. + +**Precompilation.** A slot projection precompiles: the generator dispatches on the declaration rather +than on a name, constructs your extension, and runs the `InitStart` above inside your own assembly, so +the slot state is decided by your hook rather than predicted. --- @@ -482,14 +565,15 @@ namespace MyApp.Extensions Usage in a template: `@upper(Name)`. -> **Precompilation note.** This example overrides `InitStart` (to type the body against the parent -> model), which is a **runtime‑tier** shape. Because `UpperExtension` is not a `[BranchRole]` extension, -> a *precompiled* template calling `@upper(...)` draws a build error (`HED7015`) — see -> [Precompiled mode](#precompiled-mode). If your templates must precompile, omit the `InitStart` override -> (accepting the default typing) or keep such templates on the dynamic tier. +> **Precompilation note.** This example overrides `InitStart` to type the body against the parent model, +> and a precompiled template calling `@upper(...)` **precompiles anyway**: the generated static +> initializer constructs `UpperExtension` in your own assembly and calls this very method, handing it the +> already‑generated body instead of letting it compile one. The typing decision below is therefore made +> by your code, not guessed at by the build — see [Precompiled mode](#precompiled-mode). > -> The example also derives from `AbstractHtmlExtension`/`[EncodeOutput]`, whose HTML encoding is **not** -> reproduced by precompiled binding (see the warning under [Precompiled mode](#precompiled-mode)). +> The example also derives from `AbstractHtmlExtension`/`[EncodeOutput]`; that encoding **is** reproduced +> by precompiled binding, on the bodiless and the bodied path alike, and it is now *derived from the live +> type* rather than written into the generated file, so it cannot drift. Compare with the real [`StringExtension`](../src/Heddle/Extensions/StringExtension.cs) and [`DateExtension`](../src/Heddle/Extensions/DateExtension.cs), which follow the same shape. @@ -503,11 +587,15 @@ Declared in [src/Heddle/Attributes](../src/Heddle/Attributes): | Attribute | Target | Purpose | | --- | --- | --- | | `[ExtensionName("name")]` | class | The verb used in templates (`@name(...)`). Required. The empty name `""` is the unnamed `@(...)` carrier; `raw` is its always‑verbatim alias. | -| `[DataType(typeof(T))]` | class | The model type the extension expects. Repeatable (e.g. `int` *and* `long` on `IntegerExtension`). | +| `[DataType(typeof(T))]` | class | The model type the extension expects. Repeatable (e.g. `int` *and* `long` on `IntegerExtension`); inherited by subclasses. A call whose value has a static type assignable to none of them is refused when the template is compiled (`HED0004`, naming the value's type and every accepted one) — on both tiers, so a template that does not compile does not precompile either. Assignability is reflection's (`Type.IsAssignableFrom`) in full, with a `Nullable` value unwrapped first — so it includes generic variance (`List` reaches `IEnumerable`) and array covariance, including the element types the CLR reduces to one — each signed/unsigned integer pair (`nint`/`nuint` included) and an enum with its underlying primitive, in either direction and through the array's own generic interfaces (`uint[]` reaches `int[]`, `DayOfWeek[]` reaches `int[]`, `int[]` reaches `IList`). It is not a conversion relation: there is **no** numeric widening, so `[DataType(typeof(int))]` refuses a `long`, and a value-type element never covaries to a reference-type one, so `int[]` does not reach `object[]`. A value with no static type (`dynamic`) is decided at render instead. | | `[ChainedType(typeof(T))]` | class | The expected chained‑input type. | | `[EncodeOutput]` | class | HTML‑encode the output (pairs with `AbstractHtmlExtension`). This encodes under **both** output profiles — it is independent of `OutputProfile`, which only governs the unnamed `@(...)` carrier. Keep `[EncodeOutput]` on value formatters that emit user text; leave it off for containers that merely forward a body (so encoding stays at the emitting leaf). | | `[ExtensionReplace]` | class | Marks an extension intended to replace another of the same name. | | `[BranchRole(BranchRole.Opener\|Continuation\|Terminal)]` | class | Declares the extension's position in a branch set (opener/continuation/terminal), giving it the same set semantics as the built‑in `@if`/`@elif`/`@else` family. Compile‑time only; inherited by subclasses. See [Building your own branch set](#building-your-own-branch-set). | +| `[ScopeChannel]` | class | Declares that the extension publishes to or reads from the [local context channel](#the-local-context-channel). Bodies containing one are provisioned with a locals frame at compile time; without one, `Scope.Publish` throws and `Scope.TryRead` returns `false`. Compile‑time only; inherited by subclasses. | +| `[SlotProjection]` | class | Declares that the extension is a **slot projection**: inside a definition body that declares a slot parameter (``) the call carries that slot's value and renders the caller's content in its place, and outside one it splices the caller's content against the enclosing model. Both tiers dispatch the slot channel on this declaration rather than on the name the extension answers to, so a custom projection is served exactly as the built‑in `@out` is. Carrying it obliges the extension to read the enclosing definition's slot type off the compile context in its own `InitStart`, to report the slot diagnostics that reading implies, and to render through the scope's slot carrier rather than through its own body. Compile‑time only; inherited by subclasses. | +| `[ChildTemplateHost]` | class | Declares that the extension is a **child‑template host**: its body is not content but a name, which it resolves at compile time to a second template, compiles as a child of the one being compiled, and hosts — rendering that child's output in place of its own body. Both tiers dispatch the child‑template route on this declaration rather than on the name the extension answers to, so a custom host is served exactly as the built‑in `@partial` is. Carrying it obliges the extension to evaluate its own body once at compile time to produce the name, to queue the child compile so the child's errors reach the parent's compile result, and to take delivery of the compiled child in `CompleteInit`. A call to one **precompiles in a default build**: the extension is constructed and its hook run at static init, and the child arrives through the engine's child supply — the precompiled entry when the registry holds the named template, the extension's own compile under the request's options when it does not. Compile‑time only; inherited by subclasses. | +| `[ZeroOutput]` | class | Declares a **directive**: the extension emits nothing and its whole block is removed from the document rather than kept as rendered output. The runtime’s own protocol for this is behavioral — a directive’s `InitStart` returns `null` — and stays authoritative; this attribute is the declarative form of it, and it is what makes the **precompiled tier** classify your extension correctly (a build‑time generator can only read symbols). Declare it whenever `InitStart` returns `null`: without it, the block is removed dynamically and kept as output when precompiled. The four built‑in directives (`@model`, `@using`, `@import`, `@profile`) carry it. Inherited by subclasses. | | `[Prop("name", typeof(T))]` | class | Declares one typed, named input **parameter** the caller passes by name (`@grid(Photos, columns: 4)`) — the identical call shape a definition with props accepts, with the identical diagnostics. One attribute per parameter (`AllowMultiple = true`); inherited by subclasses. Optional when `Default = value` is set (or `Optional = true` for a null default); required otherwise. Read at render via `Scope.TryGetParameter`/`Scope.GetParameter`. | | `[NotEncode]` | model property | Reserved, currently **inert** — the attribute type ships but has no effect (its only check runs against extension classes, never properties). Do not rely on it; its per‑property meaning is revisited with typed props. | | `[Hidden]` | model property | Hide a model property from template resolution. | @@ -521,7 +609,7 @@ carries `[ExtensionReplace]`; otherwise registration throws `TemplateOverrideExc ## Registering your extensions -Two steps: +Two steps to register, and a third if you pre‑compile: 1. **Export** the extension(s) from the assembly with the assembly‑level attribute [`ExportExtensions`](../src/Heddle/Attributes/ExportExtensionsAttribute.cs): @@ -536,54 +624,107 @@ Two steps: // [assembly: ExportExtensions] ``` -2. **Configure** the engine with your startup assembly so the export is discovered: +2. **Register** each assembly that exports extensions: ```csharp - HeddleTemplate.Configure(typeof(Program).GetTypeInfo().Assembly); + HeddleTemplate.Register(typeof(Program).GetTypeInfo().Assembly); + HeddleTemplate.Register(typeof(SomeLibrary.WidgetExtension).GetTypeInfo().Assembly); ``` -`Configure` walks the given assembly and its references, so exporting from any referenced -assembly is sufficient as long as that assembly is reachable from the one you pass. +3. **If you pre‑compile**, make sure the build sees the assembly too. The build tier resolves + extension and model types over the **compilation's reference closure**, not over what is loaded, so + an extension library you already reference needs nothing — but a project that does not reference it + can put it in front of the compiler with the escape‑hatch item: + + ```xml + + + + ``` + + Model assemblies have the stronger declarative form, `[assembly: HeddleModelAssembly(typeof(T))]`, + which configures both tiers at once. See + [Assemblies the build must see](precompilation.md#assemblies-the-build-must-see). An unseen + extension assembly is never an error — the templates that call it simply degrade to the dynamic + tier, where step 2's registration still serves them. + +Registration is per assembly and is **not** transitive: the engine loads nothing and scans nothing on +its own, so an extension library you merely *reference* is not discovered — register it too. This is +deliberate. Extension names are a shared namespace, and the set of assemblies allowed to claim a name +is the host's decision, not a consequence of which packages happened to be in the dependency graph. + +Registration is idempotent per assembly and repeatable, so you may register in whatever order +establishes the precedence you want — a later `[ExtensionReplace]` extension displaces an earlier +incumbent of the same name, and two unrelated types claiming one name throw +`TemplateOverrideException` at the registering call rather than out of a type initializer. + +`HeddleTemplate.Configure(assembly)` is the same call under its older name, kept working. + +> **Migrating from 2.0.** 2.0 loaded the entry assembly's whole reference closure and scanned all of it, +> so exporting from any referenced assembly was enough and `Configure` was optional. Both are gone: +> export **and** register. A template calling an unregistered extension reports +> `Cannot find extension ` (`HED0002`); a precompiled one degrades per request with an +> `ExtensionBindingMismatch` naming it. ## Precompiled mode When you [pre‑compile templates](precompilation.md) at build time, a custom extension is **bound from its referenced assembly, never inlined** — a security or logic patch reaches -precompiled templates by updating the package, no regeneration. For a template that uses your -extension to precompile, the extension must satisfy the same contract precompiled binding -reproduces: +precompiled templates by updating the package, no regeneration. + +**Your extension precompiles.** Bodied, hook‑overriding, `[Prop]`‑declaring, `[BranchRole]`‑carrying — +in a default build, with no property to set and no name list to be on. It needs a parameterless +constructor. If its compile‑time behaviour genuinely cannot be reproduced from a static initializer, it +declares `[PrecompileUnsupported]` and the calls to it fall back **one call site at a time**, never +taking the template with them. The rest of this section is those three sentences with their reasons: - **A parameterless constructor.** The generator constructs one shared, pre‑built instance per call site (`new YourExtension()`); no `Activator`, no registry lookup at run time. - **No reliance on runtime registry mutation.** The instance is built once and never mutated after binding; extensions that expect to be re‑registered or reconfigured per render are not supported. -- **No `InitStart`/`CompleteInit` override** *(outside the engine assembly)*. Those are - compile‑time hooks the build‑time backend runs the *base* behavior of; an override could run - arbitrary compile‑time logic the generator cannot evaluate, so a template binding such an - extension is a build error (`HED7015`). **Exception:** a `[BranchRole]` custom branch extension - is expected to override `InitStart` (its canonical parent‑model shape), so it is *not* a - `HED7015` error — a bodied call to it degrades quietly to the dynamic tier instead (see - [Building your own branch set](#building-your-own-branch-set)). Keep custom logic in `ProcessData`/`RenderData` — the - render‑time methods both backends share. A plain, non‑encoding extension (the common case) needs no changes. - -**Build‑time binding covers only bodiless custom calls.** A bodiless value transform (`@ext(x)`) binds -directly to your extension at build time; a call that carries a `{{ … }}` body falls back to the dynamic -tier for that call site (a bodied body's model‑typing is extension‑specific, so the generator cannot bind -it conservatively). Bodied calls therefore run identically to the dynamic path. - -> **Warning — precompiled binding does NOT reproduce `[EncodeOutput]` / `AbstractHtmlExtension` encoding.** -> On the dynamic tier, an extension deriving from `AbstractHtmlExtension` and marked `[EncodeOutput]` -> HTML‑encodes its output. Precompiled binding hard‑codes `RenderType.Raw` for every custom extension and -> never reads `[EncodeOutput]`, so the *same* extension renders its output **unencoded** once its template -> is precompiled — a silent loss of HTML encoding, i.e. an XSS vector for untrusted data. There is **no -> build‑time diagnostic** for this. If you rely on `[EncodeOutput]`/`AbstractHtmlExtension` for encoding, -> either **encode explicitly inside your `ProcessDataInternal`/`RenderDataInternal` override** (so output is -> safe on both tiers) or **exclude such templates from precompilation**. The same gap affects the built‑in -> `@html`. (Scope: the unsafe path is a *bodiless* call — a `{{ … }}` body falls back to the encoding -> dynamic tier — with *no* `InitStart`/`CompleteInit` override, since an override is caught loudly as -> `HED7015`. Built‑ins `@string`/`@money`/`@date`/`@time`/`@int` are unaffected because they override a -> compile‑time hook and fall back to the dynamic tier.) +- **An `InitStart`/`CompleteInit` override is fine — it runs for real.** The generated static + initializer constructs your extension inside your own assembly and calls its actual hook, supplying + the already‑generated body in place of a body compile. Everything the hook decides is decided by your + code: the typing it hands the body, the state it caches, the diagnostics it raises. A bodied call to + your extension precompiles too. Where your hook chooses a model type the build could not resolve, the + body is emitted with **no model cast** and its member reads bind to the engine's own accessor once + your hook has answered — three shapes inside such a body still cost that one call site its tier (a + computed native expression, an embedded C# expression, and a nested call whose typing needs the same + answer), and the rest of the template is unaffected. + If your hook genuinely cannot survive this — the clear case being one that walks the enclosing + document through `InitContext.ParseContext.Tokens`/`SubContexts`, which a single call site cannot + carry — declare it and be taken at your word: + + ```csharp + [ExtensionName("toc")] + [PrecompileUnsupported("reads the enclosing document's headings through InitContext.ParseContext")] + public sealed class TableOfContentsExtension : AbstractExtension { … } + ``` + + Every call to it binds dynamically and reports `HED7033` quoting your sentence verbatim; the rest of + the template still precompiles. The attribute is read at build time *and* off the live type at run + time, so adding it in a package update protects consumers who have already built. +- **A `[Prop]` default whose type generated code can name.** Defaults are frozen into the generated + source as the exact boxed value the runtime would build from the attribute, so a default of an `enum` + type — including on an `object`‑typed prop, where the box keeps the enum, not its underlying number — + is written by naming that enum. A default whose type is `internal` to your assembly cannot be named + there, so a template calling that extension quietly runs on the dynamic tier instead. Make the enum + `public` if such templates must precompile. + +**There is no list of supported body shapes, and no name on it.** What a `{{ … }}` body is typed against +is your `InitStart`'s decision, so the build stopped keeping an answer of its own — a bodiless value +transform and a bodied call bind by the same route, and a body the build cannot type is written so that +it does not need to be typed. Nothing about your extension has to be recognised for this to work. + +> **`[EncodeOutput]` / `AbstractHtmlExtension` encoding is reproduced on both tiers.** Precompiled binding +> derives the render type from the extension's own `[EncodeOutput]`/`[NotEncode]` attributes — the same +> two‑bool decision the dynamic tier evaluates over the live instance — for bodiless calls and, since the +> body‑hosting bind stopped hard‑coding `RenderType.Raw`, for bodied ones too. This paragraph used to warn +> that it did not, and that warning outlived the code it described; the hard‑coded value that was still +> left had no reachable call site until an encoding extension could host a body, which is exactly what +> made fixing it urgent rather than cosmetic. Both halves are pinned by differential tests that render the +> same template on both tiers and compare bytes. An extension name that resolves to no `[ExtensionName]` type in any referenced assembly is a build error (`HED7006`) **when the call carries a `{{ … }}` body**; a bodiless unresolvable call falls back diff --git a/docs/editor-support.md b/docs/editor-support.md index 4715b5a0..24d95da6 100644 --- a/docs/editor-support.md +++ b/docs/editor-support.md @@ -65,22 +65,60 @@ setting). Because it is a single file, it is the editor‑agnostic carrier. "rootPath": "Views", "outputProfile": "html", "expressionMode": "native", - "fileNamePostfix": ".heddle" + "fileNamePostfix": ".heddle", + "trimDirectiveLines": true, + "maxRecursionCount": 100 } ``` -| Field | Meaning | +The editor follows the same configuration surface the engine permits: every compile option that +affects analysis has a key here, and its name is the option's own name camel‑cased, with the same +default the engine and the build tier use. + +The options with **no** key are exactly these eleven, each for a stated reason — the list is gated +against the parity test's own exclusion set, so it cannot quietly fall out of date: + +| Option | Why it has no key | | --- | --- | -| `assemblies` | Model assemblies for typed completion/hover, **and** the input of the one‑shot export scan (see below). Relative to the workspace root. | -| `rootPath` | Template root for `@<<` import and `@partial` resolution (`TemplateOptions.RootPath`). | -| `outputProfile` | `text` or `html` — so diagnostics match your host's compile options. | -| `expressionMode` | `memberPathsOnly` / `native` / `fullCSharp`. | -| `fileNamePostfix` | Template file name postfix. | +| `TemplateName` | Per‑document identity; the analyzer derives it from the file being analyzed. | +| `FullPath` | Computed from `RootPath`/`TemplateName`/`FileNamePostfix` — not an input. | +| `Functions` | A `FunctionRegistry` object with no literal JSON form; represented by `assemblies`, which the one‑shot export scan reads. | +| `Data` | Render input (the model instance); analysis compiles, never renders. | +| `Encoder` | Render‑time output encoding, object‑valued; changes rendered bytes, never a diagnostic. | +| `RenderBudget` | Per‑render resource limits, object‑valued; no lint depends on them. | +| `ValidateModelType` | Retained for source compatibility but no longer read — the render‑time model‑type check is always on; analysis has no data anyway. | +| `PrecompiledMismatchPolicy` | Selects run‑tier fallback vs throw; the analyzer never consults the precompiled registry. | +| `EnableFileChangeCheck` | The runtime's file watcher; the editor owns document versioning itself. | +| `ProvideLanguageFeatures` | Always on in the LSP — the analyzer's operating mode, not a workspace choice. | +| `AllowCSharp` | Obsolete bridge over `ExpressionMode`; wiring both would let a config contradict itself. | + +| Field | Meaning | Default | +| --- | --- | --- | +| `assemblies` | Model assemblies for typed completion/hover, **and** the input of the one‑shot export scan (see below). Relative to the workspace root. | none | +| `rootPath` | Template root for `@<<` import and `@partial` resolution (`TemplateOptions.RootPath`). | the workspace root | +| `outputProfile` | `text` or `html` — so diagnostics match your host's compile options. | `html` | +| `expressionMode` | `memberPathsOnly` / `native` / `fullCSharp`. | `native` | +| `fileNamePostfix` | Template file name postfix. | empty | +| `trimDirectiveLines` | Whether whole‑line directives swallow their line (`TemplateOptions.TrimDirectiveLines`). | `true` | +| `maxRecursionCount` | Compile‑time recursion bound (`TemplateOptions.MaxRecursionCount`). | `100` | + +An unrecognized value never breaks editing: the option keeps its default and the server writes a +log line naming the accepted values (visible in the client's Heddle output channel). A key of the +wrong JSON type is ignored the same way. + +::: warning The default output profile is `html` +Before 2.0.x the editor defaulted to `text` while the engine and the build tier defaulted to `html`, +so a workspace with no `outputProfile` never saw the encoding lints (`HED2004` and friends) its +build of record produces. The editor now defaults to `html` like everything else. If your templates +really are text‑profile, set `"outputProfile": "text"` — that is the opt‑out, and it is also what +your host should be passing. +::: The VS Code extension contributes mirror settings (`heddle.model.assemblies`, `heddle.workspace.rootPath`, `heddle.compile.outputProfile`, `heddle.compile.expressionMode`, -`heddle.compile.fileNamePostfix`, plus `heddle.server.path` and `heddle.trace.server`) and forwards -them to the server. +`heddle.compile.fileNamePostfix`, `heddle.compile.trimDirectiveLines`, +`heddle.compile.maxRecursionCount`, plus `heddle.server.path` and `heddle.trace.server`) and +forwards them to the server. **Types are stale until rebuild.** The editor loads your model assemblies as they are on disk; rebuild your project to pick up type changes. @@ -97,9 +135,18 @@ runs a **one‑shot scan** of the configured `assemblies`: exported functions register into the workspace registry, so their calls resolve (no false "unknown function"), complete with real signatures, and participate in expression typing. -For runtime parity, call -[`FunctionRegistry.RegisterFrom(assembly)`](custom-extensions.md#declaratively-exporting-functions) -on the same assemblies in your host startup — the editor and the host then see one set. +For runtime parity, do the same two registrations on the same assemblies in your host startup — a +`new FunctionRegistry()` filled with +[`RegisterFrom(assembly)`](custom-extensions.md#declaratively-exporting-functions) and assigned to +`TemplateOptions.Functions`, plus +[`HeddleTemplate.Register(assembly)`](csharp-api.md#registration-register). The editor and the host +then see one set. + +**And the build tier is the third reader of the same declarations.** `assemblies` is how the editor is told +which model assemblies to load; the build tier is told by a reference, which +[`[HeddleModelAssembly(typeof(T))]`](precompilation.md#assemblies-the-build-must-see) makes exist and +`HeddleTemplate.Register` reads at startup. Declaring it once covers the run and build tiers; point +`assemblies` at the same DLLs and all three agree about what `@model Foo` names. **The scan is one‑shot per server process.** A new export, a changed extension body, or an `assemblies` change after load requires a **server restart** (VS Code: *Heddle: Restart Language diff --git a/docs/getting-started.md b/docs/getting-started.md index 3b14579c..06f9e128 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -19,7 +19,7 @@ fallback. - **.NET SDK 10.0** (the repository pins `10.0.100` with `rollForward: latestMinor` in [global.json](../global.json)). The core library itself targets - `netstandard2.0;net6.0;net8.0;net10.0`, so the compiled package runs on a wide range of hosts. + `netstandard2.0;net8.0;net10.0`, so the compiled package runs on a wide range of hosts. - A reference to the **`Heddle`** package. To build the engine from source, see [Building & Testing](building.md). @@ -28,22 +28,22 @@ To build the engine from source, see [Building & Testing](building.md). Using the engine always follows the same shape: -1. **Configure** — register the extensions found in your assemblies (once per process). +1. **Register** — hand the engine each assembly that exports extensions (once per process). 2. **Compile** — parse a template string or file into a `HeddleTemplate`. 3. **Generate** — render the compiled template against a data object, as many times as you like. -### 1. Configure (register extensions) +### 1. Register (declare your extensions) -`HeddleTemplate.Configure` scans the given assembly (and assemblies it references) for exported -extensions. The built‑in extensions in the `Heddle` assembly are picked up automatically; -call `Configure` with *your* startup assembly so any custom extensions you wrote are -discovered too. +`HeddleTemplate.Register` reads one assembly's exported extensions. The built‑in extensions in the +`Heddle` assembly are always present; register *your* assembly so the custom extensions you wrote are +too. Registration is per assembly and not transitive — the engine loads and scans nothing on its own, +so an extension library you only *reference* needs its own call. ```csharp using System.Reflection; using Heddle; -HeddleTemplate.Configure(typeof(Program).GetTypeInfo().Assembly); +HeddleTemplate.Register(typeof(Program).GetTypeInfo().Assembly); ``` See [Writing Custom Extensions](custom-extensions.md) for how extensions are exported with diff --git a/docs/language-reference.md b/docs/language-reference.md index 2641d3c3..7269787e 100644 --- a/docs/language-reference.md +++ b/docs/language-reference.md @@ -528,6 +528,14 @@ Two well‑known identifiers are available in embedded C#: There is also a `chained` value available to extensions such as `@for` (the loop index); see [`Scope`](csharp-api.md#scope-the-data-view-during-rendering). +> **Arithmetic is unchecked.** An embedded C# expression is compiled inside `unchecked(…)`, so an +> overflow wraps rather than throwing — including a constant overflow, which C# would otherwise reject +> at compile time (`CS0220`). This matches [native expressions](native-expressions.md), which are built +> from the unchecked expression-tree factories, and it is what lets a +> [precompiled](precompilation.md) template behave the same when the consuming project sets +> `true` — a setting the template knows nothing +> about. Write the check yourself (`checked(…)`) if you want one. + > **Parser nuance.** A C# expression is just a run of C# tokens up to the matching `)`, so > nested parentheses inside it (as in `@Foo(1)`) are part of the expression. The named call > form `@x(@Foo(1))` and the unnamed form `@(@Foo(1))` therefore classify those tokens @@ -653,6 +661,12 @@ Generic and array type names are recognized by the lexer's type rule (`ID_TYPE`, [HeddleLexer.g4](../src/Heddle.Language/HeddleLexer.g4)), which accepts `Namespace.Type[]` forms. +The annotation also constrains the **call site**: when a call passes a member path or a prop — +`@article_card(Featured)` — that value's static type must be assignable to the annotated type, +or the template fails to compile with **HED0004** naming both. Other call forms are not checked, +because they reach the definition with no static type to compare against it: a literal, `this`, +a computed expression, a chain, and a path that goes through a `dynamic` hop. + ### Abstract definitions and late type binding The annotation is **optional**, and leaving it off is a feature, not a shortcut. A definition @@ -715,7 +729,8 @@ default**: ``` - **Types** resolve exactly like a `:: Type` annotation (C# keyword types, dotted names, - generics, arrays — `List`, `int[]`). + generics, arrays — `List`, `int[]`). A type name that does not resolve is **HED5010**. +- **Prop names are unique within one header** — declaring the same name twice is **HED5007**. - **Defaults are literals only** — the phase‑1 literal forms (`"…"`, `42`, `1.5`, `true`, `'c'`, `null`, and a leading `-` on a number). A default must be convertible to the prop's type under the same rule call‑site arguments use; `` is fine, @@ -890,7 +905,7 @@ rendered entry point must be the final page and a page can't easily become a bas In Heddle the relationship is symmetric — `layout` knows nothing about `home`, any template that exposes regions can serve as a base for anything, and because it all compiles into a single execution‑ready document, **this composition costs nothing at render time**. (The -[performance benchmark](../src/Heddle.Performance) uses exactly this `home` + `layout` +[performance benchmark](../benchmarks/dotnet) uses exactly this `home` + `layout` shape.) See [Architecture → Performance](architecture.md#performance-characteristics). --- @@ -951,7 +966,10 @@ Rules: - **Region-context scope.** An override body runs in the **region's own context** — the component's props (`@(theme)`, `@(title)`) plus the region's model (`@(Title)` against `Article`) — exactly like the default body it replaces. An `@out(value)` inside a region body - is the ordinary "no slot" error (**HED5012**); a region is not the host of the component's slot. + is the ordinary "no slot" error (**HED5012**); a region does not inherit the component's slot. + A region that declares a slot **of its own** (``) is a slot definition like any other: + inside it `@out(value)` projects that region's caller content, and a bare `@out()` there is + **HED5013**. - **Self- and sibling calls.** Inside a fill body, calling the region's **own** name renders the region's *default* (no recursion); calling a **sibling** region resolves that sibling's fill (or default) — exactly like the default body it replaces. @@ -964,6 +982,20 @@ Rules: scope at the call site stays a **normal override** (the local override wins — it is never rerouted to a region fill); a `` naming neither a region nor anything in scope keeps today's *"Base definition x couldn't be found"* error. +- **One body, whatever calls it.** A region's body is compiled **once per component body**, against + the model of whichever call site inside that body reaches it first; a later call site's value is cast + to that same model. So an untyped `<:r>` called both directly and from inside `@list(Items){{@r()}}` + renders the *component's* members at both call sites — and if the element's type is not the + component's, the cast fails at render. Declare a separate region per model rather than calling one + region from two places that hand it different types. + The **fill scope is not part of that identity either**: two calls in one component body that fill the + same region differently share the body the first of them compiled, fills included. Fill once per + component body, or move the second call to document scope, where each call parses its own copy. +- **What the model is.** A region declaring `:: T` runs its body against `T`. A region declaring + `dynamic`, `object`, `System.Object` — or nothing at all — runs it against the value its call site + passes, because all four resolve to `System.Object` and none of them says anything about the model. + The one thing `dynamic` still changes is a call site that passes a member path: as everywhere else, + that reaches the model accessor's dynamic exit and the body's reads bind at render. - **Both backends.** Region defaults **and** overridden fills precompile natively under the source generator and render byte-identically to the dynamic engine. @@ -983,7 +1015,8 @@ inline body attached to a call. ``` Because the body is itself a full template, subtemplates may contain text, output blocks, -nested definitions, imports, and raw blocks — to any depth. A call hands its subtemplate to +nested definitions, imports, and raw blocks — nested as deeply as you like within the compiler's +depth limit (see [Imports](#imports---)). A call hands its subtemplate to its extension; `@list(Articles){{ … }}`, for instance, renders its body once per element with the element as the current model: @@ -1080,6 +1113,13 @@ The path between `{{ }}` is resolved relative to `TemplateOptions.RootPath` (an wins, per `Path.Combine`). The path is taken **verbatim** — no trimming — so keep the braces tight (`@<<{{layout.heddle}}`); a stray space inside becomes part of the filename. +An import path is **not** a template key, and the key idioms do not apply to it: write the +extension (`@<<{{lib.heddle}}`, not `@<<{{lib}}`), and do not spell it `~/lib.heddle` or +`/lib.heddle` expecting "from the root" — `Path.Combine` reads the first as a literal `~` +directory and the second as an absolute path. `.` and `..` segments *are* reduced, because +`Path.GetFullPath` reduces them. The precompiler refuses the spellings the key grammar would +rename, so a template that resolves on one tier resolves on both. + **`@<<{{ path }}` — the composition import.** Handled at parse time by dedicated `@<<` syntax ([HeddleMainListener.ExitImport_block](../src/Heddle/Language/HeddleMainListener.cs)). It parses the referenced file, **merges its definitions** into the current document (callable after the @@ -1092,6 +1132,52 @@ level** of a document — nesting it inside a subtemplate (an `@if`/`@for` body, a definition body) is a compile error (**`HED4004`**), because composition merges definitions and re‑bases chains into the document as a whole and has no well‑defined meaning at a nested scope. +An import that names a file the engine cannot read — not there yet, renamed, or a path the platform +rejects — is a compile error (**`HED4009`**) positioned at the `@<<` directive, naming the read +failure; that import is skipped and the rest of the document still compiles. This is the ordinary +state of a document being edited, which is why it is a diagnostic rather than a thrown error: an +editor analysing the buffer keeps reporting everything else about it. + +Imports may nest, and two branches may import the same library. What they may not do is form a +**cycle** — an import that reaches a document already being imported. That is a compile error +(**`HED4006`**) naming the chain that closes it; the repeated import is skipped and the rest of the +document still compiles. + +Depth has a limit in the same spirit. Nesting beyond what the compiler can carry is a compile error +(**`HED4007`**) rather than something that exhausts its stack, and the limit is a fixed count rather than +a measurement of available memory, so a template behaves the same on every host. Two bounds apply: + +- **Parse nesting — 300 levels**, counted in grammar rules rather than in constructs you can see. A block + such as `@if(...){{ … }}` costs about three, so roughly a hundred nested blocks reach it; a chain of + operators in one expression costs one each. The figure is set against the smallest stack the engine can + be hosted on — a 1 MB thread, which is the Windows and thread-pool default — rather than the largest, so + that it is reached before the stack is. It remains far above hand-written templates, where a few dozen + levels of nesting is already unusual. +- **`@<<` import nesting — 64 levels.** Imports are counted separately because each one parses another + document in place. This bounds the depth of a chain, not how many imports a document may have: a file + with hundreds of sibling imports is unaffected. +- **`@<<` imports expanded — 1024 in total, per document compiled.** Depth is not the only way an import + graph grows. Each repeat of an import is parsed again — that is what lets it contribute its output at + each position — so a file imported from two places in a document that is itself imported from two + places multiplies out: sixteen such levels are acyclic, well inside the depth limit, and expand to a + hundred thousand parses. Past the total, the remaining imports are skipped and a compile error + (**`HED4008`**) says so once. Ordinary composition is nowhere near it; reaching it means a library is + being pulled in along many paths at once, and naming it in one place fixes the multiplication. + +The same bounds apply at build time in the source generator, where an unbounded parse would take down the +compiler rather than fail the build. + +**Why the limit is where it is.** Prefix operators (`!`, `-`, `+`, `~`) and the right-associative `?:` +and `??` are parsed by recursive descent, so each one costs a stack frame — far more stack per level than +a block does. The bound is set below where those shapes exhaust a 1 MB thread, which is the Windows and +thread-pool default, so it is reached first there. + +**Known limit.** That bound covers the parser's descent only. A long run of prefix operators also drives +ANTLR's *prediction* into deep recursion, which the counter cannot see — the rule depth is still in single +figures when the stack runs out — so a sufficiently long run terminates the process at any stack size. +This is upstream ([antlr/antlr4#744](https://github.com/antlr/antlr4/issues/744)) and no fixed count fixes +it. If you compile untrusted templates, put a size limit in front of the compiler. + **`@import(){{ path }}` — removed.** The old compile‑time include ([ImportExtension.cs](../src/Heddle/Extensions/Archived/ImportExtension.cs)) merged nothing into the importing document and had surprising, offset-dependent isolation semantics. It no longer @@ -1270,8 +1356,8 @@ slightly between a definition header and a body. For the full picture see [Output profiles](#output-profiles) and [Built‑in Extensions → Output profiles](built-in-extensions.md#output-profiles). - **Recursion is capped** by `TemplateOptions.MaxRecursionCount` (default 100). -- **Type mismatches and unknown members fail at compile time** (or, in `DEBUG`, when - `Generate` is given a model of the wrong type) — see +- **Type mismatches and unknown members fail at compile time** (or, when `Generate` is + given a model of the wrong type, with a `TemplateProcessingException` at render) — see [error handling](csharp-api.md#errors-and-diagnostics). Continue to the **[Built‑in Extensions](built-in-extensions.md)** reference for the helpers diff --git a/docs/native-expressions.md b/docs/native-expressions.md index 72ac2170..27f3228f 100644 --- a/docs/native-expressions.md +++ b/docs/native-expressions.md @@ -38,9 +38,9 @@ C# precedence, verbatim. Highest to lowest: | unary | `!` `-` `+` `~` | right | `Not`, `Negate`, `UnaryPlus`, `OnesComplement` | | multiplicative | `*` `/` `%` | left | | | additive | `+` `-` | left | `+` is string concatenation when an operand is a string | -| shift | `<<` `>>` | left | integral left operand; `int` right operand | -| relational | `<` `<=` `>` `>=` | left | null operands compare `false` (lifted, non‑null result) | -| equality | `==` `!=` | left | `object.Equals` fallback for unrelated reference/mixed types | +| shift | `<<` `>>` | left | integral left operand; **any** integral right operand, converted to `int` (a [deviation](#deviations-from-c)) | +| relational | `<` `<=` `>` `>=` | left | a `null`‑*valued* `Nullable` compares `false` (lifted, non‑null result); the `null` **literal** is `HED1008` | +| equality | `==` `!=` | left | `object.Equals` fallback when **both** operands are reference types or `Nullable`; a reference/value mix is `HED1008` | | bitwise AND | `&` | left | ints, same‑enum, and `bool` | | bitwise XOR | `^` | left | | | bitwise OR | `\|` | left | | @@ -59,8 +59,24 @@ signed operand becomes `long`) → `uint` → `int`. Mixing `decimal` with `floa ### Lifted (nullable) operands When either operand is `Nullable`, arithmetic and bitwise operators produce a nullable result -(`null` in → `null` out). Relational and equality operators produce a plain `bool`: any `null` -operand compares `false`, and `null == null` is `true` — exactly as C#. +(`null` in → `null` out). Relational and equality operators produce a plain `bool`: a `null` operand +compares `false`, and `null == null` is a constant `true`. + +**Lifting is numeric-path only.** A mixed-nullability pair of a *non-numeric* type does not lift, so +where C# has a lifted operator this tier has none: + +| Expression | C# | Here | +| --- | --- | --- | +| `@(FlagNullable == Flag)` (`bool?` vs `bool`) | lifted, compiles | `HED1008` | +| `@(FlagNullable & Flag)` (`bool?` vs `bool`) | lifted, compiles | `HED1008` | +| `@(N < 3)` (`int?` vs `int`) | lifted, compiles | lifted, compiles | + +Both tiers agree on refusing the bitwise row with the same positioned id — the bool arm of the +bitwise visitor guards mismatched nullability explicitly, and `NativeOperatorRules.ClassifyBitwise` +carries the same verdict at build time. + +The `null` **literal** is separate from a `null`-valued `Nullable`: `@(x < null)` and +`@(3 == null)` are `HED1008`, exactly as C# rejects them. ### Why there is no `?.` @@ -120,8 +136,9 @@ nothing else is. There is no path from template text to arbitrary methods by nam ### The default built‑ins -All are invariant‑culture and never throw at render (string‑returning ones map `null` input to -`""`): +All are invariant‑culture, and all but `range` never throw at render (string‑returning ones map +`null` input to `""`). `range` is the one sanctioned exception: a non‑positive step known only at +render throws, because the alternative is a loop that never terminates — see [`range`](#range). | Function | Behavior | | --- | --- | @@ -134,7 +151,8 @@ All are invariant‑culture and never throw at render (string‑returning ones m | `format(value, fmt)` | `IFormattable.ToString(fmt, InvariantCulture)` | | `format(fmt, args…)` | composite `string.Format(InvariantCulture, …)` | | `str(value)` | invariant `Convert.ToString` | -| `abs`, `min`, `max`, `round`, `floor`, `ceil` | over `int`/`long`/`double`/`decimal` as applicable; clamped, non‑throwing | +| `abs`, `min`, `max` | `int`, `long`, `double`, `decimal` (one overload per type); clamped, non‑throwing | +| `round`, `floor`, `ceil` | `int`, `long`, `double`, `decimal` (as `abs`/`min`/`max`); `round` also takes a digit count. The integral overloads are the identity | | `range(start, last[, step])` | builds a `Heddle.Models.Range` for `@for` — iterates `start … last‑1` by `step` (default 1) | @@ -164,10 +182,26 @@ var options = new TemplateOptions { Functions = functions }; - Names are ordinal and case‑sensitive. - Registering the same name with identical parameter types **replaces**; otherwise it adds an - overload. Overload resolution ranks exact match over widening over boxing to `object`. -- The registry **freezes on first compile use**; registering afterwards throws - `InvalidOperationException`. Frozen registries are immutable and safe for concurrent compiles and - renders. + overload. Overload resolution ranks each candidate on a flat scale — exact match over implicit + widening over boxing to `object` — and refuses when two candidates tie, rather than applying C#'s + better‑conversion‑target rule. Both tiers share one ranker, so a call that binds at build time + binds identically at run time and a tie is `HED1013` on both. + The consequence is narrower acceptance than C#, not a different winner: measured over the shipped + built‑in table, **0 of 480** argument combinations would change which overload wins under C#'s rule, + **100** would become bindable that are ties today, and **38** stay ambiguous either way (`double` + and `decimal` are mutually non‑convertible, so neither is closer). Adopting C#'s rule would *widen* + what compiles, which cannot be withdrawn later, so it is a **window‑gated** change rather than a fix + to make casually. + Note that betterness is not what makes an integral argument bind to `floor`/`ceil`/`round`: with only + a `double` and a `decimal` overload the two are mutually non‑convertible, so C# reports the tie too — + `Math.Floor(3)` is `CS0121`. What binds `floor(3)` is that those three carry an `int` and a `long` + overload, exactly as `abs`/`min`/`max` do. +- The registry **freezes when a native expression is first compiled against it** — not when a + template is merely compiled, so a template containing no native expression leaves it open. + Registering after the freeze throws `InvalidOperationException`. Frozen registries are immutable + and safe for concurrent compiles and renders, which is why the freeze exists. + Registration order therefore matters: register everything before the first render, not lazily on + demand. - `null` `TemplateOptions.Functions` means `FunctionRegistry.Default` (the frozen built‑ins). ### Standalone vs. in‑expression calls @@ -195,23 +229,87 @@ returns whether the mode is `FullCSharp`. It is retained for compatibility and m Native expressions match C# except for a small, deliberate set of ergonomic choices: -1. `==`/`!=` on unrelated reference/mixed types compiles to a total, null‑safe `object.Equals` - instead of a compile error. +1. `==`/`!=` on **unrelated reference types** compiles to a total, null‑safe `object.Equals` + instead of a compile error — `@(Maker == Where)` renders `False` rather than failing to compile. + The fallback requires **both** operands to be a reference type or `Nullable`; a + reference/value mix such as `@(Name == Count)` is a positioned `HED1008` on **both** tiers, which + is what `NativeExpressionCompiler`'s `IsReferenceish(left) && IsReferenceish(right)` guard decides + and what `OperatorGuardDifferentialTests.MixedTypeEquality_CompilesTheConsumerProject_AndDegrades` + pins. **Do not widen the guard to match a looser reading of this rule:** doing so turns a compile + error into a silent `false`, which is a breaking change and window‑gated. + On the precompiled tier this deviation emits through `Heddle.Precompiled.RuntimeOperators`, whose + generic entry points replay the engine's own fallback chain over the call site's static types — + a user operator where the pair binds one, null‑safe `object.Equals` otherwise — cached per type + pair, so the two tiers keep one verdict byte for byte instead of the template degrading. 2. `.` hops (and indexer targets) are null‑safe, yielding `default(T)`. 3. `-2147483648` types as `long` (first‑fit literal typing, without C#'s lexer special case); the value is identical. 4. Enum arithmetic (`enum + int`) is not supported. 5. The `enum & 0`‑literal special case is not carried over. -6. User‑defined *operators* are honored (e.g. `DateTime`/`TimeSpan`), but user‑defined *implicit - conversions* are not consulted during promotion or arm unification. +6. User‑defined *operators* are honored for **arithmetic, relational, equality and `??`** (e.g. + `DateTime`/`TimeSpan`), and **not at all** for `&`/`^`/`|`, `<<`/`>>`, or any unary operator — + those arms refuse a non‑numeric, non‑`bool`, non‑enum operand before an operator method could be + found. User‑defined *implicit conversions* are never consulted, in any arm, during promotion or + arm unification. 7. `&&`/`||` reject `bool?` with a targeted error instead of C#'s wording. +8. `<<`/`>>` accept **any** integral right operand and convert it to `int`, so `@(I << L)` compiles + here and is `CS0019` in C#. **Do not narrow this to match C#:** it would break templates that + compile today, so it is window‑gated. +9. Mixed nullability does not lift outside the numeric paths — see + [Lifted (nullable) operands](#lifted-nullable-operands) for the two shapes and which of them is a + deviation and which is a defect. + +## Diagnostics + +Every diagnostic the native tier raises. All are **compile-time** and positioned at the offending +construct, so none of them can reach render. The build tier raises the same id for the same input — +that is the match requirement: wherever the generator can **prove** the refusal, `HED1003`, `HED1004`, +`HED1005`, `HED1007`, `HED1008`, `HED1009`, `HED1010`, `HED1011` and `HED1018` also fire at **build** +as errors forwarded from the generator, carrying the engine's own sentence at the `.heddle` position. +Where it cannot prove the refusal it degrades the call to the dynamic tier instead of guessing, and +the template meets the engine's verdict at runtime. + +| ID | Severity | Raised when | +| --- | --- | --- | +| `HED1001` | error | A function name matches neither the registry nor an extension/definition. | +| `HED1002` | error | An in‑expression call names an extension or definition rather than a registered function. Call it standalone, or register a function. | +| `HED1003` | error | Method‑call syntax (`x.Foo(...)`) appears in an expression. Only registered functions are callable. | +| `HED1004` | error | An operand is a dynamic scope, or a path crosses a `[Dynamic]` property. Declare a typed `@model`, or use the `@` C# tier. | +| `HED1005` | error | `&&`/`\|\|` applied to a non‑`bool` operand — including `bool?`, which C# would accept. | +| `HED1006` | error | `??` applied to a left operand that is a non‑nullable value type. | +| `HED1007` | error | The `?:` arms have no common type. Also raised for a `??` pair with no common type. | +| `HED1008` | error | A binary operator has no rule for its operand types — a reference/value equality mix, a promotion with no common type, enum arithmetic, a `null` literal in a relational position — or a numeric literal overflows its type. | +| `HED1009` | error | A unary operator is not defined for its operand type (`-` on `ulong` or a non‑numeric, `~` on a non‑integral, `!` on a non‑`bool`). | +| `HED1010` | error | An indexer target has no accessible indexer matching the argument types. | +| `HED1011` | error | The `?:` condition is not `bool`. | +| `HED1012` | error | No overload of a registered function binds to the supplied argument types. | +| `HED1013` | error | A registered‑function call is ambiguous — two candidates tie under the flat rank. `min(1, 2u)` is the canonical case; see [Registering your own](#registering-your-own). | +| `HED1014` | error | An expression beyond a bare member path is used while `ExpressionMode` is `MemberPathsOnly`. | +| `HED1015` | error | A composite `format` literal references an argument index beyond the supplied count. | +| `HED1016` | warning | A standalone `@name(...)` resolved to an extension that shadows a registered function of the same name. Write `@( name(...) )` to reach the function. | +| `HED1017` | error | A standalone registry hit was given a chain or C#‑parameter shape rather than a single expression. | +| `HED1018` | error | An integral or `decimal` `/` or `%` over **constant** operands whose divisor is zero — `@(1/0)`, `@(1%(1&0))`, `@(1.0m/0m)`. Rendering could only throw `DivideByZeroException`, so the expression fails the compile instead, **on both tiers**: the engine raises it and the generator forwards the same id as a build error. Scoped exactly as C# scopes `CS0020` — floating‑point stays legal (`@(1.0/0)` renders `∞`), and a runtime divisor that happens to be zero still throws at render. | + +A member‑path segment that fails resolution is **`HED0001`**, not a `HED1xxx`: the member tier is +shared with the C# tier and the dynamic path, so its diagnostic is shared too. It fires when a segment +is missing, non‑readable, `[Hidden]`, or has an inaccessible getter — see +[Exposing models to untrusted templates](patterns.md#exposing-models-to-untrusted-templates). + +An expression that faults the compiler itself for a reason no other diagnostic covers is +**`HED0005`**, the compile‑item catch‑all — positioned at the call and carrying the exception. The +canonical case is a member path *ending on* a `ref struct` (an expression operand must box, and a +`ref struct` cannot): the engine refuses it at compile time on modern TFMs, and the build tier +degrades the same path so the reader gets this positioned id rather than a consumer‑build `CS0030`. +Reading *through* a `ref struct` to an ordinary member stays legal on both tiers. ## The sandbox The compiler can only ever emit invocations of: property/indexer getters that pass the member‑tier -visibility and `[Hidden]` filter; the `MethodInfo`s/delegates the host registered (built‑ins -included); compiler‑chosen intrinsics (`string.Concat`, static `object.Equals`, conversions); and -user‑defined operator methods declared by the operand types themselves. Method‑call syntax +visibility and `[Hidden]` filter; **array element access** (`Expression.ArrayIndex`, single- and +multi-dimensional), which invokes nothing but is an emitted access all the same; the +`MethodInfo`s/delegates the host registered (built‑ins included); compiler‑chosen intrinsics +(`string.Concat`, static `object.Equals`, conversions); and user‑defined operator methods declared by +the operand types themselves. Method‑call syntax (`x.Foo()`), unregistered names, dynamic‑scope operands, assignment, lambdas, `new`, casts, and `is`/`as` are all rejected at **compile time** with a positioned error — never executed. See the [built‑in extension parameter docs](built-in-extensions.md) for how `@if`/`@for` consume these @@ -220,3 +318,16 @@ expressions, and [csharp-api.md](csharp-api.md) for when to escalate to the `@` For host‑side guidance on exposing models safely — DTOs, `[Hidden]`, the registry freeze, render budgets, and encoding contexts — see [Exposing models to untrusted templates](patterns.md#exposing-models-to-untrusted-templates). + +--- + +*Verified against source at `6639f6f` (2026-07-26).* Claims marked ✓ are gated by a test: +the diagnostics table ✓ (`DiagnosticIdTests.EveryShippedIdIsNamedInAPublishedDocument` — every id +here is a shipped constant and this page is its registry-designated home); deviation 1's guard ✓ +(`OperatorGuardDifferentialTests.MixedTypeEquality_CompilesTheConsumerProject_AndDegrades`); the +operator legality table and the lifted-operand shapes ✓ (`NativeOperatorRulesTests`, which drives the +shared rule core both tiers use); the overload-rank measurement ✓ +(`OverloadBetternessEvaluationTests`). Everything else on this page is dated-verified, not gated — +which matters: an unmarked claim is **evidence of intent, not an authority**, so a contradiction +between it and both tiers agreeing is investigated and recorded, never resolved by editing code to +match the sentence. diff --git a/docs/precompilation.md b/docs/precompilation.md index 09d70582..188ef58b 100644 --- a/docs/precompilation.md +++ b/docs/precompilation.md @@ -11,7 +11,11 @@ Pre‑compilation is **purely additive and opt‑in**. The runtime stays fully d runtime‑loaded template strings, `:: dynamic`, `AllowCSharp`/`ExpressionMode.FullCSharp` runtime compilation, and hot reload all keep working, and precompiled and runtime‑compiled templates coexist in one -process. The precompiled assembly is a *cache seeded at build time*, never a cage. +process. The precompiled assembly is a *cache seeded at build time*, never a cage. A template the +build cannot fully bind renders through the dynamic tier instead of failing, and a single *call* the +build cannot bind costs that call rather than the file — see +[What precompiles, and what falls back](#what-precompiles-and-what-falls-back) for where those two +lines now run. > The generated backend must produce **byte‑identical** output to the runtime backend — a > differential test harness proves it across the whole fixture corpus in CI. The runtime @@ -21,8 +25,10 @@ process. The precompiled assembly is a *cache seeded at build time*, never a cag ## Setup -Add the generator package (it ships the emitter in `analyzers/dotnet/cs`; the core `Heddle` -package stays runtime‑only and unrestricted): +Add the generator package (it ships one emitter build per Roslyn generation under +`analyzers/dotnet/roslyn{4.1,4.11,5.3}/cs` — a versioning‑aware host loads the newest folder its +compiler can bind, and older hosts are trimmed to the 4.1 floor by the package targets; the core +`Heddle` package stays runtime‑only and unrestricted): ```xml @@ -32,42 +38,135 @@ package stays runtime‑only and unrestricted): ``` By default every `**/*.heddle` file in the project (excluding `bin`/`obj`) is picked up as a -template. Opt individual files out, or add extra ones, with the `HeddleTemplate` item. The -only item metadata the generator reads is `Key`, which sets both the lookup key **and** the -generated class name (via `SanitizeName`); to exclude a file, `Remove` it (or disable the -default glob and include explicitly): +template. Opt individual files out, or add extra ones, with the `HeddleTemplate` item. Four item +metadata are read: + +| Metadata | Effect | +| --- | --- | +| `Key` | The item's explicit **registration key**, replacing the path‑derived one. It sets both the lookup key **and** the generated class name (via `SanitizeName`), and it is the remedy for a template outside `HeddleTemplateRoot` — an explicit key suppresses `HED7018`, because the flattened key is then what you asked for. It normalizes through the shared key rule and takes part in `HED7002`/`HED7003`. A value the normalizer refuses is `HED7004`. | +| `Name` | An **additional** name the template answers to — *not* a rename. The template keeps its key (path‑derived, or `Key`) **and** answers to the name, so both spellings resolve and nothing that resolved before stops resolving. It works at **both tiers**: the `@<<` import map at build time, and the precompiled registry at run time (the manifest row carries it, so `TryGet`/`TryResolve` find the same template by either spelling). It does not touch the key, the generated class name, the `#line` file or `HED7018`, and it takes no part in `HED7002`/`HED7003`, which are about keys. Where a spelling names one template's key and another's name, **the key wins** — a name is an addition and never displaces an existing spelling. Setting `Key` *and* `Name` is two names for one template, not a conflict. Importing a named template by its key resolves and warns (`HED7028`); a name the normalizer refuses, or one another template in the same build already answers to, is `HED7004` against the name — the key is unaffected. Across assemblies the same collision is `HED7104` at registration. | +| `ModelType` | The template's **model type**, declared from the project file instead of an in‑file `@model` directive. A template with neither is untyped; the metadata gives it the same typed emission the directive gives — the typed `Generate(...)` entry‑point signature, native member paths, `this` — without a directive in the template text. The spelling resolves exactly as the directive's does (the template's `@using` imports apply, and an unresolvable or ambiguous spelling reports the same way: `HED7007`/`HED7023`). The directive wins nothing — **agreement is required**: when both are present they must name the same resolved type, and a disagreement is the `HED7032` build error. Equal spellings, or two spellings resolving to the same type, are fine. | +| `Precompile` | `false` opts the file out of pre‑compilation: no entry point, no manifest entry — but it **stays available to `@<<` imports**, which `Remove` cannot do. Absent or any other value means "precompile". This pairs naturally with `Name`: an import‑only partial under a friendly name. Its `Key`/`Name` are validated and its own imports advised like any other item's, even though it emits nothing; note that with no manifest row, an opted‑out template's `Name` is a **build‑time** import spelling only — there is no registry entry for the runtime to answer with. | ```xml - - + + + + + + + + false ``` +A template whose path is **not** under `HeddleTemplateRoot` and that carries no explicit `Key` +registers under its bare filename — the directory is dropped — and the build reports `HED7018` +naming the file, the root, and the flattened key it used. + +### Assemblies the build must see + +A `@model` spelling is resolved at **compile** time by both tiers, so both tiers have to be able to see the +assembly it names — and neither finds it by magic. The engine [loads nothing on its own](csharp-api.md#registration-register) +and takes an assembly only by registration; the generator resolves over the **compilation's reference closure** +and loads nothing either. The two questions have one answer: + +```csharp +// in the consuming project — ONE declaration, read by both tiers +[assembly: Heddle.Attributes.HeddleModelAssembly(typeof(Acme.Models.Invoice))] +``` + +The `typeof` is the point. You cannot spell a type in a project that does not reference its assembly, so +"referenced at build, registered at run" stops being a rule your project can quietly violate and becomes +**CS0246 in your own source**. There is no `HED` id for a missing reference because the C# compiler already +owns that diagnostic. The reference then reaches the compiler, the generator indexes it with everything else the +compilation references, and `HeddleTemplate.Register` reads the same attribute at startup and registers the +assembly for engine type resolution. One declaration, both tiers, no way to configure one and forget the other. + +**The escape hatch, for projects that cannot carry a `typeof`** — a templates-only project that must not take a +source dependency, or a model assembly with no compile-time-nameable public type: + +```xml + + + + +``` + +The targets append `@(HeddleModelAssembly)` and `@(HeddleExtensionAssembly)` to `@(ReferencePath)`, so the item's +job is to reach the **compiler** — not the generator. An item carries an obligation the attribute discharges for +you: **it configures the build only**, so the host still makes its own `HeddleTemplate.Register` call, and, not +being an ordinary reference, the file is absent from the deps file and deployment still has to put it where the +process can load it. + +> **Configuration is an input, not a discovery.** The item deliberately does not name a path for the generator to +> read. Build output has to be a function of the compilation's declared inputs — a generator that opened files +> mid-build would make the output depend on when it looked, and would break incrementality, which is why there is +> no `CompilerVisibleItem` here and none is needed. Routing through `@(ReferencePath)` means MSBuild's own +> `ResolveAssemblyReferences` stays the loader and `SymbolTypeIndex` indexes the result with zero extra machinery. +> For the same reason **assembly configuration is not part of the options fingerprint**: it changes *whether* a +> template precompiles, never a rendered byte, so adding or removing a declaration can never produce an +> `OptionsMismatch` and never changes what a template renders. + +Two consequences worth stating plainly: + +- **Assembly configuration adds nothing to the run-tier fallback taxonomy.** No new `PrecompiledFallbackReason`, no new `HED` id. + Configuring the build can move a template from "degraded at build" to "precompiled"; it cannot invent a way for + a registered template to fail at run time that did not already exist. +- **Ambiguity that configuration creates is not a regression.** Making a second assembly visible that declares the + same type spelling is `HED7023` at build — and a runtime with both assemblies registered raises its own + "the type name is ambigous" error for the same input. The tiers agree in the failure, which is the same + agreement they have in the success. + +What this does *not* reach: types that do not exist at build time (`TypeBuilder`, scripting hosts); collectible or +reloadable model contexts, which have deliberately **no** build-time twin — baking one generation of a reloadable +type into IL that the next reload invalidates is worse than degrading; types your compilation may not *name* +(`HED7030` — the remedy is `[InternalsVisibleTo]`, not a Heddle setting); `@model dynamic`; assembly-qualified +spellings whose version a reference does not carry; and registration that is imperative by nature +(`TemplateFactory.AddExtensions` over live `Type`s, `FunctionRegistry.Register` over a delegate). + ## Compile options (MSBuild properties) These mirror `TemplateOptions` and are baked into the generated artifact; a mismatch against the runtime request is caught by the validation gauntlet (below). An unparsable value is a build error (`HED7009`). The generator defaults track the engine defaults (both flipped in 2.0), -so an unset property produces the same options fingerprint as a default‑options runtime request -— an unset property never causes a gauntlet mismatch. - -| Property | Values / default | Effect | -| --- | --- | --- | -| `HeddleOutputProfile` | `Html` (default) \| `Text` | Output encoding profile (part of the options fingerprint). | -| `HeddleExpressionMode` | `MemberPathsOnly` \| `Native` (default) \| `FullCSharp` | Expression tier. `FullCSharp` is the build‑time equivalent of `AllowCSharp`. | -| `HeddleTrimDirectiveLines` | `true` (default) \| `false` | Trim directive‑only lines (part of the fingerprint). | -| `HeddleMaxRecursionCount` | positive int, default `100` | Definition‑carrier recursion limit, baked at build. | -| `HeddleTemplateRoot` | dir, default `$(MSBuildProjectDirectory)` | Root the template key is made relative to. | -| `HeddleGeneratedNamespace` | default `Heddle.Generated` | Namespace of the generated entry classes. | -| `HeddleEmitUtf8Pieces` | `false` (default) \| `true` | Emit pre‑encoded `"…"u8` static pieces for the byte sink. | +so an unset property produces the same options fingerprint as a **default‑options** runtime request. +It does not follow that an unset property is always safe: the fingerprint compares what the build +baked against what the request carries, so a host that sets a non‑default `OutputProfile`, +`ExpressionMode` or `TrimDirectiveLines` at run time while the build left the property unset gets an +`OptionsMismatch` and a per‑request degrade. Set the property to match the host, or leave both at +their defaults. + +The **runtime counterpart** column is the option the request has to carry to match. Where it says *(build only)* +there is nothing to match: the property decides how the artifact is emitted, not what a render produces. + +| Property | Values / default | Runtime counterpart | Effect | +| --- | --- | --- | --- | +| `HeddleOutputProfile` | `Html` (default) \| `Text` | `TemplateOptions.OutputProfile` | Output encoding profile (part of the options fingerprint). | +| `HeddleExpressionMode` | `MemberPathsOnly` \| `Native` (default) \| `FullCSharp` | `TemplateOptions.ExpressionMode` | Expression tier. `FullCSharp` is the build‑time equivalent of `AllowCSharp`. | +| `HeddleTrimDirectiveLines` | `true` (default) \| `false` | `TemplateOptions.TrimDirectiveLines` | Trim directive‑only lines (part of the fingerprint). | +| `HeddleMaxRecursionCount` | positive int, default `100` | `TemplateOptions.MaxRecursionCount` | Definition‑carrier recursion limit, baked at build. | +| `HeddleTemplateRoot` | dir, default `$(MSBuildProjectDirectory)` | `TemplateOptions.RootPath` | Root the template key is made relative to. | +| `HeddleGeneratedNamespace` | default `Heddle.Generated` | *(build only)* | Namespace of the generated entry classes. | +| `HeddleEmitUtf8Pieces` | `false` (default) \| `true` | *(build only)* | Emit pre‑encoded `"…"u8` static pieces for the byte sink. | +| `HeddleNodeFallback` | `true` (default) \| `false` | *(build only)* | Per‑node fallback: a member path the engine resolves but generated C# cannot **name** (e.g. a referenced assembly's `internal` member without `[InternalsVisibleTo]`) is computed by the engine's own accessor instead of degrading the whole template. Never changes rendered bytes, so it is not part of the options fingerprint; `false` restores the whole‑template degrade **for the nodes it governs**. Its scope is exactly the naming question: it decides between spelling a member in generated C# and computing it through the engine, so it does **not** reach a type‑agnostic body, where the model type is unresolved and nothing could have been spelled in the first place — those reads bind through the same accessors either way, and the body precompiles either way. | +| `HeddleObserveEngine` | `Auto` (default) \| `Off` \| `Strict` | *(build only)* | Whether the build **observes a real engine compile** of each template before emitting it, to learn the model type an extension's hook chooses for its body. A body it types is emitted with a direct cast; a body it cannot type is still precompiled, through the engine's own accessors — so this changes which tier a *read* takes and never a rendered byte, and it is not part of the options fingerprint. `Auto` reports `HED7034` as a note when it cannot observe; `Strict` makes that an error, so a CI leg never silently emits different sources from a developer machine that can observe; `Off` never tries. The intermediate assemblies it writes live under `obj/…/heddle/observe/`, are named after a digest of their own content, and are removed by `Clean`. Nothing is written at all unless a template actually contains a body the build cannot type on its own. Observation needs the **implementation** of your engine and extension assemblies. A package reference names one directly; for a project‑to‑project reference the compiler holds only a reference assembly, so the targets declare the implementation behind it in `HeddleObserveImplementationPath` and observation loads that, matched by assembly identity. A reference with no implementation on record is emitted type‑agnostically under `HED7034`. | + +The same mapping is what the editor uses: each of the first five has a `.heddle-lsp.json` key spelled as the +camelCased **runtime** name (`outputProfile`, `expressionMode`, …), so the three tiers name one option three ways +and mean the same thing. See [editor‑support.md](editor-support.md#configuring). + +Assembly configuration is deliberately **not** in this table — it is not an option, it is a reference. See +[Assemblies the build must see](#assemblies-the-build-must-see). --- @@ -85,6 +184,13 @@ The signature is `Generate(TModel model, object chained = null, object callerDat where `TModel` is the declared `@model` type (`object` for `:: dynamic` **and for a model‑less template** — the generator always emits an `object model` parameter). +> **This path runs no validation gauntlet, and it has no fallback either.** A typed entry point calls +> `PrecompiledRuntime.GenerateString` directly: it never looks the template up, so it never reaches the +> gauntlet, so an extension or function binding that drifted between build and deployment is not +> detected and not degraded — it renders precompiled against the stale binding. That is the price of +> the fast path, and the remedy is the aggregate pass below: call +> [`PrecompiledTemplates.ValidateAll`](#validating-everything-once-after-configuration) once at startup. + ## The registry — for dynamic call sites Templates identified by a runtime value (a path, a database key) resolve through the registry @@ -94,19 +200,76 @@ instead. Registration is repeatable and idempotent per assembly: using Heddle.Precompiled; PrecompiledTemplates.Register(typeof(MyApp.Program).Assembly); // once per assembly -// Register(assembly) is the only registration path — HeddleTemplate.Configure(assembly) -// discovers extensions but does NOT register precompiled templates. +// Register(assembly) is the only registration path. HeddleTemplate.Register(assembly) is the +// separate call for extensions, and does NOT register precompiled templates. // Discovery is a first-class, public API — keys, model types, fingerprints, capabilities: foreach (var entry in PrecompiledTemplates.Entries) Console.WriteLine($"{entry.Key} model={entry.ModelType} precompiled={entry.IsPrecompiled}"); ``` -For direct (`TemplatePathType.None`) lookups, `TemplateResolver.GetTemplate` consults the -registry **before** the dynamic cache and file check; hosted view/partial‑view search paths -stay fully dynamic and do not consult the registry. On a hit it runs the per‑request -validation gauntlet; all pass → a `HeddleTemplate` in -precompiled‑adapter mode (zero parse, zero compile). A registry **miss** is never a failure — +### Lookup by key, and by registered name + +A lookup resolves **keys first, registered `Name`s second**. Both spellings reach the same entry, so +a template built with `Name="BuildReport"` is found by `BuildReport` and by its key, and the entry it +returns reports its **key** either way — the key is the identity the staleness check and every +diagnostic message are written against. A name is not a registry *entry*: `Entries` does not +double‑count it. + +The order is a decision, not an accident. Where a spelling names one template's key and another's +registered name, the **key owner wins**, whichever assembly registered first: a `Name` is an +*addition*, and an addition that displaced a spelling which already resolved would be a rename by the +back door. The losing name is simply not registered (or, if a key claims its spelling later, it stops +being registered), and the host hears about it once through `OnFallback` as `HED7104` — +`PrecompiledFallbackReason.RegisteredNameUnavailable`. Nothing throws, and the template whose name lost +stays fully reachable by its key. Contrast a duplicate **key**, which does throw +`PrecompiledRegistrationException`: two templates claiming one registration has no resolvable answer, +while a name/key collision already has one. + +`HED7104` also covers a manifest `Name` the shared key rule refuses outright — a `..` segment, a +trailing separator, whitespace. The generator cannot emit one (that is `HED7004` at build time), so the +population is manifests no build tier vetted: hand‑written, third‑party, or emitted by a tool that +skipped the rule. It is reported rather than dropped in silence, through the same reason and id as a +collision, because from the host's side the outcome is identical — a name it expected to resolve does +not, and the template is still reachable by its key. + +### What a fallback event names + +`PrecompiledFallbackEvent` carries **two carriers and populates exactly one**: + +| Carrier | Populated for | Reasons | +| --- | --- | --- | +| `TemplateKey` | a per‑request event, which is about one resolved template | `UnsupportedFunction`, `OptionsMismatch`, `ModelTypeMismatch`, `ExtensionBindingMismatch`, `FunctionBindingMismatch`, `StaleContent`, `StaleImport`, `CaseMismatch` | +| `AssemblyName` | a registration‑time event, which is about an assembly and has no one template to name | `SchemaVersionUnsupported`, `EngineVersionIncompatible`, `RegisteredNameUnavailable` | + +Branch on the carrier, not on the reason. The 2.0 event had a single `Key` property holding either +meaning, so a host had to re‑derive from `Reason` which of the two it had; that property is **removed in +2.1** rather than narrowed, so the change surfaces as a compile error at the reading site instead of a +null at run time. Events are constructed through `PrecompiledFallbackEvent.ForTemplate` / +`ForAssembly`, each of which refuses a reason belonging to the other carrier — the mapping above is +enforced, not documented. + +Name lookup is ordinal, exactly as key lookup is, so a case‑sloppy spelling misses rather than serving +the wrong template. + +**Every** resolver arm consults the registry. For direct (`TemplatePathType.None`) lookups +`TemplateResolver.GetTemplate` consults it before the dynamic cache and file check; for the +hosted `View`/`PartialView`/`Master` arms the search ladder is three tiers — **registry, then +cache, then disk**, each walked in search‑location order — so a candidate location whose +root‑relative path maps onto a registered key is served precompiled instead of compiled. Tier +order beats location order, which is how the cache tier has always behaved (a cached template at +the second location already won over a first‑location file on disk). + +The hosted arms' candidate locations (`views/{controller}/{view}` and its `partial`/`base` +siblings) are root‑relative and `/`‑separated, joined to the resolver's root with +`Path.Combine`. They were previously written with backslashes and a leading separator, which is a +path shape only Windows reads — and there only from the current drive's root — so on Linux and +macOS the disk tier of the ladder matched nothing and those arms served registry hits only. + +On a hit the per‑request validation gauntlet runs against the arm's *real* effective options — +including the hosted arms' `ExpressionMode.FullCSharp`, so a manifest built under `Native` is +refused by the fingerprint check with no special‑casing anywhere. All pass → a `HeddleTemplate` +in precompiled‑adapter mode (zero parse, zero compile). A registry **miss** is never a failure — the dynamic path proceeds untouched. ## The validation gauntlet and mismatch policy @@ -115,6 +278,13 @@ Before trusting a precompiled entry the resolver checks it is compatible with th - **Options fingerprint** — `(OutputProfile, ExpressionMode, TrimDirectiveLines)`. A template compiled under `Text` is not a valid answer for an `Html` request. +- **Model type** — only for an entry whose model type is *ambient* + (`PrecompiledTemplateInfo.ModelTypeIsAmbient`), meaning the template declares no `@model` and the build + chose the type: the `ModelType` item metadatum, else `object`. The engine types such a template from the + requesting `CompileContext` instead, so the two answers have to be the same type or the entry is not an + answer to this request. A template that declares `@model` is typed by its directive on both tiers and + this step does not look at the request at all — the *value* is still checked at render, where a model the + entry's `ModelType` cannot hold raises the dynamic tier's own `TemplateProcessingException`. - **Extension bindings** — the `[ExtensionName]` extensions the template bound at build vs. the live registry (catches `[ExtensionReplace]` overrides). Default match is assembly‑qualified type name *without* version; supply your own via @@ -138,6 +308,113 @@ On any failure, behavior is controlled by `TemplateOptions.PrecompiledMismatchPo An assembly whose manifest schema/engine version is incompatible is ignored wholesale (every template falls back), with one `HED7102` callback per manifest. +### Validating everything once, after configuration + +The gauntlet above runs **per request, and only on the dynamic call path** — typed entry points never +reach it. `PrecompiledTemplates.ValidateAll` runs the same checks over **every** registered entry at a +time of the host's choosing, and reports *all* the failures rather than the first: + +```csharp +// Once, after registration/extension/function configuration is complete and before serving: +var report = PrecompiledTemplates.ValidateAll(options); +if (!report.PassedForValidatedOptions) { + foreach (var failure in report.Failures) // ordered by template key + log.Warn("{0}: {1} — {2}", failure.TemplateKey, failure.Reason, failure.Detail); + // Your call what a failure costs: log it, or refuse to start. +} +``` + +Each failure is an ordinary `PrecompiledFallbackEvent` carrying the same reason, `Detail` and +`HED7101` id the per‑request gate produces, so existing logging handles it unchanged. + +**The model‑type step is skipped here**, and deliberately: it judges the requesting `CompileContext`'s +model type, which `TemplateOptions` does not carry and a pre‑render pass does not have. An entry with +`ModelTypeIsAmbient` set can therefore still fall back at a request this report passed. + +**It is a report, not a gate.** Nothing about per‑request behaviour changes: the gauntlet still runs +where it ran before. The pass does not raise `OnFallback` — nothing degraded, because no render +happened — and `PrecompiledMismatchPolicy.Strict` does not make it throw, because that policy polices +requests. What a failure costs is the caller's decision. + +**The verdict is scoped to the options you pass, and the report says so.** Four gauntlet inputs are +per‑request rather than per‑configuration: `OutputProfile`, `ExpressionMode` and `TrimDirectiveLines` +(the fingerprint), and the effective `Functions` registry. One pass can therefore only be complete for +one options shape, so the report records the shape it used and names its green property accordingly: + +| Member | Meaning | +| --- | --- | +| `PassedForValidatedOptions` | No entry failed **under the validated options**. Not an unscoped "is valid". | +| `Failures` | Every failing entry, ordered by template key (ordinal). | +| `EntriesChecked` | How many registered entries were examined — a snapshot of `Entries`, markers included. | +| `ValidatedFingerprint` | The `(OutputProfile, ExpressionMode, TrimDirectiveLines)` triple compared against — a snapshot, so mutating your `TemplateOptions` afterwards cannot make the report describe a shape it did not check. | +| `ValidatedFunctions` | The effective `FunctionRegistry`, by reference; `null` means the default‑registry shape. | +| `ValidatedStaleness` | Whether the staleness step ran (`EnableFileChangeCheck`). When false, the report says nothing about files changing on disk. | + +A host that renders under more than one shape — two output profiles, or a request‑scoped +`FunctionRegistry` — calls the pass once per shape. There is no parameterless overload, deliberately: a +verdict with no options to scope it could only be misread. + +A `UnsupportedFunction` failure is reported like any other. It arises two ways, and both are worth +hearing: a marker entry (`HED7014` — a call the build refused on purpose, which will never render +precompiled), and a **late‑bound** entry whose recorded function name the live registry does not know, +which is a real configuration gap between the build and the deployment. + +### The staleness identity + +`ContentHash` is the lowercase‑hex SHA‑256 of the template's **decoded text** re‑encoded as UTF‑8 +without a BOM — not of the file's raw bytes. Both tiers compute it the same way +(`Heddle.Precompiled.ContentHash.HashText`): the build hashes the text Roslyn decoded, and the +staleness check decodes the file (honoring and stripping a BOM; no BOM means UTF‑8) before +hashing. An **encoding‑only** re‑save — adding a BOM, switching to UTF‑16 — therefore does not +read as stale, because it does not change the compiled output; any character change still does. +A file with no BOM that is not valid UTF‑8 is outside this contract, and its verdict is +unspecified — it degrades safely to the dynamic path. + +### Deploying template files next to a precompiled assembly + +Staleness compares the manifest key against a file at `TemplateOptions.RootPath`, so under +`EnableFileChangeCheck` the deployed templates must mirror their **build‑time** root‑relative +layout: a template built at `$(HeddleTemplateRoot)/views/home.heddle` must be deployed at +`{RootPath}/views/home.heddle`. The two roots cannot see each other (the build does not know the +deployment layout), so a mismatch is not validated — it simply reads as `StaleContent` and takes +the byte‑identical dynamic path, with an `OnFallback` event naming the key. + +### Which fallbacks are legitimate + +Falling back is the right answer for *stale data and change tracking*, and a defect everywhere +else: silently rendering dynamically because the deployed assemblies disagree with what the build +saw hides a packaging bug behind identical output. The classification: + +| Reason | Class | Why | +| --- | --- | --- | +| `StaleContent` | legitimate fallback | The template changed on disk after the build — dynamic recompile is the correct semantics, and `EnableFileChangeCheck` exists to ask for exactly this tracking. | +| `StaleImport` | legitimate fallback | The same, one hop out: an import changed under an unchanged root template. | +| `UnsupportedFunction` | legitimate fallback *(marker)* / **must surface** *(late‑bound)* | Two causes under one reason. A marker entry is not a run‑time discovery at all — the build refused *on purpose* and warned `HED7014`. A **late‑bound** entry naming a function the live registry does not hold is the opposite: the build did its work and the deployment did not register what the template calls, so the fallback is hiding a configuration gap. The detail string separates them (`manifest= live=`). | +| `OptionsMismatch` | legitimate fallback | Options are per‑request degrees of freedom a host legitimately exercises; the same template served `Text` for mail and `Html` precompiled is a designed miss of the fingerprinted point, not a defect. | +| `ModelTypeMismatch` | legitimate fallback | The host typed its `CompileContext` differently from the build's assumption for a template that names no model of its own. Both types are legitimate — one is the deployment's, one is the build's — and only the dynamic tier can honour the deployment's. Precompiling for that host is a *build configuration* opportunity (`ModelType` item metadata), not a run‑time defect. | +| `ExtensionBindingMismatch` | **must surface** *(provisional)* | A residual mismatch means the deployed binding set genuinely differs from the one the build declared — rendering dynamically with *different bindings than the build recorded* is the hazard, not the cure. | +| `FunctionBindingMismatch` | **must surface** *(provisional)* | Declaring‑type/overload drift under the default registry signals assembly skew. A per‑request export registry (`options.Functions`) diverging by host choice is the one arguable sub‑case. | +| `SchemaVersionUnsupported` | **must surface** | A manifest outside the engine's schema window means the deployable pairs generator and engine packages out of contract — a packaging defect that today silently un‑precompiles an entire assembly. | +| `EngineVersionIncompatible` | **must surface** | The same argument for engine skew; whole‑assembly silent rejection is the worst place to be quiet. | +| `CaseMismatch` | informational | Never a gauntlet failure — a registry lookup miss is contractually never a failure; the `HED7103` event is a diagnostic aid. | +| `RegisteredNameUnavailable` | informational | Never a gauntlet failure and never a throw (`HED7104`): a registered `Name` is an *addition*, and an addition whose spelling is already taken — or that the key rule refuses outright — costs the addition and nothing more — the template stays registered under its key, so no resolution that worked before changes meaning. Unlike a duplicate key there is nothing unresolvable to refuse, because key precedence already decides which template the spelling means. | +| duplicate key at registration | already surfaces | `PrecompiledTemplates.Register` throws `PrecompiledRegistrationException` — the precedent that registration defects throw. | + +**Today's behavior is unchanged**: under the default `Fallback` policy every class marked *must +surface* degrades to the dynamic tier and reports it through `OnFallback`, and only `Strict` throws. +"Silent" here means silent to the *render* — the output is correct and nothing fails — not +unreported: a host that leaves `OnFallback` unset is what makes it silent. The two rows marked +*informational* do not degrade at all; they report an addition that was not available and leave the +template reachable by its key. Making the must‑surface +classes throw *by default* (with an explicit opt‑out policy for hosts that rely on silent +degrade) is a behavioral change: it is filed as a candidate for the next breaking window and does +not ship outside one. + +The build tier obeys the same principle already: an exception escaping the template emitter is a +defect, so it reds the build with a per‑template `HED7020` error naming the template and the +exception — the remaining templates and the manifest still emit — instead of being swallowed into +a silent degrade. + --- ## Functions in precompiled templates @@ -164,20 +441,295 @@ assemblies the host registers from — every `options.Functions.RegisterFrom(ass startup pairs with a build‑time reference to the same assembly; both read the same `[ExportFunctions]` metadata. -A function that *cannot* be expressed as an exported `public static` method (a -`Register(string, Delegate)` closure) is not representable in assembly metadata: the template -draws build warning `HED7014` and is left un‑precompiled (a fallback‑marker entry) — it -compiles dynamically at run time. Wrap the closure in an exported static method to precompile -it. +**Binding is static, and the build‑time inventory is the only scope that can be correct.** A +precompiled call is emitted as a direct call to the chosen method — nothing in `PrecompiledRuntime` +consults `options.Functions` at render, so precompiled code cannot resolve a function a host +registers at run time *at all*. That is why `HED7025` proves illegality against the overload set the +build can see (the shipped built‑in table plus every `[ExportFunctions]` method) rather than against +some wider one: there is no wider one for what precompiles. A host that registers extra overloads — +which can make an ambiguous set unambiguous, or an inapplicable set applicable — is handled at the +gate instead: the gauntlet's `FunctionBindings` check sees the divergence and the template renders +through the dynamic tier, where the host's registrations are live. The one case the gate cannot +rescue is a build **error**, since it fails before any tier is chosen; the escape hatch there is +`Precompile="false"` on the item, which skips key derivation and emit entirely while keeping the +template in the `@<<` import map. + +### Functions the build cannot see + +A function registered only at run time — a `Register(string, Delegate)` closure — is not representable +in assembly metadata, so the build cannot bind it. It does not have to: the **call's shape** is known +even where its target is not, so the call is emitted as a *late‑bound site* that resolves **once, at +first render**, through the engine's own overload ranker, and caches the bound delegate. The same +overload wins on both tiers by construction, and steady‑state renders cost one delegate call and no +allocation. + +Three consequences worth knowing: + +- **The manifest records the name with no target.** The gauntlet checks it per request and falls back + to the dynamic tier where the live registry cannot serve the name — unregistered, or registered as an + *extension*, whose render protocol a value site cannot reproduce. `ValidateAll(options)` reports both + before any render. +- **Failure is the engine's failure.** A name nothing registers, an ambiguous call, and a call no + overload accepts each raise the engine's own positioned error (`HED1001`, `HED1013`, `HED1012`) from + the precompiled tier too, rather than rendering something the engine would not. +- **The registry is part of the request.** A render under a different `TemplateOptions.Functions` + re‑binds, matching the dynamic tier, which compiles per options. + +`HED7014` still fires for the calls this cannot serve — chiefly an argument whose static type has no +build‑time answer (an argument that is itself a call to an unknown function), so no overload can be +selected against it. Exporting the function with `[ExportFunctions]` on a public static container binds +it at build time and avoids the first‑render work entirely. ## Custom extensions in precompiled templates Custom `[ExtensionName]` extensions bind **from the referenced assembly, never inlined** — a security or logic patch reaches precompiled templates by updating the package. See -[custom‑extensions.md](custom-extensions.md#precompiled-mode) for the requirements -(parameterless ctor; no reliance on runtime registry mutation; a `InitStart`/`CompleteInit` -override is refused as `HED7015` — **except** for a `[BranchRole]` custom branch extension, whose -`InitStart` override is its canonical shape and instead degrades quietly to the dynamic tier). +[custom‑extensions.md](custom-extensions.md#precompiled-mode) for the requirements (chiefly a +parameterless ctor and no reliance on runtime registry mutation). + +**A compile‑time hook is no longer a reason to fall back.** The build does not predict what +`InitStart`/`CompleteInit` does; it *runs* them. The generated static initializer constructs your +extension inside your own assembly and calls its real hook, supplying the already‑generated body instead +of compiling one — so a bodied call to a third‑party extension, and an extension that re‑types its body, +precompile in a **default build**, with no property to set and no name list to be on. Where the hook +chooses a model type the build could not resolve, the body is emitted with **no model cast** and its +member reads bind to the engine's own accessor once the hook has answered. + +**The type‑agnostic body costs nothing at render.** Each member read inside it is emitted as the path +only — a `PrecompiledLateAccessor` — and the delegate behind it is built the moment your hook answers, +over the **engine's own** member walk rather than over a type the build guessed. A read is then one +field read and one delegate call, the same as a directly emitted accessor field: no per‑render +allocation, no DLR, no runtime Roslyn. Deliberately not the DLR, in fact: its visibility policy and hop +rule are the *dynamic* tier's, and the engine types this read the way the typed tier does. + +Three shapes inside such a body still cannot be written without knowing that type — a computed native +expression (its result type depends on an operand type that does not exist yet, and the DLR's numeric +promotion is not the engine's), an embedded C# expression (its model parameter has to be *spelled*), and +a nested call whose own typing needs one. Each costs **that call site** and not the template: the call +renders by compiling its own source text at first render. + +The substitute states its own bound, and the build respects it. A fragment compiled as its own document +sees no enclosing definition, no ambient region fill scope and no active prop layout — so a body that +would need the substitute *and* reaches for one of those is not handed to it; the **template** goes to +the dynamic tier instead, where all three exist. That is the `HookBehavior` refusal below, and it is the +one place a hook still costs a file rather than a call. + +An extension whose compile‑time behaviour genuinely cannot survive this — chiefly one whose hook walks +the enclosing document through `InitContext.ParseContext` — says so with +`[PrecompileUnsupported("…")]`, and gets the same per‑call‑site treatment under `HED7033`. The +declaration is read on both sides: off the symbol at build, and off the **live type** at run, so an +extension package that adds it after your assembly was built still falls back rather than binding +through a seam its author has disowned. + +### Engine observation — a typing optimisation, never a degrade + +`HeddleObserveEngine` decides whether the build **observes a real engine compile** of your templates +before emitting them, purely so it can learn the model type a hook chooses and write a direct cast +instead of a type‑agnostic body. It changes which tier a *read* takes; it never changes a rendered +byte and never takes a template **off** the precompiled tier — it can only put one on. The whole corpus +is generated under `Off` and under `Strict`, and every entry class either build produces is rendered +and byte‑compared **against the dynamic engine's own output**, which is the contract both tiers owe. + +`Off` is a genuinely reduced mode rather than an equivalent one: a body's typing comes from the +observed compile and from nowhere else, so a build that does not observe types only what an attribute +declares. Such a body is emitted type‑agnostically and renders identically — a tier, never a byte. + +| Mode | What it does | +| --- | --- | +| `Auto` (default) | Observe where it can. Where it cannot, emit type‑agnostically and report `HED7034` **once per compilation** as a note. Nothing is reported when no template needed observing, or when no observe directory was configured at all. | +| `Strict` | The same, except that a failure to observe is a build **error**. This exists so a CI leg that cannot observe never silently emits *different sources* from a developer machine that can. | +| `Off` | Never try. Every body the build cannot type on its own is emitted type‑agnostically. | + +How it works: the generator emits the compilation it is being run inside to a **content‑addressed** +intermediate assembly, loads it together with your `Heddle.dll` and your extension assemblies, and +compiles the real template through the real engine — so a source‑declared model and a source‑declared +extension are real `Type`s rather than shims. + +Two honest limits: + +- **A project‑to‑project reference is observed through its implementation, not its reference assembly.** + The compiler is handed a *reference assembly* for a referenced project — metadata with no method + bodies, which cannot be executed — but MSBuild knows both halves, and the targets declare the + implementation of every such reference in `HeddleObserveImplementationPath`. The compilation still + compiles against the reference assemblies; observation loads the implementations instead, matched by + **assembly identity** so a near‑miss is never substituted. A reference with no implementation on + record is the one that cannot be observed, and that is `HED7034`. +- **Each distinct C# source state leaves one intermediate assembly on disk.** `Assembly.LoadFrom` holds + a file open for the life of the compiler server, which is exactly why the file is named after a + digest of its own content — the permanent lock always lands on a file nothing will ever rewrite. + The cost is that an edit that changes the compilation produces a new file rather than replacing the + old one, under `obj/…/heddle/observe/`, until MSBuild `Clean` removes them. Nothing is written at all + unless a template actually contains a body the build cannot type on its own. + +### Startup order: a suggestion, not a rule + +The build tier binds every extension the compilation could see; the run tier holds only the ones you +registered. So a precompiled template survives the gauntlet's extension step exactly when the extension assemblies it +was built against are registered **before** the template renders — and which assemblies those are, and +when they load, is the host's decision. The engine does not make it: it will not load an assembly to +satisfy a binding, and it will not defer a render waiting for one. It reports. + +The pattern that keeps the reporting out of the request path: + +```csharp +// 1. Extensions first — every assembly that exports any, in the precedence order you want. +HeddleTemplate.Register(typeof(Program).Assembly); +HeddleTemplate.Register(typeof(SomeLibrary.WidgetExtension).Assembly); + +// 2. Functions next. TemplateOptions.Functions defaults to null, which means the frozen built-ins — +// so create a registry, fill it, and assign it. Registering into the default one throws. +var functions = new FunctionRegistry(); +functions.RegisterFrom(typeof(Program).Assembly); +options.Functions = functions; + +// 3. Then the precompiled manifests. +PrecompiledTemplates.Register(typeof(Program).Assembly); + +// 4. Then prove it, before serving a request. +var report = PrecompiledTemplates.ValidateAll(options); +if (!report.PassedForValidatedOptions) + throw new InvalidOperationException(report.ToString()); // fail the deployment, not the request +``` + +Registering an extension assembly *after* a template has already rendered is legal and takes effect, +but anything rendered in between degraded to the dynamic tier and said so through `OnFallback`. Step 4 +is what turns "said so, per request, in production" into "failed at startup, once". + +**The build‑side mirror.** Each of the first three steps has a build‑time counterpart, and a template only +precompiles when the build's answer is at least as complete as the run tier's — so it is worth reading the two +side by side: + +```xml + + + + +``` +```csharp +// 2. Functions: the build reads [ExportFunctions] off the reference closure — the same declaration +// RegisterFrom reads at run time, so exporting rather than registering imperatively is what makes a +// function-calling template precompile. +[assembly: ExportFunctions(typeof(MyApp.TemplateFunctions))] + +// 3. Models: one declaration for both tiers — the typeof forces the reference the build resolves against, +// and HeddleTemplate.Register reads the same attribute at startup (step 1 above already makes that call). +[assembly: Heddle.Attributes.HeddleModelAssembly(typeof(Acme.Models.Invoice))] +``` + +Step 4 has no build twin, and deliberately so: `ValidateAll` proves what *this process* is configured to serve, +which is the question the build cannot answer. What the build does instead is refuse to claim a template it +could not fully bind — the degrade — so the two never disagree about a template they both accepted. + +--- + +## What precompiles, and what falls back + +**The headline: custom and third‑party extensions precompile in a default build.** Bodied, +hook‑overriding, `[Prop]`‑declaring, branch‑role — all of them, with no property to set, no probe to +enable and no name list to be on. The build stopped predicting what an extension's compile‑time hook +does and started *running* it: the generated static initializer constructs your extension inside your +own assembly and calls its real `InitStart`/`CompleteInit`, handing it the already‑generated body in +place of a body compile. See +[Custom extensions in precompiled templates](#custom-extensions-in-precompiled-templates). + +**There are two sizes of fallback, and only one of them is about the template.** + +- A **template** fallback: the build declined the file, the manifest carries no bound strategy for it, + and the dynamic tier renders it. `HED7031` says so, with the refusal's class beside the sentence. +- A **call‑site** fallback: the file precompiles, and one call inside it renders by compiling its own + source text at first render. The rest of the template is emitted normally. This is what + `[PrecompileUnsupported]` buys (`HED7033`), and what the three shapes a type‑agnostic body cannot + write cost. Nothing else in the file is affected. + +Within a template, **refusal is the last option and not the first**. Each value node is planned before +it is written — typed C# in place, `.ToString()` in place where the sink only renders, a site that +resolves once at first use, the engine's own accessor delegate, a per‑call‑site substitute — and only a +node no plan serves declines the file. That inversion is why the list of constructs that cost a +template its tier is much shorter than it was. Control flow is still the harder half: reproducing the +engine's compile context for a subtree (prop layout, fill scope, slot carrier, region rebinds) is where +byte identity gets genuinely hard, which is why the substitute states its own bound rather than +guessing (see `HookBehavior` below). + +Falling back is never a correctness question, at either size. Both tiers are parity‑checked to the +byte, so a fallen‑back template — or a fallen‑back call — renders exactly what a precompiled one +would; what it costs is the build‑time work. `HED7031` is how you hear about the template‑sized one, +and `HED7031` is how you make it matter. + +### Recovered — these precompile now + +| Construct | How, and what it needs | +| --- | --- | +| Embedded C# (`@( @expr )`), reading `model`, `chained` or `root` | Emitted as a one‑line static method into the generated file, inside a `namespace Heddle.Runtime` block — the same shape and the same enclosing namespace the engine's own generated assembly uses, compiled by your compiler with the rest of the file. A value with no static type is declared `dynamic`, so the DLR call sites are the engine's mechanism rather than a reconstruction of it. Needs `HeddleExpressionMode=FullCSharp`, exactly as the engine needs `ExpressionMode.FullCSharp`, and an in‑file `@model` — typed **or** `dynamic` — to pin the scope every host compiles this template under. | +| `@partial`, static or computed name, and any extension declaring `[ChildTemplateHost]` | The extension is not reproduced, it is run: `PrecompiledRuntime.Init` constructs it at static init and calls its real `InitStart`/`CompleteInit`, so the name is evaluated by the hook itself — once, against a null scope, exactly as the engine does at its compile time — and the child is queued on the engine's own delayed‑template queue. `CompleteInit` takes delivery of the child through the engine's **child supply**, armed for the length of that one call's drain: the precompiled entry when the registry holds the named template, and the hook's own dynamic compile under the request's options when it does not. The child renders **streamed** through the caller's renderer, so a partial into a writer sink materialises nothing. | +| A member path ending on a `ref struct` in a **rendered** position | Stringified in place. The rendered carrier's protocol never needs the boxed value, so `.ToString()` is byte‑identical. Every other sink still boxes — see the boundary table. | +| A member the engine resolves and your assembly may not *name* — a referenced assembly's `internal` member without `[InternalsVisibleTo]` | Computed by the engine's own accessor, built once at type init from `System.Linq.Expressions` and called once per render (`PrecompiledRuntime.MemberAccessor`/`NativeAccessor`). No runtime Roslyn, no per‑render allocation. Controlled by `HeddleNodeFallback` (on by default); `false` restores the whole‑template degrade for this node. | +| A **bodied** call to a custom or third‑party extension — including one that overrides a compile‑time hook, declares `[Prop]`s, or carries a `[BranchRole]` | The hook is not predicted, it is run: `PrecompiledRuntime.Init` constructs your extension inside your assembly at static init and calls its real `InitStart`/`CompleteInit` with the generated body supplied in place of a body compile. Where the build cannot resolve the model type your hook chooses, the body is emitted **type‑agnostically** — no model cast — and each member read inside it becomes a `PrecompiledLateAccessor` bound to the engine's own member walk the moment your hook answers. One field read and one delegate call per read, no per‑render allocation, no runtime Roslyn. | +| A **chained call** (`@a():b():c()`), in output position or as a call parameter (`@a(b():c())`) | Emitted as the engine's own `TemplateChain`, statement for statement: the chained channel seeds the running value, every item is handed `scope.Chain(running)` — so an item's own call parameter is read off the chained scope rather than the ambient one — and the leftmost item renders where the rest process. The **chained type** is not predicted either: the engine threads it right to left, and each item's site names the producer to its right (`PrecompiledInitSite.ChainProducer`) so `Init` reads the type that producer's real `InitStart` returned. Items bind through every route a lone call does — a definition, a custom extension, a function, a late‑bound name, the unnamed carrier — and an item the seam cannot serve costs that item, not the chain. | +| A function only a run‑time `Register(string, Delegate)` supplies | Emitted as a late‑bound site that resolves once at first render through the engine's own overload ranker and caches the result — see [Functions the build cannot see](#functions-the-build-cannot-see). | +| A **bodied** call to a step‑back encoder (`@money(Cost){{ @(Locale) }}`, `@url`, `@attr`, `@js`, `@date`, `@time`, `@int`, `@guid`, `@string`) | Their hook re‑types the default body against the caller's scope and does nothing else — one hook body shared verbatim by nine built‑ins. That role is now read off the extension rather than predicted from a name list, so the bodiless and bodied forms bind alike. | +| A template that declares no `@model`, served to a host whose `CompileContext` **is** typed | Routed rather than assumed: the entry records that its model type is the build's answer (`ModelTypeIsAmbient`), the gauntlet compares it against the request, and a disagreement degrades that request with `ModelTypeMismatch` instead of serving the build's guess. Declaring the type with `ModelType` item metadata is what makes it precompile for that host. | +| An `[EncodeOutput]` extension hosting a body | The render type is derived from the extension's own `[EncodeOutput]`/`[NotEncode]` attributes at every allocation site, including the body‑hosting one, which previously hard‑coded `Raw`. | +| Definition override/layering (``), at any depth, with props, a narrowed `:: T`, caller content, or declared inside another definition's body | Nothing was built for it; a belief was removed. The emitter never resolved layers itself — it asks the same `ParseContext` the engine asks, and the parser has already put the layer each call site sees in it: a full override's body is isolated at its declaration, so a call to its own name there reaches the layer **below**, while every other context holds the most‑derived one. A definition is materialized where it is used, and precompilation always starts from the top‑level template, so the layer arrives resolved and emits as an ordinary definition call with its own body and its own position. The recursion guard is the engine's own carrier on both tiers, so a genuinely circular pair of layers stops identically. | +| A call whose body compiles to **no processors** — static text alone, nothing but directives, or a chain that composes to nothing — including a **bodied unnamed carrier** (`@( … ){{ … }}`) | The engine builds that body's document, finds no processor in it (`RuntimeDocument.Empty`) and discards it, leaving the hook with no strategy and the shaped body text as an inert `_innerResult`. The build emits that third post-state rather than predicting past it: the call site is handed `null` where a `BodyN` strategy used to go, so `InnerExist` is false on both tiers and every hook that reads it — the raw carrier, the encoding carrier, and any extension of anyone's — renders the same bytes. `@raw(){{mid}}` renders the model, not `mid`. | + +### The boundary, stated precisely + +An accurate boundary is worth as much as the coverage: each of these is a decision with a reason, not +a gap waiting to be filled. Two things are **not** on it and are worth saying so: `@model dynamic` and a +model‑less template both precompile — the entry point takes `object` and member reads route through the +engine's own dynamic binder, pinned to Heddle's assembly so the two tiers bind alike — and an +`internal` type or member of the **consumer's own** assembly is nameable by generated code and always was. + +| Boundary | Why it is where it is | +| --- | --- | +| Embedded C# outside `FullCSharp` | The engine refuses the same template under the same options. The degrade reproduces a refusal rather than losing a capability. | +| An `InitStart`/`CompleteInit` override **outside the engine assembly** | No longer a decline at all: the hook runs for real inside your assembly at static‑init, whichever way the extension reaches it — a package reference, a project reference, or a declaration in the compilation being built. What remains is narrower and per‑call‑site: a computed native expression or an embedded C# expression inside a body whose model type the hook chooses, and an extension that declares `[PrecompileUnsupported]` (`HED7033`). | +| A `ref struct` in a boxing sink — a model, an operand, a function argument, a slot value | `CS0029`/`CS1503`, and the engine refuses it too on modern TFMs (its expression trees reject by‑ref‑like types wholesale). Both tiers say no. | +| A type generated code may not **name** — a referenced assembly's `internal` type, or `[Obsolete(…, error: true)]` | `HED7030`. The engine binds by reflection, which asks neither question. The remedy is `[InternalsVisibleTo]` or dropping the error‑level `[Obsolete]`, not a Heddle setting. | +| An open generic model type | Re‑grounded, not repaired: the dynamic tier accepts **no** model value for an open generic type and cannot build a member accessor for one, so precompiling it would render where the engine refuses. | +| Types that do not exist at build time — `TypeBuilder`, scripting hosts | Nothing to reference, so the spelling resolves to nothing and the build reports `HED7007`. Not reachable by any assembly declaration. | +| Collectible or reloadable model contexts | Deliberately **no** build‑time twin of `UnregisterModelAssemblies`: baking one generation of a reloadable type into IL that the next reload invalidates is worse than degrading. | +| Assembly‑qualified spellings whose version a reference does not carry | The reference names an assembly; it does not carry the version the spelling pins. | +| Imperative‑only registration — `TemplateFactory.AddExtensions` over live `Type`s, `FunctionRegistry.Register` over a delegate | Not representable in metadata. Functions have the late‑bound site above; extensions have the declarative form ([`ExportExtensions`](custom-extensions.md#registering-your-extensions)). | + +### Why a template declines: the refusal categories + +Every `HED7031` carries a machine‑readable class beside its sentence, under the diagnostic property +`HeddleRefusalCategory`. The sentence is what a template author reads; the category is what a build +log, a dashboard or a coverage gate can group by, because a message is prose and a class is not. + +Every category here names a decline that costs the **template** its tier. A per‑call‑site fallback has +no category, because it is not a refusal: the file precompiles, and the call renders by compiling its +own text. It reports as `HED7033` when an extension author declared it, and as nothing at all when the +build simply could not write one body shape. + +Three of the seventeen are the only *legitimate* end‑state refusals — a genuine wall, a value the +build cannot know, and an engine failure the degrade reproduces. The rest are operational groupings +of what the emitter cannot emit **yet**, each one the retire‑target of a capability. Two of the +seventeen currently have **no site in the emitter at all** and are kept as declared, unreached members +— `ClrWall` and `DefinitionLayering` — because the coverage gates pin these names, so a category is +retired in place rather than deleted, exactly as a diagnostic id is. + +| Category | The refusal it names | +| --- | --- | +| `ClrWall` | No C# produces the engine's bytes. Declared as the vocabulary's first rung and currently reached by nothing: every wall found so far turned out to be a *sink* question (`RefLikeSink`) or a *spelling* question (`UnnameableType`), which are narrower and recover more. | +| `UnknowableValue` | A value or type that decides the bytes exists only at run time, or is chosen by reflection order — an ambiguous `IEnumerable` element type, an indexer whose choice depends on member order. | +| `EngineParity` | The engine refuses or fails here and generated code would render. The degrade hands the template to the tier whose diagnostic is the contract — an engine lint refusal, a division by a constant zero, an open generic model. | +| `ChainCarrier` | Narrowed twice: a chained call is emitted as the engine's own `TemplateChain` now, and the **bodied unnamed carrier** it kept after that is emitted too — it was refused for one rendered byte, and the byte is the inert-body post‑state above, which the build now emits. What is left is an item of a chain the emitter could not build and a chain‑item name it cannot bind, plus two floors the grammar does not reach — a chain‑parameter item carrying a body, and a call parameter with no producer in it. | +| `DefinitionLayering` | Definition override/layering. Reached by nothing: it named a belief about how the emitter resolved definitions rather than a limit, and it is retired in place — declared, so the category vocabulary the degrade seam pins keeps its member — the way `ClrWall` is. | +| `DefinitionProps` | A definition or extension prop prototype the emitter cannot freeze: unknown, duplicate, missing or unreproducible values, and dynamic arguments it cannot type. | +| `EmbeddedCSharp` | An embedded C# expression the compiled‑fragment path cannot carry — no in‑file `@model` to pin the scope, an expression reading `root` where nothing pins the root type, a `@using` body naming no namespace, or text the engine's own compiler rejects. Inside a type‑agnostic body it costs the call site rather than the template: the fragment's model parameter would have to be *spelled*. | +| `FunctionBinding` | A call no build‑time registration binds and no late‑bound site can serve. Its loud twin is `HED7014`. | +| `HookBehavior` | The **substitute's own bound**, and nothing wider. A hook the build has not read is not a decline — it runs for real at static‑init — so what is left here is what a per‑call‑site substitute cannot be honest about: it compiles the call's own text as its own document, which sees no enclosing definition, no ambient region fill scope and no active prop layout. A body reaching for any of those sends the **template** to the dynamic tier rather than the call. `HED7015`, the loud twin the unread hook once had, is retired in place. | +| `ExtensionBinding` | An extension the binder cannot bind at build time, or a binding‑surface fault: an unbindable type, an unbound name, a malformed `[Prop]` declaration. | +| `HostSetup` | The consumer's build configuration forbids the emission — an expression‑mode gate, a missing `Microsoft.CSharp` reference, conflicting model declarations. The remedy is host setup, not template or emitter work. | +| `MemberAccess` | A member path, prop read or receiver the emitter cannot resolve statically — and that the engine's accessor cannot serve either. | +| `NativeExpression` | A native‑expression shape the shared operator tables or the expression writer do not emit. Inside a type‑agnostic body a *computed* expression costs the call site rather than the template: its result type depends on an operand type that does not exist until the hook answers. | +| `PartialName` | A child‑template host's body that names no template at all — the one call shape the role cannot carry. The name itself is no longer the emitter's to evaluate or normalize: the extension does both. | +| `RefLikeSink` | A ref‑struct value in a boxing sink — recoverable only in the rendered sink, where the carrier stringifies in place. | +| `SlotChannel` | An `@out`/slot shape the emitter cannot carry: a slot definition whose declared slot type cannot be named, and a **bodied** projection. Everything else the build once decided about a projection — slot mode, a value where no slot is declared, a missing value inside one, a value the declared slot type cannot take — is the extension's own `InitStart`, run for real at registration; a hook reporting the engine's compile errors there is a template‑scope fault and the request renders on the dynamic tier, which reports the same diagnostic. The bodied projection no longer stands on the byte it was kept for: it named the inert‑body divergence above — `[@out(){{BODY}}]` rendering `[BODY]` on one tier and `[]` on the other — and the build emits that post‑state now. What keeps it is not the byte but a role‑dispatch question: with the body emitted, the projection route is a passthrough and a declared `[SlotProjection]` changes nothing the build tier does. | +| `UnnameableType` | A type generated code cannot spell: inaccessible, error‑obsolete, unresolvable, or with no writable name. Its loud twin is `HED7030`. | --- @@ -191,22 +743,66 @@ their `.heddle` position; file/key/option‑level conditions report without a so | `HED7001` | An `AdditionalFiles` `.heddle` source could not be read. | | `HED7002` | Two templates normalize to the same key. | | `HED7003` | Two keys differ only by case (warning). | -| `HED7004` | Invalid explicit `Key` metadata. | +| `HED7004` | Unusable explicit key metadata on an item: a `Key` or `Name` value the key normalizer refuses, or a `Key` and a `Name` that name two different keys. | | `HED7005` | Unpaired surrogate in static text — the `"…"u8` twin is suppressed (warning). | -| `HED7006` | A named extension resolves to no `[ExtensionName]` type in any reference. | +| `HED7006` | A named extension resolves to no `[ExtensionName]` type in any reference **under the runtime's own discovery rule** (implements `IExtension` and carries an inherited `[ExtensionName]`). A name the runtime *would* find but the generator cannot bind — an `IExtension`-direct implementor, or a collision between unrelated types — degrades to the dynamic tier with a recorded reason instead (phase 3, F3). | | `HED7007` | The `@model`/`::` type does not resolve (milestone‑2 native diagnostic). | | `HED7008` | A member path does not resolve on the model type (milestone‑2 native diagnostic). | | `HED7009` | An MSBuild option value is unparsable. | | `HED7010` | Two keys sanitize to one generated class identifier. | -| `HED7011` | An `@<<` import is not among the compilation's `.heddle` `AdditionalFiles`. | +| `HED7011` | An `@<<` import is not among the compilation's `.heddle` `AdditionalFiles`. The spelling is matched against the item's key, so it is case-sensitive; it is first reduced the way the engine's own `Path.GetFullPath` reduces it — `.` segments and repeated separators drop out, a `..` cancels the segment before it, and a trailing separator survives (so `lib.heddle/.` names the file and `lib.heddle/` names a directory neither tier can read). Which characters separate segments is the platform's answer: a backslash separates on Windows and is an ordinary file-name character elsewhere, on both tiers. A `..` that reaches above the template root names nothing on either tier. An import path is **not** a template key, so the key idioms are refused rather than applied: a leading `/` is an absolute path to `Path.Combine`, a leading `~/` is a literal `~` directory, and an extension-less name is a file without an extension — the precompiler declines each of the three rather than renaming the file the engine reads. | | `HED7012`/`HED7013` | A forwarded front‑end error/warning carrying no id. | -| `HED7014` | A called function is delegate‑only (not precompilable) — the template falls back (warning). | -| `HED7015` | A bound extension overrides a compile‑time hook — unevaluable at build. | +| `HED7014` | A called function no build‑time registration binds, in a call shape a late‑bound site cannot serve either (chiefly an argument whose static type has no build‑time answer) — the template falls back (warning). A delegate‑only registration alone no longer reaches this: see *Functions the build cannot see*. | +| `HED7015` | **Retired in place — no build raises it any more, and the id stays claimed forever.** It reported that a bound extension outside the engine assembly overrode a compile‑time hook the build had not read, and that the template therefore fell back. The build no longer has to read a hook to bind one: the extension's own `InitStart`/`CompleteInit` runs inside your assembly at static‑init, so the fact this warning reported is no longer true of any build. The id is never reused and never renumbered; this row is its permanent home. | | `HED7016` | A branch continuation/terminal (`[BranchRole]`) omits `[ScopeChannel]`, so it can never read the branch state at run time (warning). | +| `HED7017` | An extension declares a malformed `[Prop]` parameter — the build‑tier twin of the dynamic tier's declaration diagnostics. | +| `HED7018` | A template is outside `HeddleTemplateRoot` and has no explicit `Key`, so its directory is dropped and it registers under a flattened filename key (warning). Only `Key` suppresses it: a `Name` is additive and leaves the flattened key in place, so the warning is still about something real. | +| `HED7019` | The `Heddle` engine assembly is not visible among the compilation's references, so the manifest records the generator's own version as `engineVersion` (warning). | +| `HED7020` | The template emitter threw — a generator defect, not a template error. That one template emits nothing; the rest of the pass and the manifest are unaffected. | +| `HED7021` | An `[assembly: ExportFunctions(...)]` container is not a public static class. The runtime throws when the host assembly is registered, so the build errors rather than skipping the container silently. | +| `HED7022` | An `@profile(){{…}}` value is neither `text` nor `html`. The runtime rejects the template with `HED2001`, so the build reports it rather than pre-compiling output the dynamic tier would never produce. | +| `HED7023` | A model/prop/slot type name is ambiguous — several types answer to it and the `@using` imports do not settle it. The runtime raises the same ambiguity, so the build errors rather than binding one candidate. | +| `HED7024` | A call-site fill overrides a region the definition declares private. The runtime raises `HED5019` for the same template, so the build reports the matching error at the override's position. | +| `HED7025` | A function call the shared overload ranker proved illegal — ambiguous under Heddle's flat Pareto rank (`HED1013`), or no applicable overload (`HED1012`). Fires only when every argument estimate is typed: an argument the generator cannot describe proves nothing about the runtime and still degrades silently. | +| `HED7028` | An `@<<` import names a template by its registration key while the template also carries a `Name`. Both spellings resolve — `Name` adds an import name, it never replaces the key — so this is a warning recommending the name-first spelling for a named template. | +| `HED7030` | A type — a model, a member's type, or a bound host **extension** — that generated code may not name: an `internal` type or `internal` member declared in a *referenced* assembly, or one marked `[Obsolete(…, error: true)]`. The engine binds it by reflection — which ignores both assembly boundaries and `[Obsolete]` — and renders normally, while generated code naming it would not compile (`CS0122`, `CS0619`), so the template degrades to the dynamic tier under a warning. Make it public or grant the consuming assembly `[InternalsVisibleTo]`, or drop the error-level `[Obsolete]`, to precompile it. A warning-level `[Obsolete]` changes nothing: the template still precompiles, and the generated file suppresses the warning. An extension is discovered by reflection over the exporting assembly and created with `Activator.CreateInstance`, neither of which asks either question, so a non-public or error-obsolete extension registers and renders while the `new` the generated field is initialised with does not compile. An extension whose declared `[Prop]` *type* is unnameable is unaffected: nothing on the parameter path ever spells a prop type. | +| `HED7031` | The emitter declined to precompile this template for a reason with no more specific channel — embedded C# outside `FullCSharp` expression mode, or a prop prototype the build cannot freeze — so it renders through the dynamic path. The message carries the emitter's own reason, and the diagnostic carries the reason's **class** beside it as the `HeddleRefusalCategory` property: see [Why a template declines](#why-a-template-declines-the-refusal-categories). Output is unaffected: the two tiers are parity-checked and produce identical bytes, so this costs build-time work rather than correctness. It is the catch-all for a decline that was previously **silent**: the emitter computed a reason, the generator's `if (Emitted) … else if (IsMarker)` had no final `else`, and the template produced no source, no manifest row and no diagnostic — leaving a project no way to learn that a template it believed precompiled was rendering dynamically on every request. Where precompilation is a requirement rather than an optimisation, promote it with `HED7031`. | +| `HED7032` | A template carries **both** an in‑file `@model` directive and `ModelType` item metadata, and the two spellings resolve to **different types**. The runtime reads only the directive, so the build refuses to pick one rather than typing the same template differently on the two tiers. Equal spellings, or different spellings resolving to the same type, agree and raise nothing. Reported at the file's start — item metadata has no in‑file position. | +| `HED7033` | A bound extension declares `[PrecompileUnsupported]` — its author's own statement that a static initializer cannot reproduce its compile‑time behaviour (warning). The declared reason is quoted **verbatim**. Cost is **one call site**: that call binds dynamically (it renders by compiling its own source text at first render) while the rest of the template stays precompiled. Read on both sides — the build reads the declaration off the symbol, the runtime reads it off the live type — so an extension package that adds the declaration *after* your assembly was built still falls back rather than binding through a seam its author has disowned. | +| `HED7034` | The build could not observe a real engine compile of your templates, so a body whose model type only an extension's hook can supply is emitted type‑agnostically rather than with a direct cast. A **note** under `HeddleObserveEngine=Auto` and an **error** under `Strict`; reported once per compilation, and not at all under `Auto` when no observe directory was configured — nor in either mode when no template ever needed observing. A project‑to‑project reference to the engine or to an extension assembly is handled — MSBuild declares the implementation behind each reference assembly in `HeddleObserveImplementationPath`, and observation loads that — so what is left is a reference with no implementation on record, a host that does not import `Heddle.Generator.targets`, an observe directory that could not be written, or an engine image the process could not load. The template still precompiles and renders identical output either way — this is a typing optimisation, not a tier. | + +**Engine ids that fire at build.** A refusal the generator can *prove* the engine repeats at its own +template compile is not a `HED7xxx` twin but the engine's id **forwarded** as a build error — same +fact, same id, same sentence, at the `.heddle` position: `HED1003` (method‑call syntax in a native +expression), `HED1004` (a native expression under a declared‑`dynamic` model, or a path crossing a +`dynamic` member), `HED1005` (`&&`/`||` over a non‑`bool` operand), `HED1007` (ternary arms or a `??` +pair with no common type), `HED1008`/`HED1009` (a binary/unary operator not defined for its operand +types), `HED1010` (no accessible indexer on a known target type), `HED1011` (a non‑`bool` ternary +condition), and `HED1018` (constant division by zero). The template still degrades to the dynamic +tier; the build now fails the way the engine's compile would, instead of hiding the error until the +first runtime compile. A refusal the generator cannot prove — an operand it cannot type, a verdict +that depends on runtime binding, a template whose model type is simply undeclared — keeps degrading +silently under `HED7031`. Member/type errors in milestone 1 arrive as C# errors remapped to the template span via `#line`; milestone 2 replaces the covered ones with native `HED7007`/`HED7008`. +**How many of these one build reports.** The body walk **collects** refusals rather than abandoning +at the first: two sibling elements that each refuse produce two diagnostics, each at its own +`.heddle` position, for every id an element can raise (`HED7025`, `HED7008`, `HED7006`, `HED7033`, +`HED7017`, `HED7014`, `HED7022`). Refusal still propagates — a refused element fails its body up to +the template, so the template emits no generated source and no manifest row; collecting changes how +many diagnostics a build *surfaces*, never what it emits. Within **one expression** the walk still +reports once: expression writing is string-or-`null` composition, where a parent has nothing to +compose once a child fails, so `@(min(1, 2u)) @(max(1, 2u))` reports twice while +`@(min(1, 2u) + max(1, 2u))` reports once. That asymmetry is deliberate. + +This is the one place the build tier deliberately does not mirror the dynamic engine's *shape*: the +dynamic engine raises the first such error and stops, so a build can report a set no single dynamic +compile produces. The match principle is untouched — every collected report is one the runtime +raises for the same input once the earlier fault is fixed. What differs is how many surface per +build, never which verdict either tier reaches. + --- ## The T4‑successor CLI @@ -226,3 +822,16 @@ access, arrays drive `@list`/`@for`, and scalars map to CLR primitives. ``` heddle render