95 lines
3.3 KiB
Markdown
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.
|