Skip to content

feat(scripts): local A/B boot benchmark harness - #253

Open
gmaclennan wants to merge 1 commit into
feat/backend-memory-telemetryfrom
feat/boot-benchmark-harness
Open

feat(scripts): local A/B boot benchmark harness#253
gmaclennan wants to merge 1 commit into
feat/backend-memory-telemetryfrom
feat/boot-benchmark-harness

Conversation

@gmaclennan

Copy link
Copy Markdown
Member

Stacked on #249, which adds backend/lib/memory-snapshot.js and the [comapeo.memory] boot log line this harness reads. Review that one first; the base branch here is feat/backend-memory-telemetry.

Answering "is build B lighter than build A?" has so far meant a throwaway script each time. This makes it one command:

./scripts/benchmark-boot.sh --ab before.apk after.apk --rounds 3 --per-round 5

It runs interleaved cold boots of apps/integration, alternating which build goes first each round, discarding the warm-up boot after each install and wiping the compile cache before every boot so neither build inherits the other's. It prints medians (not means — one scheduling stall drags a mean around), deltas, two-sided Mann–Whitney p-values, and per-round medians.

The per-round table is the part worth reading first. A development machine is doing other things and host load drifts over the twenty-odd minutes a full run takes, so the question is not whether the two medians differ but whether they separate the same way in every round. If the rounds disagree, you measured the machine.

Peak RSS, RSS and the heap breakdown come from the backend logging its own reading once per launch, so no root is needed and the harness works unmodified on a production device; adb root only adds an optional 50 ms /proc trajectory on top. With no --apk/--ab it builds apps/integration in Release first — benchmark against Release, never debug, where startForeground alone is about ten times slower.

Parsing and statistics live in a pure scripts/lib/benchmark-core.mjs with no device or filesystem dependency, covered by npm run test:scripts; the shell wrapper is only device orchestration. Output lands in benchmark-results/ (gitignored): one JSON per label plus the raw per-boot logcat captures. docs/BENCHMARKING.md gains the usage sections — the flags, how to read the output, and the ways a run can mislead you (steady-state RSS is bimodal, VmSize is not a footprint).

Validation

Used to re-run the V8 pointer-compression A/B end to end — 24 boots, one command — reproducing an earlier throwaway-script measurement independently: peak RSS −12.4 MB, live V8 heap −37.9%, per-round medians non-overlapping.

npm run lint, npm test, npm run backend:test (113) and npm run test:scripts (40) all pass.

Depends on #248 for the default build path (--apk/--ab work without it).

`scripts/benchmark-boot.sh --ab before.apk after.apk` runs interleaved cold
boots of `apps/integration`, alternating which build goes first each round,
discarding the warm-up boot after each install and wiping the compile cache
before every boot so neither build inherits the other's. It prints medians,
deltas, Mann–Whitney p-values and per-round medians — the last being the
check that matters on a machine that is also doing other work.

Peak RSS, RSS and the heap breakdown come from the `[comapeo.memory] boot`
line the backend already logs once per launch, so no root is needed and the
harness works unmodified on a production device; `adb root` only adds a
50 ms `/proc` trajectory on top.

Parsing and statistics live in a pure `scripts/lib/benchmark-core.mjs`
covered by `npm run test:scripts`; the shell wrapper is only device
orchestration. Usage, the flags, how to read the output and the ways a run
can mislead you are in docs/BENCHMARKING.md.
@gmaclennan
gmaclennan force-pushed the feat/boot-benchmark-harness branch from 2a8b8e7 to c87f3d9 Compare August 24, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature (changelog)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant