3.1 KiB
PR #278: reuse counts for immutable calendar dates
Measured on 2026-10-16 against c7e7abc, which already includes the
direct date-key optimization.
A loaded-year CPU profile attributed 4.06 of 69.37 seconds to repeatedly counting
distinct non-working dates for time-off-period objectives. The existing calendar
cache already shares frozen date arrays between candidate plans, but each score
rebuilt a Set to count the same dates again.
The objective evaluator now keeps those counts in a WeakMap keyed by the frozen
array. Mutable arrays are recounted on every evaluation. The weak keys allow
unused arrays to be collected, and configuration validation and duplicate-date
handling remain intact. This change touches only that scoring operation.
Before and after
Both protocol runs used Node 24.18.0, Bun 1.3.14 and Vitest 5.0.3 on the same local
machine. The baseline is the completed run recorded for c7e7abc; its saved core
bundle is byte-for-byte identical to a fresh bundle of that commit. No other
test, build or profiling workload ran alongside either protocol measurement.
NODE_OPTIONS=--max-old-space-size=2048 timeout 300s bunx vitest run src/app/benchmark/leave-planner-benchmark.spec.ts --maxWorkers=1
All seven warm-ups, fourteen measured calculations, the typed-obligation precheck, fixtures, assertions and resource limits remain unchanged.
| Measurement | Before | After |
|---|---|---|
| Entire command, external wall time | 268.573 s | 256.034 s |
| Benchmark test | 263.265 s | 250.652 s |
| Loaded year, mean of two measured calculations | 67.747 s | 64.360 s |
| Headroom before timeout | 31.427 s | 43.966 s |
The full command was 4.7% faster in this pair. Both runs completed successfully, and every repeated scenario remained deterministic. Live CI performance still needs confirmation.
An isolated check using the loaded-year plan's frozen date arrays took 551–554 ms before and 46–57 ms after for 100,000 scoring calls, following 5,000 warm-ups per run in before/after/after/before order. That result isolates the repeated counting cost; the protocol above measures its effect on complete calculations.
Correctness checks
Complete outcomes, stable explanations and final-state snapshots match c7e7abc
for all seven scenarios. These separate comparisons ran alongside functional
checks; their diagnostic timings are not used in the protocol comparison.
The functional coverage suite passes all 638 tests across 33 files. Three new
regression cases cover duplicate dates and changes to mutable arrays alongside
frozen arrays for sum, count and maximum scores. Application and spec type checks,
lint, formatting and git diff --check also pass.
No browser timing run or live CI rerun was performed for this change.
Diagnostic sources, profiles, bundles and full logs are retained in
/tmp/vac-opt278-step2. The original core diagnostic runner is documented in
issue-78.md.