mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2026-09-10 18:08:29 -04:00
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>