Some checks failed
repo hygiene / hygiene (push) Has been cancelled
PDF engine / engine (push) Has been cancelled
PDF engine / makepad-integration (push) Has been cancelled
PDF engine / fuzz (push) Has been cancelled
nigig-build (CAD) / supply-chain (push) Has been cancelled
nigig-build (CAD) / cad-module (push) Has been cancelled
nigig-build (CAD) / full-crate-check (push) Has been cancelled
nigig-build (CAD) / cad-engine-coverage (push) Has been cancelled
nigig-build (CAD) / doc-workspace-coverage (push) Has been cancelled
nigig-build (CAD) / cad-widget-coverage (push) Has been cancelled
traffic / gates (push) Has been cancelled
traffic / nigig-traffic (push) Has been cancelled
traffic / supply-chain (push) Has been cancelled
doc-engine / engine (push) Has been cancelled
doc-engine / coverage (push) Has been cancelled
doc-engine / consumer (push) Has been cancelled
email / gates (push) Has been cancelled
email / email-domain (push) Has been cancelled
email / nigig-email (push) Has been cancelled
email / supply-chain (push) Has been cancelled
nigig-map / test (push) Has been cancelled
sms / gates (push) Has been cancelled
sms / robius-sms (push) Has been cancelled
sms / android (push) Has been cancelled
sms / nigig-sms (push) Has been cancelled
sms / supply-chain (push) Has been cancelled
spreadsheet / engine-coverage (push) Has been cancelled
spreadsheet / ui-controller-coverage (push) Has been cancelled
p2p-intel / engine (push) Has been cancelled
p2p-intel / notifications (push) Has been cancelled
p2p-intel / coverage (push) Has been cancelled
p2p-intel / makepad-app (push) Has been cancelled
p2p-intel / exchange-tab (push) Has been cancelled
Payment domain, storage, platform and UI / isolated-payment-tests (push) Has been cancelled
Payment domain, storage, platform and UI / payment-ui-tests (push) Has been cancelled
Whole-tree sync: cad-core/cad-ui split sources, nigig-build construction_frame migration, pdf port progress, mpesa/pay/uikit/doc updates, workspace members/profiles/lock, CI workflows and reviews. See individual file history for details.
75 lines
3.4 KiB
Markdown
75 lines
3.4 KiB
Markdown
# nigig-traffic performance runbook (plan Phase 6)
|
||
|
||
Rule zero (HPC ch.1 "When to Optimize", ch.5): no optimization without a
|
||
profile line pointing at it, and no number counts until it is in
|
||
`PERF_BASELINE.md`. If it isn't in the baseline file, it didn't happen.
|
||
|
||
## Live frame stats
|
||
|
||
The view collects tick + draw microseconds over a 300-sample window and
|
||
reports p50/p95/p99 to the log (`src/ui/game_view.rs`: `FrameStats`).
|
||
Collection is a few integer stores per frame; reporting only fires with:
|
||
|
||
```sh
|
||
NIGIG_TRAFFIC_STATS=1 cargo run -p nigig-traffic
|
||
# look for: traffic stats: tick us p50=.. p95=.. p99=.. (n=300)
|
||
```
|
||
|
||
## Repeatable harness
|
||
|
||
```sh
|
||
cargo test -p nigig-traffic --test perf -- --test-threads=1 --nocapture
|
||
```
|
||
|
||
`tests/perf.rs` prints median build µs per category and per-tick µs over
|
||
600 ticks × every scenario. Timings are deliberately NOT asserted —
|
||
wall-clock asserts are flaky by nature (HPC ch.5.6). The sanity asserts
|
||
(tick count, Intro→Driving transition, black-boxed score) exist only so
|
||
the optimizer cannot hollow the loop.
|
||
|
||
## Methodology (HPC ch.5.6, condensed)
|
||
|
||
- `--test-threads=1`, warmed runs, one machine, nothing else building.
|
||
(Background `cargo-makepad android` jobs invalidated early readings here
|
||
— check `ps aux | grep rustc` before trusting a number.)
|
||
- Report medians, never means; re-run to check outlier stability. Outliers
|
||
that move between runs are noise, not findings.
|
||
- Debug profile numbers are for shape (which function, which scenario
|
||
class), never for absolute budgets. Ship budgets come from release runs
|
||
on the target device.
|
||
|
||
## Statistical profiling
|
||
|
||
- macOS: Instruments → Time Profiler, attach to `target/debug/nigig-traffic`
|
||
while driving; look for `step_world`, `draw_scene`, `evaluate`, text
|
||
shaping (`shaper.rs`), not the frame loop itself.
|
||
- Linux: `perf record -g` + `perf report`. Top-down first, bottom-up to
|
||
confirm callers.
|
||
- Sampling finds the hot 3%; instrumentation lies about the rest. The
|
||
`FrameStats` ring is the instrumentation — treat it as a tripwire, and
|
||
reach for the sampler before changing code.
|
||
|
||
## What the numbers said so far
|
||
|
||
See `PERF_BASELINE.md`. Headline: the tick is memory-latency-bound on
|
||
tiny data (median ~15–25µs debug, 47 scenarios), builds are single-digit
|
||
µs. There is no compute hot spot to SIMD away — Phases 7–8 accordingly
|
||
target lookups, allocations, and branches, not intrinsics.
|
||
|
||
## Build environment notes (hard-won, do not re-learn)
|
||
|
||
- `RUSTC_WRAPPER=kache` is exported on dev machines (`~/.profile`) but
|
||
the `kache` binary may not exist — cargo then fails with `could not
|
||
execute process kache ... os error 2`, surfacing in makepad-test runs
|
||
as `BuildStopped 101`. Fix: `ln -s sccache ~/.cargo/bin/kache`, or
|
||
standardize on `sccache` + `SCCACHE_DIR` in one place.
|
||
- One target dir: the workspace root `target/`. Per-crate `target/`
|
||
dirs (a stale 2.2G one lived under `nigig-traffic/` until Sep 2026)
|
||
waste disk and split test artifacts across two trees. The makepad-test
|
||
harness historically pointed `CARGO_TARGET_DIR` at the per-crate dir;
|
||
keep it on the workspace root.
|
||
- Release-vs-debug profile decision (`opt-level 3` vs `z` for the game
|
||
binary) is BLOCKED on a green workspace build — the fork rev bump
|
||
broke compilation repo-wide (see Phase 9 notes in PERF_BASELINE.md).
|
||
Measure both on the Phase-6 bench before choosing; do not pick on
|
||
aesthetics.
|