Reuse prepared execution snapshot ownership
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
Implement the remaining local work in the [performance roadmap](performance.md)
|
||||
in order. Each sequential stage is scoped for one Luna coding-agent prompt.
|
||||
Update status and evidence as each work unit lands.
|
||||
Stages 1–12 are complete; Stages 13–14 remain pending. The completed
|
||||
Stages 1–13 are complete; Stage 14 remains pending. The completed
|
||||
inspection plan is preserved at
|
||||
`481e2d4:docs/roadmap/implementation.md` in Git history.
|
||||
|
||||
@@ -496,9 +496,17 @@ message length as deep-copied bytes, and document lifetime assumptions.
|
||||
|
||||
## Stage 13 — Conditionally Consolidate Prepared Creation's First Snapshot Copy
|
||||
|
||||
**Outcome:** Either one justified creation-copy simplification with preserved
|
||||
ownership, or a completed, evidence-backed decision to retain the current
|
||||
implementation. This does not authorize skipping measurement or ownership work.
|
||||
**Status: Complete (2026-10-09).** The selected transfer was retained. Prepared
|
||||
execution now reuses preparation-owned messages, hashes, and schema, while
|
||||
deep-copying nested provider extras and keeping an independent details
|
||||
snapshot. Source-mutation and invalid-copy coverage pass; benchmark evidence
|
||||
shows meaningful reductions for mutable payloads without a material increase
|
||||
in retained heap.
|
||||
|
||||
**Outcome:** The ownership inventory supports transferring preparation-owned
|
||||
values. The simplified creation path is retained with its nested-extra copy,
|
||||
independent details snapshot, and existing cleanup and caller-ownership
|
||||
boundaries.
|
||||
|
||||
**Selected candidate:** Transfer preparation's already-owned messages, hashes,
|
||||
and schema into its private execution payload instead of deep-copying them
|
||||
@@ -892,6 +900,68 @@ separate details clone. Focused verification passed: `go test -mod=readonly
|
||||
./internal/usecase .`; representative content, copied schema, fake validation
|
||||
status, and post-completion details were checked outside timing.
|
||||
|
||||
### Prepared Creation Snapshot Comparison
|
||||
|
||||
The before measurements use the Stage 11 assembled benchmark fixture committed
|
||||
at `743e78d` and the Stage 12 ownership fixture committed at `11ecb92`. The
|
||||
after measurements use the Stage 13 candidate in this completion. Both runs
|
||||
used the same fixtures and environment: Linux/amd64, Intel Core i5-7260U @
|
||||
2.20 GHz, benchmark parallelism 4, Go 1.26.8, ConfigKit `v0.5.0`, JSON Schema
|
||||
`v6.0.2`, and backend modules `v3.20260930.0`. Benchmarks ran without the race
|
||||
detector. The commands are those in the Assembled Workflow Benchmark Baseline
|
||||
and Prepared Snapshot Ownership And Live-Heap Baseline subsections above.
|
||||
|
||||
The assembled creation benchmark measures `PrepareExecution` followed by
|
||||
discarding its unused handle. Times list five `ns/op` samples, then median and
|
||||
range; allocations are `B/op; allocs/op`.
|
||||
|
||||
| Case | Before `ns/op` (median; range) | Before allocations | After `ns/op` (median; range) | After allocations |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Small | 8194, 8016, 8095, 8073, 7939 (8073; 7939–8194) | 5210; 56 | 11028, 11059, 11756, 12279, 11089 (11089; 11028–12279) | 4665; 53 |
|
||||
| Large message | 937857, 955672, 919810, 1058503, 1094114 (955672; 919810–1094114) | 873679–873681; 56 | 1751124, 1647596, 1761392, 1556071, 1584325 (1647596; 1556071–1761392) | 873135–873144; 53 |
|
||||
| Mutable payload | 8114785, 8394320, 10387083, 8418604, 8528766 (8418604; 8114785–10387083) | 3711282–3711329; 60727 | 12157300, 12363416, 12185745, 11868982, 21225784 (12185745; 11868982–21225784) | 3483089–3483252; 56324–56326 |
|
||||
|
||||
Small and large cases each save about 0.5 KB and three allocations, while the
|
||||
mutable case saves about 228 KB and 4,401–4,403 allocations. The after timing
|
||||
samples in this run are higher than the recorded before samples, while other
|
||||
repetitions on the same machine varied substantially; the timing evidence
|
||||
does not establish a reliable latency improvement or regression. The ordinary
|
||||
`Prepare`, `Run`, and public `Details()` allocation counts are unchanged within
|
||||
their recorded baseline ranges; this candidate only changes prepared-execution
|
||||
creation.
|
||||
|
||||
The focused internal snapshot benchmark isolates the same creation path using
|
||||
the Stage 12 fake-collaborator fixture. Times again list five samples, median,
|
||||
and range.
|
||||
|
||||
| Snapshot case | Before `ns/op` (median; range) | Before allocations | After `ns/op` (median; range) | After allocations |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Small | 45776, 51524, 46933, 46834, 44663 (46834; 44663–51524) | 13014–13016; 216 | 50907, 79812, 62186, 65569, 62599 (62599; 50907–79812) | 9405–9406; 156 |
|
||||
| Mutable payload | 5343223, 5234718, 4213550, 4419520, 5046181 (5046181; 4213550–5343223) | 1211931–1212104; 25243–25244 | 5991662, 5508812, 6244981, 5176459, 4365122 (5508812; 4365122–6244981) | 983033–983309; 20837–20839 |
|
||||
|
||||
The internal fixture saves about 3.6 KB/60 allocations for the small case and
|
||||
about 229 KB/4,404–4,407 allocations for the mutable case. Timing samples vary
|
||||
between repeated runs and do not establish a consistent speedup or regression.
|
||||
|
||||
The retained-heap comparison uses the documented fixed batch of four mutable-
|
||||
payload handles. These are five independently repeated `retained-B` samples
|
||||
after the candidate; before samples are recorded in the baseline subsection.
|
||||
|
||||
| Handle state | Before samples (median; range) | After samples (median; range) |
|
||||
| --- | --- | --- |
|
||||
| Ready | 1458352, 1458256, 1459320, 1459048, 1459160 (1459048; 1458256–1459320) | 1458936, 1459048, 1460592, 1460464, 1460192 (1460192; 1458936–1460592) |
|
||||
| Completed | 731040, 730768, 729352, 729448, 729624 (729624; 729352–731040) | 731312, 730496, 730768, 730544, 731040 (730768; 730496–731312) |
|
||||
| Discarded | 728560, 730928, 730544, 730496, 730496 (730496; 728560–730928) | 731040, 731088, 730720, 730768, 730608 (730768; 730608–731088) |
|
||||
|
||||
All before/after retained ranges overlap. The median shifts are about 1.1 KB
|
||||
for ready and completed handles and 272 B for discarded handles, all small
|
||||
relative to their live sets and within observed run-to-run variation. This is
|
||||
not evidence of a material retention increase, nor an exact object-size
|
||||
guarantee. Together with the measured allocation reduction and mutation tests,
|
||||
it supports retaining the simple ownership transfer while keeping the nested
|
||||
extra-map copy, details clone, lifecycle cleanup, and caller-owned conversions.
|
||||
Focused validation passed: `go test -race -mod=readonly ./internal/usecase .`.
|
||||
|
||||
### Validation And Compiled-Rendering Baseline
|
||||
|
||||
The benchmark-only baseline is commit
|
||||
|
||||
Reference in New Issue
Block a user