apple / swift-nio

Event-driven network application framework for high performance protocol servers & clients, non-blocking.
https://swiftpackageindex.com/apple/swift-nio/documentation
Apache License 2.0
7.93k stars 643 forks source link

Add fast-path ByteBuffer.write method that takes a ByteBufferView. #517

Closed Lukasa closed 6 years ago

Lukasa commented 6 years ago

Currently if you want to write a ByteBufferView to a ByteBuffer, it will fall into this method:

public mutating func write<S: Sequence>(bytes: S) -> Int where S.Element == UInt8

This ends up dropping into the very complex mutating func _set<S: Sequence>(bytes: S, at index: _Index) -> _Capacity where S.Element == UInt8, which is a very complex method that potentially performs multiple resizings and many bounds checks.

This is all unnecessary, as ByteBufferView is backed by a ByteBuffer. This means that we can instead call write(buffer:) with the appropriate details, and use the fast-path that that method uses to treat the collection as a ContiguousCollection.

Note that we don't need to (or want to) actually conform the ByteBufferView to ContiguousCollection. Instead we just want the same magic we've done with ByteBuffer to apply here: take our special knowledge of the layout of this type and use it to obtain a performance improvement.

Lukasa commented 6 years ago

This would be useful for apple/swift-nio-http2#10, which uses ByteBufferViews heavily and tends to copy them around.

AlanQuatermain commented 6 years ago

Er. Isn't ByteBufferView already a ContiguousCollection…? The code certainly seems to indicate that:

public struct ByteBufferView: ContiguousCollection, RandomAccessCollection {
Lukasa commented 6 years ago

Hah, yup, sure is. Ignore me then!