Files
ruin/docs/performance-profiling.md

95 lines
3.3 KiB
Markdown

# 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.