[ByteBuffer] Reduce ARC traffic when reading (#1978)

In my local testing I have seen that the compiler adds a retain and release cycle around the use of `Optional.map` in ByteBuffer's read methods.

Modifications:
- Replaced the use of `Optional.map` with `guard let` in ByteBuffer's read methods.
This commit is contained in:
Fabian Fett 2021-10-21 16:57:25 +02:00 committed by GitHub
parent 787e2287d0
commit 269a61727e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 18 deletions

View File

@ -45,10 +45,11 @@ extension ByteBuffer {
/// - length: The number of bytes to be read from this `ByteBuffer`. /// - length: The number of bytes to be read from this `ByteBuffer`.
/// - returns: A `[UInt8]` value containing `length` bytes or `nil` if there aren't at least `length` bytes readable. /// - returns: A `[UInt8]` value containing `length` bytes or `nil` if there aren't at least `length` bytes readable.
public mutating func readBytes(length: Int) -> [UInt8]? { public mutating func readBytes(length: Int) -> [UInt8]? {
return self.getBytes(at: self.readerIndex, length: length).map { guard let result = self.getBytes(at: self.readerIndex, length: length) else {
self._moveReaderIndex(forwardBy: length) return nil
return $0
} }
self._moveReaderIndex(forwardBy: length)
return result
} }
// MARK: StaticString APIs // MARK: StaticString APIs
@ -149,10 +150,11 @@ extension ByteBuffer {
/// - length: The number of bytes making up the string. /// - length: The number of bytes making up the string.
/// - returns: A `String` value deserialized from this `ByteBuffer` or `nil` if there aren't at least `length` bytes readable. /// - returns: A `String` value deserialized from this `ByteBuffer` or `nil` if there aren't at least `length` bytes readable.
public mutating func readString(length: Int) -> String? { public mutating func readString(length: Int) -> String? {
return self.getString(at: self.readerIndex, length: length).map { guard let result = self.getString(at: self.readerIndex, length: length) else {
self._moveReaderIndex(forwardBy: length) return nil
return $0
} }
self._moveReaderIndex(forwardBy: length)
return result
} }
// MARK: Substring APIs // MARK: Substring APIs
@ -238,10 +240,11 @@ extension ByteBuffer {
/// - length: The number of bytes. /// - length: The number of bytes.
/// - returns: A `DispatchData` value containing the bytes from this `ByteBuffer` or `nil` if there aren't at least `length` bytes readable. /// - returns: A `DispatchData` value containing the bytes from this `ByteBuffer` or `nil` if there aren't at least `length` bytes readable.
public mutating func readDispatchData(length: Int) -> DispatchData? { public mutating func readDispatchData(length: Int) -> DispatchData? {
return self.getDispatchData(at: self.readerIndex, length: length).map { guard let result = self.getDispatchData(at: self.readerIndex, length: length) else {
self._moveReaderIndex(forwardBy: length) return nil
return $0
} }
self._moveReaderIndex(forwardBy: length)
return result
} }
@ -426,10 +429,11 @@ extension ByteBuffer {
/// - length: The number of bytes to slice off. /// - length: The number of bytes to slice off.
/// - returns: A `ByteBuffer` sharing storage containing `length` bytes or `nil` if the not enough bytes were readable. /// - returns: A `ByteBuffer` sharing storage containing `length` bytes or `nil` if the not enough bytes were readable.
public mutating func readSlice(length: Int) -> ByteBuffer? { public mutating func readSlice(length: Int) -> ByteBuffer? {
return self.getSlice(at: self.readerIndex, length: length).map { guard let result = self.getSlice(at: self.readerIndex, length: length) else {
self._moveReaderIndex(forwardBy: length) return nil
return $0
} }
self._moveReaderIndex(forwardBy: length)
return result
} }
@discardableResult @discardableResult

View File

@ -31,10 +31,11 @@ extension ByteBuffer {
/// - returns: An integer value deserialized from this `ByteBuffer` or `nil` if there aren't enough bytes readable. /// - returns: An integer value deserialized from this `ByteBuffer` or `nil` if there aren't enough bytes readable.
@inlinable @inlinable
public mutating func readInteger<T: FixedWidthInteger>(endianness: Endianness = .big, as: T.Type = T.self) -> T? { public mutating func readInteger<T: FixedWidthInteger>(endianness: Endianness = .big, as: T.Type = T.self) -> T? {
return self.getInteger(at: self.readerIndex, endianness: endianness, as: T.self).map { guard let result = self.getInteger(at: self.readerIndex, endianness: endianness, as: T.self) else {
self._moveReaderIndex(forwardBy: MemoryLayout<T>.size) return nil
return $0
} }
self._moveReaderIndex(forwardBy: MemoryLayout<T>.size)
return result
} }
/// Get the integer at `index` from this `ByteBuffer`. Does not move the reader index. /// Get the integer at `index` from this `ByteBuffer`. Does not move the reader index.

View File

@ -112,10 +112,11 @@ extension ByteBuffer {
endianness: Endianness = .big, endianness: Endianness = .big,
as integer: Integer.Type as integer: Integer.Type
) -> ByteBuffer? where Integer: FixedWidthInteger { ) -> ByteBuffer? where Integer: FixedWidthInteger {
self.getLengthPrefixedSlice(at: self.readerIndex, endianness: endianness, as: Integer.self).map { guard let result = self.getLengthPrefixedSlice(at: self.readerIndex, endianness: endianness, as: Integer.self) else {
self._moveReaderIndex(forwardBy: MemoryLayout<Integer>.size + $0.readableBytes) return nil
return $0
} }
self._moveReaderIndex(forwardBy: MemoryLayout<Integer>.size + result.readableBytes)
return result
} }
/// Gets an `Integer` from `self` and gets a slice of that length from `self` and returns it. /// Gets an `Integer` from `self` and gets a slice of that length from `self` and returns it.