Measure output capture allocations for chunked writes

This commit is contained in:
2026-10-09 03:08:51 +00:00
parent 7d92c477c2
commit 6376ef23f1
4 changed files with 72 additions and 16 deletions

View File

@@ -150,7 +150,8 @@ before timing. The fixture server retains only digest and size metadata for
uploads and streams known matching bytes directly from shared fixture content.
Output measurements call the combined writer directly, with forwarding to
`io.Discard`, then capture its completed buffer. They include the current
`io.Discard`, then capture its completed buffer. Each baseline and final
comparison writes its complete input in one call. The baseline includes the
completed-output copy. Runtime fallback measurements call `Version()` repeatedly
against real build metadata; injected access measures the selection helper's
injected-version branch. The benchmark process reports its own allocations,
@@ -163,8 +164,8 @@ the fixture server.
| Declarations plus local verification | 186.7–188.4 ms; 33,554,432 binary bytes per each of two passes; about 136.2 KB allocated. | 94.3–95.3 ms; one 33,554,432-byte verification pass; about 69.7 KB and 58–59 allocations. |
| Facade delivery, fresh uploads | 429–447 ms; 32 MiB binary payload, two files plus manifest; 1.43–1.46 MB allocated. | 331.9–415.3 ms; same payload; 1.38–1.39 MB allocated. |
| Facade delivery, matching retry | 309.1–310.0 ms; 32 MiB of local verification plus streamed remote comparisons; 1.21–1.22 MB allocated. | 210.7–217.5 ms; same local verification and streamed comparisons; 1.15 MB allocated. |
| Combined output, 4 KiB and `io.Discard` | 1.82–1.87 μs; 8,256 B and 3 allocations per operation. | 0.94–1.06 μs; 4,176 B and 2 allocations. |
| Combined output, 8 MiB and `io.Discard` | 2.02–2.36 ms; 16.78 MB and 3 allocations per operation, including the completed capture copy. | 1.73–2.22 ms; about 8.39 MB and 2 allocations. |
| Combined output, one 4 KiB write and `io.Discard` | 1.82–1.87 μs; 8,256 B and 3 allocations per operation. | 0.94–1.06 μs; 4,176 B and 2 allocations. |
| Combined output, one 8 MiB write and `io.Discard` | 2.02–2.36 ms; 16.78 MB and 3 allocations per operation, including the completed capture copy. | 1.73–2.22 ms; about 8.39 MB and 2 allocations. |
| Injected version selection | 0.745–0.754 ns; 0 B and 0 allocations. | 0.754–0.758 ns; 0 B and 0 allocations. |
| Repeated real metadata fallback | 1.438–1.474 μs; 1,184 B and 7 allocations per operation. | 4.59–4.65 ns after cache initialization; 0 B and 0 allocations. Separate initialization: 1.54–2.14 μs; 1,264 B and 9 allocations. |
@@ -173,6 +174,31 @@ these fixtures. The output component benchmark does not include child startup;
the real delivery benchmark does include HTTP request handling. These results
describe measured workloads and do not establish runtime guarantees.
### Output Chunking Follow-Up
The R3 follow-up extends `BenchmarkPerformanceCombinedOutput` with 32 KiB
writes. Three repetitions on Go 1.26.8, linux/amd64, and the Intel Core i5-7260U
used the completed writer at `7d92c47` with the extended benchmark:
```sh
GOPROXY=off GOSUMDB=off GOTOOLCHAIN=local go test ./internal/gotool -run '^$' -bench '^BenchmarkPerformanceCombinedOutput$' -benchmem -count=3 -benchtime=1s
```
| Workload, forwarding to `io.Discard` | Elapsed time | Total allocated bytes/op | Allocations/op | Returned output length |
| --- | --- | --- | --- | --- |
| One 8 MiB write | 1.49–1.56 ms | 8,388,697–8,388,702 | 2 | 8,388,608 bytes |
| 32 KiB writes totaling 8 MiB | 2.56–2.93 ms | 16,744,532–16,744,541 | 10 | 8,388,608 bytes |
Both workloads verify complete captured and forwarded bytes outside the timed
region. Measurements include capture and forwarding to `io.Discard`, excluding
subprocess costs and failure diagnostic strings. Total allocated bytes count
all allocations during an operation, including superseded buffers. The returned
slice retains the final backing buffer; its logical output length is 8 MiB in
both cases. Peak live memory was not measured and depends on buffer growth,
garbage collection, and other command work. These results describe the measured
workloads and establish no numerical runtime guarantee. Both paths transfer the
completed buffer without the former final copy.
### Final Comparison Record
The final benchmark run measured commit `42569b4`, before this Stage 11 record
@@ -215,8 +241,8 @@ fresh uploads measured 331.9–415.3 ms and matching retries 210.7–217.5 ms. A
retry still reads and verifies local assets and compares streamed remote bytes;
those fixture and remote-comparison costs remain in the complete workflow.
Output capture allocations fell from 8,256 B to 4,176 B for 4 KiB, and from
about 16.78 MB to 8.39 MB for 8 MiB. The 8 MiB timing ranges overlap, while one
For single-write workloads, output capture allocations fell from 8,256 B to
4,176 B for 4 KiB, and from about 16.78 MB to 8.39 MB for 8 MiB. The 8 MiB timing ranges overlap, while one
allocation and the completed-buffer copy are removed. The returned capture
remains caller-owned in memory; a failed output command can also retain its
diagnostic string. Warm runtime fallback access measured 4.59–4.65 ns and zero
@@ -565,8 +591,8 @@ artifact compilation use `Run`; compiler identification uses `Output`.
Preparation retains its network-capable environment and formats diagnostics
from the transferred buffer. Go tool fixtures cover forwarded output, large
failure output, cancellation, and writer failure. Go tool, validation, build,
facade, preparation, and CLI tests passed. The combined-output benchmark now
measures 1.0–1.1 µs and 4,176 B/2 allocations for 4 KiB, and 1.51–1.56 ms and
facade, preparation, and CLI tests passed. The single-write combined-output
benchmark now measures 1.0–1.1 µs and 4,176 B/2 allocations for 4 KiB, and 1.51–1.56 ms and
8,388,699–8,388,703 B/2 allocations for 8 MiB. The Stage 2 8 MiB result was
2.02–2.36 ms and about 16.78 MB/3 allocations, including its capture copy.
The returned 8 MiB slice remains caller-owned in memory; failed Output also

View File

@@ -1,6 +1,6 @@
# Performance Implementation Remediation
**Status:** Remediation in progress; R1–R2 complete.
**Status:** Remediation in progress; R1–R3 complete.
**Review baseline:** df064bd, reviewed on 2026-10-09 against the
[performance target](performance.md) and
@@ -126,6 +126,13 @@ design; these findings do not require disk-backed diagnostics or a memory cap.
and confirm captured bytes and forwarding remain correct. Report allocation
results as workload-specific measurements with no numerical runtime guarantee.
**Completion:** Complete. The benchmark now includes equal 8 MiB output in one
write and 32 KiB chunks, with untimed byte-for-byte capture and forwarding checks.
Three repetitions passed and measured about 8.39 MB/2 allocations and
16.74 MB/10 allocations respectively. Go-output documentation and implementation
results qualify the single-write figures and distinguish allocation totals,
retained output, and unmeasured peak memory.
## R4: Reconcile Feature And Implementation Status
**Priority:** Low.