NAME
problem48-saved-page-route-benchmark - profile a saved browser page and its navigation fragments
PURPOSE
Measures the warmed production Web::App->handle('/app/welcome') path with a configurable number of saved nav/*.tt fragments, an isolated temporary HOME, strict HTTP/body validation, configurable installed-skill navigation fragments, and optional collector indicators and NYTProf profiling.
WHY IT EXISTS
Problem 48 needs performance evidence at ordinary application boundaries, not only the status endpoint. This tool compares the same fixture on v5.88 and the current source tree and supports larger nav sets to measure how per-request root discovery scales. It normalizes only the live status timestamp, then requires the remainder of every response to stay byte-identical during the run.
WHEN TO USE
Run after changes to saved-page routing, Template Toolkit preparation, page chrome, saved navigation discovery, or request-local runtime caches. Compare the output from both source trees before attributing a speedup to a change. The report includes nav candidate-root searches, nav file reads, and containment checks so cache and provenance effects remain distinguishable. Output distinguishes requested snapshot caching from observed hits and reports whether the optional native watch backend is available. Use --no-native-watch to benchmark the portable fallback explicitly on a system that has the native backend installed. Use --indicators to seed collector-managed indicator records and measure the prompt-summary freshness cache under status-heavy page rendering. The cache control --no-prompt-summary-cache disables only prompt-summary reuse; the benchmark reports freshness-check and cache-hit counts and requires the same response bytes in both modes. Use --skill-nav-fragments to create temporary installed skills with one raw navigation fragment each. The report verifies that every fixture fragment was rendered by the real route; this isolates the skill-navigation discovery and rendering path without reading user skill directories. Use --no-nav-cache on current source to compare the same fixture with nav inventory rescanning on every request; the output reports scan count. Use --no-nav-fragment-cache to clear the bounded literal-fragment cache before each request and compare the file-read count and latency with the validated-cache path. Use --no-skill-literal-nav-cache to disable reuse of unchanged static skill-nav pages while preserving skill discovery and exact rendered output. The report includes the number of skill-nav instruction reads, making the warm-cache effect measurable. Use --no-skill-nav-inventory-cache to rescan the skill-nav directory tree on every request. Compare it with the metadata-validated directory inventory cache; both modes preserve exact response bytes, and the report records actual recursive directory scans. Use --duplicate-page-containment to recreate the former extra containment check in candidate lookup, so exact-output route measurements can compare its cost with the single validation at secure open time. Output reports the total containment checks during measured requests. Use --no-page-roots-cache to disable the request-local saved-page root snapshot for page lookups that do not have a supplying-layer provenance hint. Saved nav files use their scanned layer provenance and do not repeat candidate root search. Output reports the number of measured calls to dashboards_roots. Use --duplicate-skill-layer-resolution to recreate the former second layer lookup in _load_skill_page; compare its layer-resolution count and route timing with the optimized path while checking response hash parity. Use --duplicate-skill-nav-layer-resolution to recreate repeated layer resolution while enumerating and loading each skill navigation fragment. Use --legacy-skill-nav-enumeration to replay the former per-skill discovery loop against the same fixture. The benchmark reports layer-resolution counts and requires exact response parity with the bulk-inventory path. Use --parse-raw-skill-nav as a control that forces raw skill nav templates through the structured instruction parser rather than the raw-fragment path. Use --legacy-runtime-root-access as the pre-cache control for the request-scoped runtime-root accessor. Use --legacy-config-snapshot-signature as the prior pretty-JSON control for the request-local configuration snapshot key; the response bytes must match.
HOW TO USE
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --nav-fragments 100
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --skill-nav-fragments 50
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --skill-nav-fragments 50 --no-skill-literal-nav-cache
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --skill-nav-fragments 50 --no-skill-nav-inventory-cache
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --no-nav-cache
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --no-nav-fragment-cache
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --duplicate-page-containment
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --no-page-roots-cache
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --no-native-watch
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --legacy-runtime-root-access
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --legacy-config-snapshot-signature
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --skill-nav-fragments 50 --duplicate-skill-layer-resolution
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --skill-nav-fragments 50 --duplicate-skill-nav-layer-resolution
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --skill-nav-fragments 50 --parse-raw-skill-nav
d2 docker compose exec dev env P48_LIB=/work/nytprof/v588/lib NYTPROF=file=/work/nytprof/saved-v588.out:start=no perl -d:NYTProf script/problem48-saved-page-route-benchmark --iterations 20 --runs 1 --profile
d2 docker compose exec dev env P48_LIB=/work/lib NYTPROF=file=/work/nytprof/saved-current.out:start=no perl -d:NYTProf script/problem48-saved-page-route-benchmark --iterations 20 --runs 1 --profile
The profile switch is enabled only around the warmed request loop. Benchmark HOME and saved-page fixtures are private and automatically removed at exit. Skill-nav fixtures are created under that same temporary HOME and removed with the rest of the fixture.
WHAT USES IT
Problem 48 performance research uses this benchmark to compare saved-page rendering, navigation includes, and chrome under identical route conditions.
EXAMPLES
Example 1: run a robust unprofiled median comparison.
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark
Example 2: collect a profile for current source.
d2 docker compose exec dev env NYTPROF=file=/work/nytprof/saved-current.out:start=no perl -d:NYTProf script/problem48-saved-page-route-benchmark --profile
Example 3: check CLI documentation and input validation.
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --help
Example 4: compare navigation inventory caching with repeated directory scans.
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --no-nav-cache
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --no-native-watch
Example 5: measure installed-skill nav discovery and rendering.
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --skill-nav-fragments 50
Example 6: compare prompt-summary reuse with a seeded indicator inventory.
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --indicators 50
d2 docker compose exec dev perl script/problem48-saved-page-route-benchmark --iterations 100 --runs 21 --indicators 50 --no-prompt-summary-cache