Repository: google/flatbuffers
File: swift/Sources/FlatBuffers/ByteBuffer.swift (Swift)

Code before:

  /// Reads an object from the buffer
  /// - Parameters:
  ///   - def: Type of the object
  ///   - position: the index of the object in the buffer
  @inline(__always)
  public func read<T>(def: T.Type, position: Int) -> T {
    #if swift(>=5.7)
    if readUnalignedBuffers {
      return _storage.memory.advanced(by: position).loadUnaligned(as: T.self)
    }
    return _storage.memory.advanced(by: position).load(as: T.self)
    #else
    return _storage.memory.advanced(by: position).load(as: T.self)
    #endif
  }

  /// Reads a slice from the memory assuming a type of T
  /// - Parameters:
  ///   - index: index of the object to be read from the buffer
  ///   - count: count of bytes in memory
  @inline(__always)
  public func readSlice<T>(
    index: Int,
    count: Int) -> [T]
  {
    assert(
      index + count <= _storage.capacity,
      "Reading out of bounds is illegal")
    let start = _storage.memory.advanced(by: index)
      .assumingMemoryBound(to: T.self)
    let array = UnsafeBufferPointer(start: start, count: count)
    return Array(array)
  }

  #if !os(WASI)
  /// Reads a string from the buffer and encodes it to a swift string
  /// - Parameters:
  ///   - index: index of the string in the buffer
  ///   - count: length of the string
  ///   - type: Encoding of the string
  @inline(__always)
  public func readString(
    at index: Int,
    count: Int,
    type: String.Encoding = .utf8) -> String?
  {
    assert(
      index + count <= _storage.capacity,
      "Reading out of bounds is illegal")
    let start = _storage.memory.advanced(by: index)

Review comment (performance):
There is no prettier way of doing this to support aligned and unaligned memory. So for now this approach would be the best, unless swift 5.9 and above would come with a nice solution that solves this for us without the copying.
PS: the benchmarks are done while using the new read method, which means in terms of writing buffers we didn't lose much in terms of performance.

Code after:

  /// Clears the current size of the buffer
  @inline(__always)
  mutating public func clearSize() {
    _writerSize = 0
  }

  /// Clears the current instance of the buffer, replacing it with new memory
  @inline(__always)
  mutating public func clear() {
    _writerSize = 0
    alignment = 1
    _storage.initialize(for: _storage.capacity)
  }

  /// Reads an object from the buffer
  /// - Parameters:
  ///   - def: Type of the object
  ///   - position: the index of the object in the buffer
  @inline(__always)
  public func read<T>(def: T.Type, position: Int) -> T {
    #if swift(>=5.7)
    if allowReadingUnalignedBuffers {
      return _storage.memory.advanced(by: position).loadUnaligned(as: T.self)
    }
    #endif
    return _storage.memory.advanced(by: position).load(as: T.self)
  }

  /// Reads a slice from the memory assuming a type of T
  /// - Parameters:
  ///   - index: index of the object to be read from the buffer
  ///   - count: count of bytes in memory
  @inline(__always)
  public func readSlice<T>(
    index: Int,
    count: Int) -> [T]
  {
    assert(
      index + count <= _storage.capacity,
      "Reading out of bounds is illegal")
    let start = _storage.memory.advanced(by: index)
      .assumingMemoryBound(to: T.self)
    let array = UnsafeBufferPointer(start: start, count: count)
    return Array(array)
  }

  #if !os(WASI)
  /// Reads a string from the buffer and encodes it to a swift string
  /// - Parameters:
  ///   - index: index of the string in the buffer