New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add custom backing storage to ByteBuffer #1218
Comments
Thanks for this suggestion! I am extremely disinclined to add an unsafe data type so prominently to NIO’s API. Specifically, I think that we should view any instance where Swift is not able to obtain an optimisation result as good as the unsafe equivalent as a Swift bug that should be reported upstream. In your sample code the reference counting overhead should be pretty low; one atomic add per field, which ought not to be a drastic amount. I’d be interested in knowing how many more retains and releases you are seeing, as if that number is drastically higher this might be a good candidate for a benchmark. |
https://github.com/Joannis/WIPTemplatingLib This codebase has an implementation of what I proposed. My current test runs 10_000 iterations. Each set of 10k iterations runs in ~20ms: Before this the amount of time spend was 2.5-4x higher (50-80ms) no matter what I tried. All of that is retains/releases. |
The fastest I could get it with SwiftNIO ByteBuffer: https://github.com/Joannis/WIPTemplatingLib/tree/slow
|
So in my sample I halved your runtime by applying 5 |
See also: https://bugs.swift.org/browse/SR-11706. |
There's one more retain/release happening in your |
ByteBuffer's API is great for common in-memory binary data storage and for parsing/serializing data.
One of the problem that I find in every single project I have is the poor performance of ByteBuffer's backing storage which Swift is retaining/releasing every single API call. I'd love to have a data type such as
UnsafeByteBuffer
andUnsafeMutableByteBuffer
which is the same API wrapped around a manually allocated/deallocated buffer.I'm very sure that this would open up many opportunities for optimizing current applications such as Database drivers, JSON libraries and templating libraries. Even if those oppurtunities are there now, it'd still be a great improvement in the ease of doing said operations.
Databases
Many databases will, for example, return a contiguous buffer with many separate entities. For each entity, an encoder will need to be created which decodes the info of a single entity's row/document into a struct/class. I
UnsafeByteBuffer Pseudo Implementation
I'd directly refer to the pointer and provide an API for reading the data from that. Like ByteBuffer but without wrapping a class for auto-deallocation. It also wouldn't allow mutations and therefore mutation.
UnsafeMutableByteBuffer Pseudo Implementation
I'd directly refer to the pointer again to provide an API for reading the data from that. Again without wrapping a class for auto-deallocation. But it would allow mutations, but would
fatalError
or at least do anassertionFailure
if you try to access data outside of bounds.The goal of this type is not to read data efficiently, but to modify current buffers manually and/or to provide a useful interface. It might support auto-expansion using mutating methods. But allocation/deallocation is 100% within the developer's control.
The text was updated successfully, but these errors were encountered: