-
Notifications
You must be signed in to change notification settings - Fork 32
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
Use C# Array Pool buffer when calling BebopWriter.Create() to Encode #144
Comments
Thank you for putting this issue together! I started investigating using ArrayPool a few weeks ago and couldn't quite decide on the best approach. Another place where perf wins could be gained is improvements to the string encoder / decoding. I believe a better option would be to allow for a buffer to be passed into |
I spent some time over the weekend thinking about this. I agree that the Bebop library shouldn't be the thing managing pooling for something as simple as encoding an object. My concern is that everyone who wants to use this new encode method would have to write the same wrapping code calling this new method. I think eventually this can be included in the SDK/Generated Code, but I don't have a good idea for what that looks like. I'll think about it some more and if I have any good ideas, I'll make a separate issue to talk about them. In the mean time, for this issue, I'll go with what you said and create an encoding method that can receive a
I went back and forth with the |
Closing this issue because the PR has been created in issue #155 |
Is your feature request related to a problem? Please describe.
I was benchmarking Bebop recently and noticed it allocated considerably more memory than the other binary serialization protocols I was comparing it to (Protobuf and MessagePack). The results of the benchmarks are at: https://github.com/ProgrammerAl/SerializationBenchmarks#benchmark-results
Looks like this is happening because new instances of
BebopWriter
are created with an empty byte array and then it's grown/re-allocated as values are written to it. I propose a new overload is added toBebopWriter.Create()
that accepts an array so it doesn't start at empty. By default this array would come fromArrayPool<byte>.Shared
.Describe the solution you'd like
There are 2 alternatives I tried locally.
The first one, temporarily named
EncodeImmutablyWithArrayPool()
, gets the buffer from the pool using the final size needed to encode to akaArrayPool<byte>.Shared.Rent(record.ByteCount)
. The benefit here is we know another array won't be allocated. In my benchmarks this was consistently 20-30 ns slower than the current code. My assumption is it was slower because of the call toGetByteCount()
. The benefit is it allocates much less memory.The second example, temporarily named
EncodeImmutablyWithArrayPoolFixed()
, gets an array from the pool using a constant value akaArrayPool<byte>.Shared.Rent(1000)
. In my benchmarks this was consistently 20-30 ns faster to run than the current code. We can play around with what constant value to use, but if we rent a buffer too small, we'll be back to our problem of allocating another array. Either way, this will still allocate much less memory than the current code and will run faster.Additional context
Below are the benchmarks for the above mentioned methods:
Here's the benchmark code:
If this is a feature you want added, I can volunteer to take it on.
Another alternative I did not try is to get a buffer from the Array pool of size
MaxByteCount
for that entity. Currently the property re-calculates the value each time it's called. But it's essentially a constant value. We could change it to a constant that gets output by the compiler and use that constant when pulling a buffer from the array pool. This would take more effort, and could be done at a later date.The text was updated successfully, but these errors were encountered: