62 lines
3.1 KiB
Markdown
62 lines
3.1 KiB
Markdown
# 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).
|