Record selected performance approaches

This commit is contained in:
2026-10-09 00:39:07 +00:00
parent f9b0454f34
commit 6612b54e2a

View File

@@ -1,6 +1,6 @@
# Computational efficiency roadmap
Status: proposed; implementation has not begun.
Status: proposed improvements; OD-1 and OD-2 resolved; implementation has not begun.
Date: 2026-10-09.
@@ -31,7 +31,7 @@ or promised speedups. Recheck the affected implementation before starting work.
| PF-01 | PromptKit text reports are built even for YAML requests. | Render only the requested format and avoid redundant report buffers. | First pass |
| PF-02 | Selected-command lookup scans a map; each ancestor is rediscovered from the root. | Direct declaration lookup and ancestry traversal proportional to path depth. | First pass |
| PF-03 | Every invocation translates and sorts metadata; help and usage construct another backend tree. | Reuse immutable metadata and the invocation's prepared tree. | Measure and improve after the first pass |
| PF-04 | Aggregate YAML framing splits every line and copies the complete native document. | Inspect only the opening lines; assess eliminating the complete framed copy. | Prefix scanning in the first pass; copying afterward |
| PF-04 | Aggregate YAML framing splits every line and copies the complete native document. | Inspect only the opening lines and retain a complete framed buffer for delivery. | First pass |
| PF-05 | Each registration copies the existing top-level registry. | Prepare new entries separately and install a validated batch atomically. | Lower priority |
| PF-06 | Scope ordering, lookup, and selection repeat; selector duplicate checks scan previous entries. | Prepare stable scope metadata once and use direct duplicate checks. | Lower priority |
@@ -130,13 +130,14 @@ second backend construction also benefits a single CLI help or usage request.
Measure both cases separately, including the cost of app construction and
registration for consumers that execute only once.
Reusing mutable backend trees across different invocations is a later option,
conditional on measured benefit and a clear account of state reset and value
ownership. The first target can retain fresh backend parse state for each
invocation. No public freeze step, backend selector, or concurrent-dispatch
Under the selected OD-1 approach, construct fresh mutable backend parse state for
each invocation, reuse that state within the invocation, and cache immutable
metadata between invocations. Reusing mutable backend trees across invocations
is deferred beyond this target. Measurements may motivate reconsidering it in
future work. No public freeze step, backend selector, or concurrent-dispatch
guarantee is needed for these improvements.
### PF-04: Reduce aggregate YAML scanning and copying
### PF-04: Reduce aggregate YAML preamble scanning
In [configuration display](../../show.go), `hasYAMLDirective` and
`frameEffectiveYAML` split the complete document into lines before examining its
@@ -149,9 +150,11 @@ decision is complete. Share the resulting framing analysis where useful so
directive detection and scope-label placement do not independently scan the same
preamble. Avoid a document-wide line index and unnecessary string conversions.
Then evaluate delivering separators, labels, and native byte segments directly,
retaining one native render buffer without a second complete framed copy. Keep
the design simple enough to preserve failure handling for multiple writes.
Under the selected OD-2 approach, retain the native render buffer and assemble a
complete framed buffer for each document before delivery. This keeps delivery
and write-failure handling straightforward. The full document copy remains an
accepted cost of this target; the optimization removes the document-wide line
index and redundant preamble scanning.
Preserve native bytes, directive placement, inline document content and block
scalars, scope-label escaping, and boundary newlines according to the CLI
@@ -207,14 +210,16 @@ preparing this metadata.
1. Establish focused before-change measurements for PF-01, PF-02, and PF-04,
then implement conditional formatting, direct command lookup/ancestry, and
YAML prefix scanning as independently reviewable changes.
2. Measure complete dispatch paths and implement PF-03's reuse within an
invocation and immutable metadata preparation where the benefit justifies
the coordination and retained memory.
3. Evaluate PF-04's segmented delivery, PF-05, and PF-06 using the first-pass
evidence and expected consumer sizes. Record a deferral if a proposed change
adds complexity without a worthwhile benefit.
4. Consider backend reuse across invocations only if the remaining measured cost
warrants it.
2. Measure complete dispatch paths, then implement PF-03's reuse within an
invocation and immutable metadata caching. Compare the resulting runtime
gains with the coordination cost and retained memory.
3. Evaluate PF-05 and PF-06 using the first-pass evidence and expected consumer
sizes. Record a deferral if a proposed change adds complexity without a
worthwhile benefit.
4. Record remaining costs after the selected improvements. Mutable backend reuse
across invocations and segmented YAML delivery remain future possibilities
beyond this target; any reconsideration should use the measurements and a
deliberate change to the selected approach.
Use Go benchmarks with controlled, offline fixtures when implementation work is
authorized. Keep external loading and service latency out of isolated CommandKit
@@ -264,45 +269,46 @@ ownership, and replacing Cobra are outside this target. They require their own
concrete motivation and review rather than following automatically from a
performance optimization.
## Open Decisions
## Resolved Decisions
The first-pass formatting, lookup, and prefix-scanning changes have a clear
recommended direction. Two broader implementation choices remain dependent on
performance evidence. Resolve them when preparing the corresponding work; they
do not require a public API change.
The following approaches were selected on 2026-10-09. Both are implementation
choices within the existing public contracts. No significant open decisions
remain for this roadmap's scope.
### OD-1: How far should backend reuse extend?
**Recommendation:** Initially reuse the prepared backend within one invocation
and cache immutable metadata between invocations, while constructing fresh
mutable backend state for each `Execute`. This removes repeated help/usage work
and metadata translation while keeping invocation isolation straightforward.
Measure the remaining backend construction cost before expanding reuse. This is
the recommended PF-03 target, not a permanent restriction on implementation.
**Selected approach:** Adopt the recommended approach: reuse the prepared backend
within one invocation and cache immutable metadata between invocations, while
constructing fresh mutable backend state for each `Execute`.
**Alternative:** Retain a mutable backend tree per `App` and reset it before each
invocation. This can remove more command and flag-set construction work for
consumers that execute repeatedly. It also retains more memory and requires
**Reasoning:** This removes repeated help/usage work and metadata translation
while keeping invocation isolation straightforward. Measure the remaining
backend construction cost to inform future work. The selection defines the
PF-03 target without establishing a permanent architectural restriction.
**Alternative considered:** Retain a mutable backend tree per `App` and reset it
before each invocation. This can remove more command and flag-set construction
work for consumers that execute repeatedly. It also retains more memory and requires
careful reset of parsed values, presence, operands, contexts, streams, and other
backend state, plus refresh after registration. Choose it if measurements show
that the remaining construction cost warrants the added lifecycle complexity
and behavioral evidence establishes independent invocations. A CLI that executes
only once receives little benefit from this additional reuse.
backend state, plus refresh after registration. The added lifecycle complexity
is deferred until measurements justify reconsideration and behavioral evidence
establishes independent invocations. A CLI that executes only once receives
little benefit from this additional reuse.
### OD-2: How much buffering should aggregate YAML retain?
**Recommendation:** After prefix scanning is improved, favor retaining the native
render buffer and delivering framing and native slices as separate segments if
measurements confirm a useful memory reduction. This removes the second complete
document copy while keeping native rendering complete before that document's
delivery begins. The work includes correct accounting for cancellation and
partial output across segment writes, without changing aggregate acquisition
timing. Compare allocation savings with any additional writer-call overhead.
**Selected approach:** Adopt the previously listed alternative: retain the
complete framed buffer after replacing the line splits with prefix scanning.
**Alternative:** Retain a complete framed buffer after replacing the line splits
with prefix scanning. This keeps delivery simple and avoids additional writes
for each document. It still allocates and copies the document a second time,
which matters for large reports. Prefer it if representative documents are small
or segmented delivery provides insufficient benefit to justify its extra error
handling. Either choice can deliver PF-04's initial prefix-scanning improvement;
record the selected buffering approach and its evidence.
**Reasoning:** This keeps delivery simple and avoids additional writes for each
document. It accepts the second document allocation and copy while removing the
line index and unnecessary scanning. Measure the resulting allocation cost,
particularly for large reports, without making segmented delivery part of this
implementation target.
**Alternative considered:** Retain only the native render buffer and deliver
framing and native slices as separate segments. This can reduce peak allocation
and copying while keeping native rendering complete before delivery. It requires
accounting for cancellation and partial output across segment writes and may
increase writer-call overhead. It remains a viable future optimization if the
selected approach's measured memory cost warrants the additional delivery logic.