Skip to content

perf: eliminate policy evaluation overhead - #93

Merged
rian-be merged 2 commits into
mainfrom
develop
Jul 28, 2026
Merged

perf: eliminate policy evaluation overhead#93
rian-be merged 2 commits into
mainfrom
develop

Conversation

@rian-be

@rian-be rian-be commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Removes all per call allocation and async overhead from policy evaluation. Evaluator now caches sorted policies per type, completes synchronously for sync policies, and the pipeline's inner async wrappers are eliminated. Benchmark policies cache their decisions so evaluation scaling cost is effectively zero.

Changes

PolicyDecision singleton (PolicyDecision.cs)

  • Parameterless Allow() returns private static readonly instance instead of new PolicyDecision { IsAllowed = true }

Evaluator sync fast path (MutationPolicyEvaluator.cs)

  • Caches sorted IMutationPolicy<TState>[] per state type via ConcurrentDictionary registry query + sort hit once per type
  • Returns ValueTask<PolicyDecision> sync completions wrap result directly, zero Task allocation
  • Checks task.IsCompletedSuccessfully before await sync policies complete via task.Result without async state machine
  • Removes InvokePolicyAsync wrapper (merged try/catch inline)
  • Splits into EvaluateNoTimeoutAsync / AwaitRemainingAsync async fallback only when policy actually suspends

Pipeline ValueTask path (MutationExecutionPipeline.cs)

  • EvaluatePolicyDecisionAsync returns ValueTask<PolicyDecision> with sync fast path eliminates inner Task + state machine when evaluator completes synchronously
  • Timing recorded inline for sync path; AwaitPolicyAndRecordAsync handles async only case

Benchmark isolation (PolicyBenchmarkSupport.cs)

  • SyncAllowBenchmarkPolicy / AsyncAllowBenchmarkPolicy cache PolicyDecision + Task<PolicyDecision> zero per-evaluation allocation
  • Registers NoOpAuditor + NoOpHistoryStore removes audit/history noise from baseline

Benchmark Results

Benchmark Before After Δ Time Δ Alloc
NoPolicy_Baseline 5.007 us / 3.01 KB 1.226 us / 1.66 KB −75% −45%
SingleSyncPolicy_Allow 5.324 us / 3.98 KB 1.241 us / 1.66 KB −77% −58%
SingleAsyncPolicy_Allow 5.307 us / 3.98 KB 1.238 us / 1.66 KB −77% −58%
MultipleMixedPolicies_Allow 5.607 us / 5.43 KB 1.241 us / 1.66 KB −78% −69%

Closes

Closes #92

@github-actions github-actions Bot added performance Performance improvements or regressions abstractions Public abstractions and contracts labels Jul 27, 2026
@github-actions github-actions Bot added runtime Runtime implementation and execution flow benchmark Benchmark coverage and performance measurement changes labels Jul 27, 2026
@rian-be rian-be changed the title perf: eliminate policy evaluation overhead — sync fast path, cached policies, zero-alloc allow perf: eliminate policy evaluation overhead Jul 27, 2026
@rian-be
rian-be merged commit f9e60bf into main Jul 28, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

abstractions Public abstractions and contracts benchmark Benchmark coverage and performance measurement changes performance Performance improvements or regressions runtime Runtime implementation and execution flow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Perf]: Eliminate policy evaluation overhead

1 participant