Browse Source

Save two allocations by making `MapRPCWriter` and `SerializingRPCWriter` 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.
Gustavo Cairo 1 year ago
parent
commit
9ae65503c0

+ 4 - 4
Sources/GRPCCore/Streaming/Internal/RPCWriter+Map.swift

@@ -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
   }
 

+ 7 - 4
Sources/GRPCCore/Streaming/Internal/RPCWriter+Serialize.swift

@@ -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