Skip to content

Commit

Permalink
Save two allocations by making MapRPCWriter and `SerializingRPCWrit…
Browse files Browse the repository at this point in the history
…er` generic over wrapped writer (#1983)

Motivation:

We currently wrap a base writer into an `RPCWriter` inside the `MapRPCWriter` and `SerializingRPCWriter`.
This results in an unnecessary allocation in both cases. In the case of unary requests, this means two extra allocations per requests on the client side.

Modifications:

Make the `MapRPCWriter` and `SerializingRPCWriter` generic over the base writer, to avoid the extra allocations caused by wrapping them in an `RPCWriter`.

Result:

Two fewer allocations per unary request on the client side.
  • Loading branch information
gjcairo committed Jul 17, 2024
1 parent 8af38b1 commit 9ae6550
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 8 deletions.
8 changes: 4 additions & 4 deletions Sources/GRPCCore/Streaming/Internal/RPCWriter Map.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 16,18 @@

@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
@usableFromInline
struct MapRPCWriter<Value, Mapped>: RPCWriterProtocol {
struct MapRPCWriter<Value, Mapped, Base: RPCWriterProtocol<Mapped>>: RPCWriterProtocol {
@usableFromInline
typealias Element = Value

@usableFromInline
let base: RPCWriter<Mapped>
let base: Base
@usableFromInline
let transform: @Sendable (Value) -> Mapped

@inlinable
init(base: some RPCWriterProtocol<Mapped>, transform: @escaping @Sendable (Value) -> Mapped) {
self.base = RPCWriter(wrapping: base)
init(base: Base, transform: @escaping @Sendable (Value) -> Mapped) {
self.base = base
self.transform = transform
}

Expand Down
11 changes: 7 additions & 4 deletions Sources/GRPCCore/Streaming/Internal/RPCWriter Serialize.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 16,22 @@

@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
@usableFromInline
struct SerializingRPCWriter<Serializer: MessageSerializer>: RPCWriterProtocol {
struct SerializingRPCWriter<
Base: RPCWriterProtocol<[UInt8]>,
Serializer: MessageSerializer
>: RPCWriterProtocol {
@usableFromInline
typealias Element = Serializer.Message

@usableFromInline
let base: RPCWriter<[UInt8]>
let base: Base
@usableFromInline
let serializer: Serializer

@inlinable
init(serializer: Serializer, base: some RPCWriterProtocol<[UInt8]>) {
init(serializer: Serializer, base: Base) {
self.serializer = serializer
self.base = RPCWriter(wrapping: base)
self.base = base
}

@inlinable
Expand Down

0 comments on commit 9ae6550

Please sign in to comment.