From 368fcfb6f082f365c1c8ba418f179d84d4dd0217 Mon Sep 17 00:00:00 2001 From: Senrokai Date: Wed, 30 Sep 2026 15:51:41 +0200 Subject: [PATCH] Keep each spectral type's giant surface once, rather than reparse it for every star at boot The star field reads every star's temperature at boot, and each read asked giantSurface, which splits the type and runs two regular expressions whether or not the star is a giant: 455 571 times for 2 888 distinct type strings. It depends on the type alone, so it is now kept per type. The tint pass over the published catalogue gives the same colours (checksum 5 830 745.929 before and after) and in Node takes 167-237 ms against 241-305. In the running app, the star field rebuilt in the page three times after each of four cold boots: median 65 ms before (60-79), 51 and 53 ms after in two runs (46-67). The longest task after the data lands did not move beyond the noise (median 851 ms before, 859 and 827 after): most of the boot growth since c38a42c is the larger catalogue and the per-star colour lookup, which the tint needs. Memoising colorIndexToRgb on its three inputs, the fix the review also named, would not help: 337 998 of the 455 571 triples are distinct, and reviewers measured it 260-370 ms slower. No behaviour changes, so no new test; the suite (819) passes as before. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/app/shared/astro/stellar.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/app/shared/astro/stellar.ts b/src/app/shared/astro/stellar.ts index 006542a..1f7383b 100644 --- a/src/app/shared/astro/stellar.ts +++ b/src/app/shared/astro/stellar.ts @@ -194,7 +194,19 @@ export function effectiveTemperatureK(star: StellarPhotometry): number | null { * a few per cent of from B8 on, and a few thousand kelvin cooler than at B0 (Alnilam, B0 Ia, about * 27 000 K against B0 V's 31 400). Carbon and S stars take {@link CARBON_STAR}. */ -export function giantSurface(spectralType: string | null | undefined): { temperatureK: number; bolometricCorrectionV: number } | null { +export function giantSurface(spectralType: string | null | undefined): GiantSurface | null { + // ponytail: kept per type string, unbounded; the catalogue has 2 888 of them. The star field asks + // for each of its 455 571 stars at boot, and the split and two regular expressions took 20-40 ms. + if (!GIANT_SURFACES.has(spectralType)) { + GIANT_SURFACES.set(spectralType, giantSurfaceOfType(spectralType)); + } + return GIANT_SURFACES.get(spectralType)!; +} + +type GiantSurface = { temperatureK: number; bolometricCorrectionV: number }; +const GIANT_SURFACES = new Map(); + +function giantSurfaceOfType(spectralType: string | null | undefined): GiantSurface | null { if (!isGiant(spectralType)) { return null; }