From ff90510c380b47a23d0ac1cd8c314b1c4366a15b Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Fri, 9 Oct 2026 00:10:13 +0000 Subject: [PATCH] Record the computational efficiency roadmap --- docs/roadmap/performance.md | 163 ++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 docs/roadmap/performance.md diff --git a/docs/roadmap/performance.md b/docs/roadmap/performance.md new file mode 100644 index 0000000..c52cc93 --- /dev/null +++ b/docs/roadmap/performance.md @@ -0,0 +1,163 @@ +# Computational Efficiency Roadmap + +**Status:** Proposed; implementation pending. + +## Objective And Scope + +Reduce the time, allocations, retained memory, and repeated I/O of routine +release operations. Implement improvements behind the existing `releasekit` +and `buildinfo` facades, following the +[architecture policy](../policy/architecture.md) and +[routine-release priorities](../adr/0002-routine-releases.md). + +This roadmap captures the computational efficiency review of commit `db9e24f` +on 2026-10-09. It owns proposed work and sequencing. The +[internal inventory](../internal/overview.md) and focused internal documents +own implemented behavior; Go declarations and GoDoc own public contracts. + +## Review Evidence + +Temporary offline probes produced the following local measurements: + +| Probe | Result | +| --- | --- | +| Read 1,000 unique committed Go blobs totaling 59,670 bytes through the existing path | 1.83–2.00 seconds across three runs. | +| Read and verify the same blobs through one Git batch command | 48–59 milliseconds across three runs. | +| Read a cached 1 MiB blob | One allocation of 1 MiB per read. | +| Resolve runtime version through the Go build metadata fallback in a test executable | Approximately 2 microseconds, 1,184 allocated bytes, and seven allocations per call. | +| Resolve an injected runtime version | Zero allocations. | + +The blob timings cover content access, with tree metadata discovery measured +separately. They exclude Go tests, compilation, formatting, and Markdown parsing. +The fixture contained small, loose Git objects. These are component measurements +on one machine; overall release gains depend on consumer workloads. The probes +were temporary and left the repository unchanged. + +Static review also identified repeated artifact hashing and unconditional Go +output copying. Their workload impact remains to be measured. + +## Priorities + +| Priority | Improvement | Expected benefit | +| --- | --- | --- | +| High | Batch selected Git blob reads | Amortize subprocess startup and object access across many files. | +| High | Clarify file-content ownership and selective caching | Reduce copies and memory retained across validation checks. | +| Medium | Consolidate artifact hashing | Reduce repeated full-file reads and SHA-256 calculations. | +| Lower | Avoid unnecessary Go-output copies | Reduce allocation and peak memory for commands with large diagnostics. | +| Low | Cache runtime version fallback | Reduce repeated metadata parsing when consumers call the accessor frequently. | + +## Implementation Sequence + +### 1. Establish Representative Measurements + +- Add a small set of offline benchmarks covering many unique Git blobs, + repeated reads, large source or Markdown files, and artifact hashing. +- Record elapsed time, allocations, retained memory where relevant, and bytes + processed. Separate Git content access from formatting, parsing, and Go work. +- Include repeated object IDs and packed objects to reflect useful cache and + batching cases. Use temporary local Git repositories and local HTTP fixtures. +- Measure representative complete check and delivery workflows locally to + distinguish component gains from overall gains. + +Follow the [testing policy](../policy/testing.md) for proportionate behavioral +coverage and fixture isolation. The +[development guide](../development.md) owns validation commands and synthetic +module-cache isolation requirements. Benchmark results inform implementation; +machine-specific timings remain measurements. + +### 2. Improve Blob Access And File-Content Ownership + +Owners: [Git object access](../../internal/git/source.go), +[candidate tree](../../internal/validation/tree.go), and +[Markdown parsing cache](../../internal/validation/markdown.go). + +- Introduce an operation-scoped, streaming Git batch reader for selected blobs. + Retain lazy selection and object-ID deduplication. +- Manage child-process lifetime explicitly, including completion, cancellation, + cleanup, and useful failures for missing local objects or malformed responses. + Preserve the existing offline object-access behavior. +- Define ownership of cached and returned bytes. Use immutable internal reads + where consumers can safely share contents, and preserve isolation where + mutation or caller ownership requires copies. +- Retain reusable data selectively. Formatting generally consumes source once; + Markdown checks already reuse parsed documents. Measure the tradeoff between + retained raw contents and rereads of shared objects or symlink text. +- Consume batch results incrementally to reduce temporary content allocations. + +Reuse existing formatting, Markdown, committed-source, and destination-resolution +tests. Extend coverage for realistic batching, cancellation, and ownership risks. +Compare allocation and retained-memory results with the baseline as well as +elapsed time. + +### 3. Consolidate Artifact Hashing + +Owners: [builder](../../internal/build/build.go), +[delivery declarations](../../internal/delivery/assets.go), +[delivery orchestration](../../internal/delivery/delivery.go), and +[asset verification and upload](../../internal/gitea/upload.go). + +A fresh managed delivery currently hashes each missing binary during building, +declaration construction, local verification, and upload preflight. Each pass +streams its input; repeated passes add work proportional to artifact size. + +- Consolidate adjacent declaration and asset verification work in one internal + owner and reuse the digest and size it computes. +- Reuse freshly computed metadata within managed delivery while artifact + ownership remains with that operation. +- Preserve meaningful verification boundaries for caller-supplied prebuilt + artifacts, detection of changed contents, and accurate partial-delivery results. +- Preserve exact remote content comparison and targeted reconciliation after + uncertain writes, as described by the + [Gitea integration contract](../integrations/gitea.md). + +Measure large-artifact delivery for fresh uploads and retries. Reuse existing +tampering, conflicting-content, partial-delivery, and additive-retry tests. + +### 4. Reduce Go-Output Copying + +Owner: [Go command execution](../../internal/gotool/gotool.go). + +Go command execution currently retains combined output and copies the complete +buffer before returning, including for callers that discard the returned bytes. + +- Distinguish output-consuming commands, such as compiler identification, from + commands whose callers consume status and diagnostics. +- Eliminate unnecessary final copies for status-only callers while preserving + forwarded output and failure diagnostics. +- Evaluate disk-backed diagnostic capture if measured large-log workloads + justify its filesystem and lifecycle costs. + +Measure allocations and peak memory with ordinary output and large diagnostics. +Preserve cancellation, command failure attribution, and output-writer behavior. + +### 5. Cache Runtime Version Fallback + +Owner: [runtime version implementation](../../internal/runtimeinfo/version.go). + +- Cache the immutable result of the Go build metadata fallback internally using + a proportionate standard-library mechanism. +- Preserve injected-version precedence, main-module version selection, and the + development fallback defined by the runtime facade. +- Keep the [runtime dependency boundary](../policy/architecture.md#runtime-version-boundary) + intact and verify concurrent access if caching introduces shared state. + +Compare repeated fallback access with the already inexpensive injected path. +This work has limited impact for consumers that read their version once. + +## Completion And Follow-Up + +Implement and validate the work in priority order, then report the measured +results and any remaining opportunities for review. Run the applicable existing +behavioral suite and facade checks using the developer guide. Update canonical +internal documentation when each implementation lands. + +Preserve the efficient foundations already present: batched tree metadata, +deduplicated object access, parsed Markdown reuse, streamed artifact I/O, one +selected Go test suite, native artifact reuse for version smoke checks, and +source-only delivery without compilation. Publication guards and exact content +comparisons remain part of the release procedure throughout this work. + +Summarize component and complete-workflow results with workload descriptions and +measurement limitations. Record lower-priority opportunities as completed or +deferred according to their measured benefit and maintenance cost. Retire this +roadmap when its work and disposition are recorded in the appropriate owners.