nigig-org/crates/apps/nigig-traffic/docs/PERF_BASELINE.md
andodeki ac8f8aa002
Some checks failed
p2p-intel / engine (push) Waiting to run
p2p-intel / notifications (push) Waiting to run
p2p-intel / coverage (push) Waiting to run
p2p-intel / makepad-app (push) Waiting to run
p2p-intel / exchange-tab (push) Waiting to run
Payment domain, storage, platform and UI / isolated-payment-tests (push) Waiting to run
Payment domain, storage, platform and UI / payment-ui-tests (push) Waiting to run
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
chore: sync full working tree to gitdab
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.
2026-09-12 07:15:24 +03:00

3.6 KiB
Raw Permalink Blame History

nigig-traffic perf baseline (plan Phase 6.3)

Machine: MacBook Pro, Apple Silicon (darwin x86_64 binary under Rosetta — target/debug/nigig-traffic: Mach-O 64-bit executable x86_64), debug profile. Two consecutive runs, cargo test -p nigig-traffic --test perf -- --test-threads=1 --nocapture. Catalog: 47 scenarios (the old "36+" copy is a floor, still true).

build_world_for — median µs over 20 reps

Category Run 1 Note
Lanes 2
Roundabout 11 16 ring segs + island
Parking 5 4 bays
UTurns 4
Signs 3
Priority 2
Hazards 3
Speed 2

Single-digit microseconds everywhere. World build is not a cost center — no caching/baking work is justified.

tick — 600 ticks/scenario, idle input, per-tick average

Run 1 Run 2
median 14 µs 26 µs
slowest #1 haz_rain 501 µs lane_bus_lane 450 µs
slowest #2 pri_yield_car 255 µs pri_yield_car 386 µs
slowest #3 rb_multi_exits 248 µs ut_single_turn 257 µs

Reading, per HPC ch.5.6: the slowest set moves between runs (haz_rain/rb_multi_exits appear once each) — that is noise (debug build, shared machine), not a scenario-intrinsic cost. pri_yield_car ranks top-3 twice; it spawns a moving AI car, so it is the prime suspect for the only genuine above-median cost — unconfirmed until a pinned, quiescent re-run. No optimization is authorized off this table alone.

Live run (NIGIG_TRAFFIC_STATS=1, same machine, windowed)

traffic stats: tick us p50=48 p95=270  p99=5761 (n=300)
traffic stats: draw us p50=69 p95=563  p99=4182 (n=300)
traffic stats: tick us p50=55 p95=332  p99=1839 (n=300)
traffic stats: draw us p50=76 p95=663  p99=4272 (n=300)
traffic stats: tick us p50=59 p95=561  p99=3681 (n=300)

Live tick p50 (~55µs) runs hotter than the harness median — it shares the machine with the window server and includes rig/camera work around the timed region. p99 spikes are millisecond-scale frame hitches (scheduler / allocator / display-link, not sim code): the next profiling step is an Instruments sample attributing p99, not optimizing p50.

Blocked: release-vs-size profile decision (Phase 9)

release currently sets opt-level = "z" with no LTO. Whether the game binary wants opt-level = 3 (throughput over size) must be measured on the Phase-6 bench — but the workspace-wide fork rev bump broke compilation of every crate (upstream b9a083c references a never-landed isolate refactor: enter_isolate/leave_isolate/IsolateEntry used in 4 files, defined in 0; plus a 4-vs-5-arg camera_boom_limit drift), so no release numbers exist yet. Decision and both measurements go here once the workspace builds again. Do not choose on aesthetics.

Conclusions authorizing later phases

  1. Tick ≈ 1525µs median (debug). At 60Hz the budget is 16,600µs — the sim consumes ~0.1%. There is no throughput emergency.
  2. Costs are latency-shaped (lookups, allocations, branches over dozens of entities), never compute-shaped. Phases 78 target exactly that; hand-written SIMD is off the table (documented anti-goal).
  3. Next measurement before any Phase 7 code: quiescent release-profile re-run + Instruments sample confirming step_world vs evaluate vs text-shaping split.