| name | precomputed-optional-parameter |
| description | Avoid redundant expensive computations — especially IsolatedPowerShellRunspace setup — by passing pre-computed results as optional nullable parameters to private delegation methods, with null-coalescing fallback for callers that don't pre-compute. WHEN: a public method computes expensive data then calls a private helper that recomputes the same data, or when runspace/session initialization is executing twice. |
| domain | performance |
| confidence | medium |
| source | earned |
Context
When a public method computes expensive data (e.g., introspection, runspace setup) and then delegates to a private helper that recomputes the same data, the helper should accept the pre-computed result as an optional parameter. This pattern eliminates redundant work while preserving backward compatibility for internal callers that don't pre-compute.
Patterns
- Parameter signature: Accept the pre-computed result as an optional parameter with a default value:
BuildDoctorJson(IConfiguration config, IEnumerable<IMcpTool> tools, List<ConfiguredFunctionStatus>? precomputedFunctionStatus = null)
- Guard clause: Use the null-coalescing operator to compute only if not provided:
precomputedFunctionStatus ?? ComputeExpensiveData()
- Type visibility: When the inner type must appear in the optional parameter signature, promote it from
private to internal. Sealed records are safe for this widening.
- Applies to:
IsolatedPowerShellRunspace operations are the primary use case. Each runspace creation + PS session initialization adds significant startup cost; double-execution doubles this cost. Other expensive introspection scenarios also benefit.
- Caller responsibility: The caller that owns the public API layer is responsible for pre-computing and passing the result to avoid double-work.
Examples
Signature with optional pre-computed parameter:
public string GetDoctorStatus(IConfiguration config, IEnumerable<IMcpTool> tools)
{
var status = _statusBuilder.ComputeStatus(config, tools);
return _innerBuilder.BuildDoctorJson(config, tools, status);
}
internal string BuildDoctorJson(
IConfiguration config,
IEnumerable<IMcpTool> tools,
List<ConfiguredFunctionStatus>? precomputedFunctionStatus = null)
{
var functionStatus = precomputedFunctionStatus ?? ComputeExpensiveFunction(config, tools);
if (functionStatus.All(s => s.Found || s.ResolutionReason is null))
{
}
return json;
}
Type visibility promotion:
private sealed record ConfiguredFunctionStatus(string Name, bool Found, string? ResolutionReason);
internal sealed record ConfiguredFunctionStatus(string Name, bool Found, string? ResolutionReason);
Anti-Patterns
- ❌ Always recomputing in the helper even if the caller already computed (wastes resources)
- ❌ Making the optional parameter required or non-null (breaks internal backward compatibility)
- ❌ Passing pre-computed data that may be stale or inconsistent with current state
- ❌ Widening visibility of non-sealed types (exposes implementation details)