Skip to content

Commit 79802e0

Browse files
authored
Reduce allocations on InlineStreamMultiplexer/createStreamChannel (#450)
## Motivation When creating stream channels on the `InlineStreamMultiplexer`, we are currently performing a `flatSubmit` on two different codepaths. This allocates two ELFs: one on `submit`, and one on `flatMap`. This is unnecessary, as we could do with just one allocation. ## Modifications Create a single ELP and call `execute` on the EL instead of using `flatSubmit`. ## Result Fewer allocations
1 parent aab0f12 commit 79802e0

File tree

5 files changed

+17
-8
lines changed

5 files changed

+17
-8
lines changed

Sources/NIOHTTP2/HTTP2ChannelHandler+InlineStreamMultiplexer.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ extension InlineStreamMultiplexer {
151151
self._commonStreamMultiplexer.createStreamChannel(multiplexer: .inline(self), streamStateInitializer)
152152
}
153153

154+
@inlinable
155+
internal func createStreamChannel<Output: Sendable>(promise: EventLoopPromise<Output>?, _ initializer: @escaping NIOChannelInitializerWithOutput<Output>) {
156+
self._commonStreamMultiplexer.createStreamChannel(multiplexer: .inline(self), promise: promise, initializer)
157+
}
158+
154159
@inlinable
155160
internal func createStreamChannel<Output: Sendable>(_ initializer: @escaping NIOChannelInitializerWithOutput<Output>) -> EventLoopFuture<Output> {
156161
self._commonStreamMultiplexer.createStreamChannel(multiplexer: .inline(self), initializer)
@@ -284,19 +289,23 @@ extension InlineStreamMultiplexer {
284289
// Always create streams channels on the next event loop tick. This avoids re-entrancy
285290
// issues where handlers interposed between the two HTTP/2 handlers could create streams
286291
// in channel active which become activated twice.
287-
return self._eventLoop.flatSubmit {
288-
self._inlineStreamMultiplexer.createStreamChannel(initializer)
292+
let promise: EventLoopPromise<Channel> = self._eventLoop.makePromise()
293+
self._eventLoop.execute {
294+
self._inlineStreamMultiplexer.createStreamChannel(promise: promise, initializer)
289295
}
296+
return promise.futureResult
290297
}
291298

292299
@inlinable
293300
internal func createStreamChannel<Output: Sendable>(_ initializer: @escaping NIOChannelInitializerWithOutput<Output>) -> EventLoopFuture<Output> {
294301
// Always create streams channels on the next event loop tick. This avoids re-entrancy
295302
// issues where handlers interposed between the two HTTP/2 handlers could create streams
296303
// in channel active which become activated twice.
297-
return self._eventLoop.flatSubmit {
298-
self._inlineStreamMultiplexer.createStreamChannel(initializer)
304+
let promise: EventLoopPromise<Output> = self._eventLoop.makePromise()
305+
self._eventLoop.execute {
306+
self._inlineStreamMultiplexer.createStreamChannel(promise: promise, initializer)
299307
}
308+
return promise.futureResult
300309
}
301310

302311
internal func setChannelContinuation(_ streamChannels: any AnyContinuation) {

docker/docker-compose.2204.510.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ services:
4040
- MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline=889050
4141
- MAX_ALLOCS_ALLOWED_create_client_stream_channel=37050
4242
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline=37050
43-
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline_no_promise_based_API=44050
43+
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline_no_promise_based_API=37050
4444
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_no_promise_based_API=37050
4545
- MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form=200050
4646
- MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form_trimming_whitespace=200050

docker/docker-compose.2204.58.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ services:
4040
- MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline=889050
4141
- MAX_ALLOCS_ALLOWED_create_client_stream_channel=37050
4242
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline=37050
43-
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline_no_promise_based_API=44050
43+
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline_no_promise_based_API=37050
4444
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_no_promise_based_API=37050
4545
- MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form=200050
4646
- MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form_trimming_whitespace=200050

docker/docker-compose.2204.59.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ services:
4040
- MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline=889050
4141
- MAX_ALLOCS_ALLOWED_create_client_stream_channel=37050
4242
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline=37050
43-
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline_no_promise_based_API=44050
43+
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline_no_promise_based_API=37050
4444
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_no_promise_based_API=37050
4545
- MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form=200050
4646
- MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form_trimming_whitespace=200050

docker/docker-compose.2204.main.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ services:
3939
- MAX_ALLOCS_ALLOWED_client_server_request_response_many_inline=889050
4040
- MAX_ALLOCS_ALLOWED_create_client_stream_channel=37050
4141
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline=37050
42-
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline_no_promise_based_API=44050
42+
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_inline_no_promise_based_API=37050
4343
- MAX_ALLOCS_ALLOWED_create_client_stream_channel_no_promise_based_API=37050
4444
- MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form=200050
4545
- MAX_ALLOCS_ALLOWED_get_100000_headers_canonical_form_trimming_whitespace=200050

0 commit comments

Comments
 (0)