Files
ruin/docs/performance-profiling.md

3.3 KiB

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:

cargo run -p ruin_perf_scenarios --release -- \
  --scenario large-scroll-list \
  --frames 300 \
  --output target/ruin-perf/large-scroll-list.json

List available scenarios:

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:

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:

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.