# Performance profiling workflow RUIN performance investigations should start with reproducible reports before deep profiler sessions. The first-pass tooling is intentionally headless and focused on high-signal app-build, layout, text, scene, and cache counters. ## Run a scenario Use the `ruin_perf_scenarios` package in release mode: ```bash cargo run -p ruin_perf_scenarios --release -- \ --scenario large-scroll-list \ --frames 300 \ --output target/ruin-perf/large-scroll-list.json ``` List available scenarios: ```bash cargo run -p ruin_perf_scenarios -- --list ``` Current scenarios: | Scenario | What it stresses | | --- | --- | | `counter` | tiny reactive-style app tree rebuild and layout baseline | | `large-scroll-list` | scroll culling, text cache reuse, layout cache behavior | | `calculator` | realistic small app tree with display, button grid, and history | | `resize-configure` | repeated viewport-size changes and layout reflow | | `large-text-body` | huge wrapped text body, text layout cache behavior, scroll clipping | The large text scenario accepts a body-size option: ```bash cargo run -p ruin_perf_scenarios --release -- \ --scenario large-text-body \ --frames 100 \ --text-kb 1024 ``` Each run writes JSON under `target/ruin-perf/` by default and prints a compact summary table to stdout. ## Interpreting the report Start with the timing rows: - `app_build`: time spent building the deterministic app tree for the frame. - `layout_total`: full layout snapshot time. - `layout_intrinsic`: intrinsic measurement work inside layout. - `text_prepare` / `text_cache_miss`: text shaping/cache miss work. Then inspect counters: - High `layout_cache_misses` with low `layout_cache_hits` means the tree or layout constraints are changing in a way that defeats caching. - High `viewport_culled` with low `scene_items` is expected for large scroll lists and means scene culling is working. - High `text_cache_misses` or `text_cache_miss` time usually means text content, bounds, style, or cache keys are changing too much. - Large `scene_items` or `text_glyphs` for tiny workloads suggests excessive UI tree expansion or missing culling. ## Investigation loop 1. Reproduce the suspected degenerate workload with the closest scenario. 2. Run it in release mode and keep the JSON report. 3. Compare the stdout summary with a known-good run or a smaller frame count. 4. If one phase dominates, use an OS profiler on that scenario: - macOS: Instruments Time Profiler / Allocations / Metal System Trace. - Linux: `perf`, `samply`, `heaptrack`, or RenderDoc as appropriate. 5. After identifying a concrete hot path, add or update a narrow Criterion benchmark before optimizing it. ## Validation The scenario runner is part of the default workspace. The usual repository validation should keep it healthy: ```bash cargo test cargo clippy --all-targets -- -D warnings cargo clippy --release --all-targets -- -D warnings ``` ## Current limitations This first pass does not automate GUI input, GPU frame capture, or platform presentation traces. Renderer frame counters are exposed for platform-backed runs, but the headless scenario reports focus on app/layout/text degeneracy first. Platform-backed resize/presentation report generation should be added after these reports are useful enough to guide concrete optimization work.