# PR #278: reuse counts for immutable calendar dates Measured on 2026-10-16 against `c7e7abc`, which already includes the [direct date-key optimization](pr-278-date-keys.md). 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. ```sh 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](issue-78.md#reproduction).