Files
compiler-explorer/test/app
Matt Godbolt 643b6db82a Avoid redundant serialisation work in the startup tail (#9043)
Profiling a production startup (2026-08-20, 6232 compilers) showed two
avoidable CPU costs in the last couple of seconds of startup:

- `setupCompilerChangeHandling`'s `onCompilerChange` ran
`JSON.stringify` over all 6232 compiler objects purely to detect whether
the compiler set had changed since the last discovery. The serialised
form is comparable in scale to the 74MB discovery JSON, and it was
computed (and retained in memory) even in production, where rescanning
is disabled (`rescanCompilerSecs` unset / `--prediscovered`) and so the
comparison can never trigger.
- The `OPTIONS HASH` log line appeared twice per startup:
`ClientOptionsHandler`'s constructor eagerly serialised and hashed the
options blob, only for the result to be immediately discarded and
recomputed by the first `setCompilers()` call.

Changes:

- `lib/app/compiler-changes.ts`: only do change detection when
rescanning is actually enabled, and compare a SHA-256 content hash
instead of retaining the full serialised compiler list. In production
the initial set is now applied with no serialisation at all; with
rescanning enabled, behaviour is unchanged (identical rescans are
skipped, changed sets applied) while dropping the tens-of-megabytes
retained string.
- `lib/options-handler.ts`: drop the constructor's
`_updateOptionsHash()` call. The hash/JSON are computed exactly once at
startup by the first `setCompilers()`, which always runs before the
server starts listening.

Tests: new `test/app/compiler-changes-tests.ts` covering initial
application, no rescan when prediscovered, unchanged rescans skipped,
and changed rescans applied; plus an options-handler test pinning that
the hash is only computed once compilers are set. `ts-check`, `lint`,
and the full test suite pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-24 19:34:52 -05:00
..