Repository navigation
perf(time): cache Intl.DateTimeFormat in getLocalHourAndMinute - #770
Closed
progremister wants to merge 1 commit into
Closed
progremister wants to merge 1 commit into
progremister wants to merge 1 commit into
Conversation
CPU profiling of the planner calendar layout (node --cpu-prof) showed getLocalHourAndMinute at 86% of runtime: every call constructed two Intl.DateTimeFormat instances, one only to validate the timezone in isValidIanaTimezone. - memoize isValidIanaTimezone verdicts per identifier (bounded map) - reuse one hour/minute formatter per timezone (bounded map) - add regression tests for cached validation and formatters - add a deterministic profiling scenario and a .cpuprofile summarizer Week render (7 days x 40 events, 2240 calls): 258.96 ms -> 3.72 ms median (~70x faster), identical layout checksum.
|
@dm-kolos is attempting to deploy a commit to the Vicky's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Caution Review failedThe pull request is closed.
Warning Some tools did not complete. Review the errors below.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Časová (CPU) profilácia rozloženia udalostí v plánovacom kalendári (Day/Week view) ukázala,
že 86 % času behu zaberá funkcia
getLocalHourAndMinutezo src/lib/time.ts.Funkcia pri každom volaní vytvárala dve nové inštancie
Intl.DateTimeFormat:isValidIanaTimezoneiba kvôli overeniu, či je časové pásmo platné,Konštrukcia
Intl.DateTimeFormatje drahá operácia (načítanie ICU dát o lokalizácii a časovom pásme),pričom jej výsledok je pre rovnaké časové pásmo vždy rovnaký. Úprava preto:
isValidIanaTimezonepre každý identifikátor časového pásma,Intl.DateTimeFormatsú nemenné, takže ich zdieľanie je bezpečné),Výsledok rozloženia je bitovo rovnaký (rovnaký kontrolný súčet), mení sa iba čas vykonávania:
258,96 ms → 3,72 ms na jedno vykreslenie týždňa (≈ 69,6× rýchlejšie, −98,6 %).
Typ profilácie a nástroj
node --cpu-prof). Nevyžaduježiadnu inštaláciu, je open source a beží lokálne bez odosielania dát. Výsledný súbor
.cpuprofilesa dá otvoriť aj v Chrome DevTools (karta Performance) alebo na speedscope.app.(bez závislostí) zo súboru
.cpuprofilevypíše najdrahšie funkcie podľa self a total času.Scenár merania
Automatizovaný a deterministický skript scratch/profile-calendar-layout.ts
simuluje vykreslenie týždenného plánovača:
Europe/Bratislava,computeTimelineRangepre celý týždeň +layoutHorizontalEventsa
layoutVerticalEventspre každý deň, teda 2 240 volanígetLocalHourAndMinute,process.hrtime.bigint(), porovnáva sa medián,Spustenie:
Prostredie: macOS (Darwin 25.6), Node.js v26.8.1.
Nájdený bottleneck (pred úpravou)
Celý výstup: before.txt
Interpretácia: samotná logika rozloženia (triedenie, prideľovanie pruhov/stĺpcov) je zanedbateľná.
Takmer celý čas sa minie v natívnom konštruktore
Intl.DateTimeFormat. Profiler ho pripisujevolajúcim funkciám
getLocalHourAndMinute(48,3 % self) aisValidIanaTimezone(37,4 % self).Jedno volanie
getLocalHourAndMinutetrvalo približne 115 µs.Po úprave
Celý výstup: after.txt
Po úprave zostáva v
getLocalHourAndMinuteuž iba volanieformatToParts. V profile sa navyšeobjavujú položky z
babel.cjsareadFileUtf8, čo je jednorazová transpilácia TypeScriptunástrojom jiti pri štarte. Pred úpravou bola voči 13 s behu zanedbateľná.
Porovnanie
getLocalHourAndMinutegetLocalHourAndMinute(total) v profileisValidIanaTimezone(self) v profilePrečo je to dôležité: tieto funkcie sa volajú pri každom renderi komponentov
planner-day-view,planner-week-viewadaily-calendar-widget. Pri plnom týždni tedavýpočet rozloženia klesol z ~260 ms (viditeľné zaseknutie UI, viac ako 15 snímok pri 60 FPS)
na ~4 ms.
isValidIanaTimezonesa navyše volá v takmer každej funkcii vtime.ts,takže memoizácia zrýchľuje aj ostatné časové pomocné funkcie.
Zmeny
src/lib/time.tsisValidIanaTimezone: memoizácia výsledku v ohraničenejMap<string, boolean>.getLocalHourAndMinute: jedenIntl.DateTimeFormatna časové pásmo v ohraničenejMap.tests/temporal-engine.test.ts: nový blok testov. Overuje, že opakované a prekladané volaniapre rôzne pásma (
Asia/Kolkata,America/New_York,UTC) vracajú správne hodnoty,že neplatné pásmo zostáva neplatné aj z cache a stále padá na UTC, a že neplatný dátum vracia
0:00.scratch/profile-calendar-layout.ts: reprodukovateľný profilovací scenár (benchmark).scratch/summarize-cpuprofile.mjs: textový súhrn súboru.cpuprofilebez závislostí.docs/profiling/calendar-layout/: výstupy profilácie pred a po úprave a tento popis.Overenie
npm test: 102/102 test suites prešlo (vrátanetemporal-engine,calendar-domain-validation,planner-ux-validation).npm run typecheck(tsc --noEmit): bez chýb.eslint src/lib/time.ts: bez chýb.Možné ďalšie kroky (mimo rozsahu tohto MR)
Rovnaký vzor (
new Intl.DateTimeFormatpri každom volaní) sa nachádza aj v ďalších funkciáchv
time.ts, napr.getLocalDateString,getIsoWeekAndYear,utcToDatetimeLocalInput,getTimezoneOffsetMinutes(volaná zlocalToUtc) agetWeekDaysForDate. Tie sa dajú zrýchliťrovnakou cache formátovačov, ak ich profilácia v inom scenári označí za úzke miesto.