Every objective evaluation revalidated its optimization configuration. Rule normalization already validates each configuration once per calculation and keeps its own copy, the presets are constant, and the summed variant of a valid configuration stays valid, so the core now scores them without revalidating. evaluateOptimization still validates for other callers. Part of #302. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
111 lines
5.9 KiB
Markdown
111 lines
5.9 KiB
Markdown
# Issue #302: plan from the best-ranked obligation solution
|
|
|
|
Step-by-step record for [issue #302](https://gitea.nessar.fr/nessar/vac-optimizer/issues/302).
|
|
The exact steps keep planning outcomes, stable explanations and final states
|
|
identical to the frozen engine at `a871f8f`. The
|
|
[frozen-engine differential check](README.md#frozen-engine-differential-check),
|
|
including its cancelled asynchronous comparisons, passes after every step.
|
|
|
|
## Per-step measurements
|
|
|
|
Each step was timed against its parent in the same session, on the development
|
|
machine (AMD Ryzen 7 7800X3D, WSL2, Bun 1.4.3), with no other test, build or
|
|
profiling workload running. Both commits' cores were bundled with the
|
|
frozen-engine build command and called through `calculatePlanningAsyncInternal`
|
|
in one Bun process, with `calculationDate: '2024-01-01'`. This is the
|
|
benchmark's in-thread asynchronous path, without the planning-calculation
|
|
service. For every scenario, each engine ran one warm-up and then one measured
|
|
calculation, alternating engines. Outcomes, explanations and final states were
|
|
hashed; every pair below matched. Only same-session pairs are comparable.
|
|
|
|
### Reuse the donor ranking across public-holiday weeks
|
|
|
|
For every public-holiday week, the holiday-week stage ranked every placement as
|
|
a potential donor by releasing it and evaluating the active objectives. That
|
|
ranking depends only on the plan, so the weeks of one plan now share each
|
|
placement's released objectives. Each week still skips its own dates and walks
|
|
the placements in the same order with the same yields.
|
|
|
|
| Scenario | Before (s) | After (s) |
|
|
| --------------------------- | ---------: | --------: |
|
|
| representative year | 0.66 | 0.66 |
|
|
| typed obligations | 5.11 | 4.89 |
|
|
| chained earned entitlements | 0.02 | 0.02 |
|
|
| deliberate conflict | 0.01 | 0.01 |
|
|
| loaded year | 58.26 | 57.75 |
|
|
| two years | 2.27 | 1.82 |
|
|
| three years | 7.45 | 5.52 |
|
|
|
|
### Retain the best valid plan more cheaply
|
|
|
|
Retaining a better valid plan for cancellation reconciled its optimization
|
|
provenance. For every placement credited by an optimization rule, that
|
|
evaluated all active objectives with the placement released. Only the credited
|
|
objectives are compared, so the released plan now evaluates just those, and
|
|
the calendar observations of the other objectives are no longer computed.
|
|
Retention also no longer computes quality metrics that nothing read. An
|
|
instrumented three-year run spent 1.16 of its 1.22 retention seconds in that
|
|
reconciliation; afterwards retention took 0.26 seconds.
|
|
|
|
| Scenario | Before (s) | After (s) |
|
|
| --------------------------- | ---------: | --------: |
|
|
| representative year | 0.45 | 0.37 |
|
|
| typed obligations | 4.76 | 5.03 |
|
|
| chained earned entitlements | 0.02 | 0.02 |
|
|
| deliberate conflict | 0.01 | 0.01 |
|
|
| loaded year | 55.59 | 53.58 |
|
|
| two years | 1.68 | 1.22 |
|
|
| three years | 5.29 | 3.85 |
|
|
|
|
The typed-obligations difference is run-to-run noise; its retention cost was
|
|
22 milliseconds.
|
|
|
|
### Yield between asynchronous slices without a timer
|
|
|
|
The asynchronous adapter yields roughly every eight milliseconds. Each yield
|
|
waited for a zero-delay timer: about 1.1 ms in Bun, and at least 4 ms in
|
|
browsers once timers nest. Browsers now yield through a message-channel task.
|
|
Bun runs port messages ahead of timers and incoming worker messages, so a
|
|
message-channel yield there kept cancellation and the heartbeat from running
|
|
until the calculation ended. Bun therefore yields with `setImmediate`, which
|
|
costs about 0.01 ms and lets both run between slices.
|
|
|
|
| Scenario | Before (s) | After (s) |
|
|
| --------------------------- | ---------: | --------: |
|
|
| representative year | 0.37 | 0.31 |
|
|
| typed obligations | 4.74 | 4.02 |
|
|
| chained earned entitlements | 0.02 | 0.01 |
|
|
| deliberate conflict | 0.01 | 0.00 |
|
|
| loaded year | 53.80 | 46.90 |
|
|
| two years | 1.23 | 1.04 |
|
|
| three years | 3.86 | 3.21 |
|
|
|
|
The browser path was checked in headless Chromium 149 on the same machine, in a
|
|
dedicated worker with a 50 ms heartbeat timer, running the bundled core before
|
|
and after this step, alternating, twice each. The `three years` calculation took
|
|
3.92 and 3.89 seconds before and 2.70 and 2.66 seconds after; `representative
|
|
year` took 0.51 and 0.45 seconds before and 0.30 seconds after. The heartbeat's
|
|
largest gap stayed between 58 and 67 ms in every run. Cancelling `three years`
|
|
one second after the request returned the retained plan 3.9 to 4.0 ms after the
|
|
cancel message reached the worker, against 7.2 to 8.7 ms before. This is desktop
|
|
evidence, not a reference-phone measurement.
|
|
|
|
### Validate each optimization configuration once
|
|
|
|
Every objective evaluation revalidated its optimization configuration against
|
|
the catalog. Rule normalization already validates each configuration once per
|
|
calculation and keeps its own copy. The presets are constant, and the summed
|
|
variant of a valid configuration is valid because every catalog row accepts
|
|
the sum. The core therefore scores them without revalidating;
|
|
`evaluateOptimization` still validates for its other callers.
|
|
|
|
| Scenario | Before (s) | After (s) |
|
|
| --------------------------- | ---------: | --------: |
|
|
| representative year | 0.35 | 0.30 |
|
|
| typed obligations | 4.03 | 3.46 |
|
|
| chained earned entitlements | 0.01 | 0.01 |
|
|
| deliberate conflict | 0.00 | 0.00 |
|
|
| loaded year | 48.12 | 44.03 |
|
|
| two years | 1.04 | 0.96 |
|
|
| three years | 3.35 | 3.03 |
|