Repository navigation
perf: memoise Intl formatters in date bucketing (#99) - #109
Merged
Carl723000 merged 2 commits intoSep 22, 2026
Merged
Conversation
Day, month and hour keys are derived once per ingested record, and each call built a new Intl.DateTimeFormat - twice, because resolveTimeZone constructed one of its own. Formatter construction dominates that path: a CPU profile of a pegged extension host attributed 57% of samples to resolveTimeZone and partsInZone alone. Memoise the resolved zone and both formatters per zone. Keys are unchanged, including the empty-zone and invalid-zone fallbacks; the cache holds one entry per configured zone. Measured on a 1.4 GB local history: 1,059 -> 167,982 records/second (158x), 0 key mismatches over the comparison set.
|
🤖 Automated first-pass review The configured analysis model did not return a usable analysis for this pull request. The item has still been received and remains available for maintainer review. To help with review, please ensure the change summary, tests, and any user-facing documentation or localization updates are included. 🤖 Posted automatically by CCU Bot — not a maintainer decision. |
This was referenced Sep 22, 2026
4 tasks done
Carl723000
pushed a commit
that referenced
this pull request
Sep 23, 2026
formatUsageDate called toLocaleDateString once per table row and chart point, constructing a fresh Intl.DateTimeFormat each time. That is the same per-call cost #109 removed from dateKeys, and it showed up at 3-8% self time in extension-host profiles captured while the dashboard was rendering. Formatters are now cached per locale and options. When no date field is requested, the numeric year/month/day default that toLocaleDateString applies is added explicitly, so output stays identical. A new test compares the result against toLocaleDateString for all eight UI locales across several option shapes, including the cached second call. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
Fixes the CPU path reported in #99.
Problem
dayKeyInZone,monthKeyInZoneandhourKeyInZoneare called once per ingested record, and each call constructed a freshIntl.DateTimeFormat— twice, in fact, becauseresolveTimeZonebuilds one of its own to canonicalise the zone. Formatter construction, not parsing, dominates indexing on a large local history.CPU profile taken against a live, pegged extension host (VS Code 1.104, Windows 11, extension 2.3.3, ~1.4 GB of local history in
~/.claude/projects), 6 s at 200 µs sampling:57% of samples are the two functions in
dateKeys.ts. The host held one core at 100% and 2 GB RSS continuously; because live sessions keep appending, the incremental index never catches up.Fix
Memoise the resolved zone and both formatters per zone. Keys are byte-identical, including the empty-zone and invalid-zone fallbacks, and each map holds one entry per configured zone — a handful for the life of the process.
Measurement
200k records, day + hour key for each,
Asia/Yekaterinburg, Node 24.8, old implementation inlined next to the new one in the same process:158x, with 0 key mismatches across the comparison set.
Tests
Two cases added to
src/test/dateKeys.test.ts: one proves the formatter is built once per zone and not per record (counting constructor viaProxy, in a zone the other cases do not touch, so the cache starts cold), one guards that memoised zones keep their calendars apart.dateKeyssuite: 14/14 pass. Fullnpm teston this machine: 1026/1036 pass. The 9 failures are all Windows filesystem-permission cases (EPERM: symlink, temp-dir rename/rmdir races) in the Codex lease and manifest suites; the same files fail identically on a cleanmainhere (155/163 both before and after), so they are environmental and unrelated to this change.