Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce allocations for execution despatch (#271) #748

Merged
merged 53 commits into from
Jan 25, 2020

Conversation

reisenberger
Copy link
Member

The issue or feature being addressed

Delivers #271: Reduce heap allocations for execution despatch

Details on the issue fix or feature implementation

  • Introduces struct-based execution despatch internally: reduces allocations per execution by 50% to 90% (50% to 90% saved). Full details will be posted on issue Execution-despatch optimization (reducing heap allocations) #271 and on v8.0.0 upgrade notes.
    • allied with use of readonly structs and in modifiers wherever possible to reduce struct copying.
  • Maintains order-of-magnitude execution latency at <1microsecond (less than one-millionth-second) extra latency per policy for applying a Polly policy, for all policy types.
  • Changes DelegateResult<TResult> to struct, as this is typically only used during an execution for short duration.
  • Tidies TaskHelper (remnant of supporting older TFMs).
  • Adds new execute overloads allowing passing objects in to delegates to be executed, without creating a closure:
void Execute<T1>(Action<Context, CancellationToken, T1> action, Context context, CancellationToken cancellationToken, T1 input1)
void Execute<T1, T2>(Action<Context, CancellationToken, T1, T2> action, Context context, CancellationToken cancellationToken, T1 input1, T2 input2)

TResult Execute<T1, TResult>(Func<Context, CancellationToken, T1, TResult> func, Context context, CancellationToken cancellationToken, T1 input1)
TResult Execute<T1, T2, TResult>(Func<Context, CancellationToken, T1, T2, TResult> func, Context context, CancellationToken cancellationToken, T1 input1, T2 input2)

Task ExecuteAsync<T1>(Func<Context, CancellationToken, bool, T1, Task> action, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext, T1 input1)
Task ExecuteAsync<T1, T2>(Func<Context, CancellationToken, bool, T1, T2, Task> action, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext, T1 input1, T2 input2)

Task<TResult> ExecuteAsync<T1, TResult>(Func<Context, CancellationToken, bool, T1, Task<TResult>> func, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext, T1 input1)
Task<TResult> ExecuteAsync<T1, T2, TResult>(Func<Context, CancellationToken, bool, T1, T2, Task<TResult>> func, Context context, CancellationToken cancellationToken, bool continueOnCapturedContext, T1 input1, T2 input2)

(and similar overloads for .ExecuteAndCapture/Async(...))

Confirm the following

  • I started this PR by branching from the head of the latest dev vX.Y branch, or I have rebased on the latest dev vX.Y branch, or I have merged the latest changes from the dev vX.Y branch
  • I have targeted the PR to merge into the latest dev vX.Y branch as the base branch
  • I have included unit tests for the issue/feature
  • I have successfully run a local build

@grant-d
Copy link

grant-d commented Jan 28, 2020

Lovely stuff, great work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants