Reduce cost of responding to unary calls. #932
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation:
When looking at the unary response path I noticed that there was quite a
lot of flushing in the callback chain for sending unary responses. In
particular, as this callback chain performed only synchronous operations
(
.map
and.recover
) there was no need for multiple flushes: thefinal
.whenSuccess
covered all code paths and had an unconditionalflush
in it, so that flush would cover the other operations.However, on further inspection I realised that I could refactor the
entire code path to use a single Future callback. This ends up being a
substantial win. Unnecessary future callbacks put pressure on the
allocator, as they tend to have to allocate closure contexts (if the
closure captures, as all of these did) as well as additional Future
objects for return values. Reducing unnecessary chaining can therefore
be a tidy win when it happens in hot paths.
Modifications:
writeAndFlush
with awrite(..., promise: nil)
, removingboth an unnecessary flush and a future allocation.
.whenComplete
.Results:
The previous code allocated 4 closure contexts and 4 futures, and
flushed twice. The new code allocates 1 closure context, zero futures,
and flushes once. A tidy little profit: 4.7% improvement in unary call
microbenchmarks.