-
Notifications
You must be signed in to change notification settings - Fork 595
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
allow to publish array segments instead of full byte arrays #489
Conversation
Thank you for your time and considering a contribution. I find this API addition to be ugly and too specific to a single user's needs. Fundamental efficiency improvements such as the recent work by @Pliner is what we should be after. I 👎 this. |
Also, as with all efficiency improvements it would be nice to see some benchmarks and what kind of difference does using this new method bring. "Quite a big overhead" is not something that our team can quantify. |
Hmm users use serialization classes and / or |
That touches on the larger issue, in that On the other hand, |
Yes, the best would be to use Span/ReadOnlySpan, but it is not available in .NET framework. So I'd prefer Spans, but the existing code is already using ArraySegments in other classes, this is why I choosed that. I'll try to create some performace test. And yes, it is ugly to have 2 methods (which accepts only the byte array, and the 2nd which accepts the offset/count, too), but I did not want to add breaking change. When a breaking change is not a problem, change the existing method. I think nowadays a good serializer is using a buffer pool to avoid memory allocations. But because of pooling the returned buffer is maybe bigger than needed. And RabbitMQ can't handle that, we have to copy the data to a new buffer which has the exact size. |
And one more thing, @Pliner 's change is reduces the allocation inside RabbitMQ client. In my case the extra allocation is in the caller's code, so it is not an alternative, both can/should be applied. Or as you mentioned, it can use Spans (for BasicPublish I think it should be ReadOnlySpan), it would solve my issue, too, but it is a bigger breaking change. |
We have been doing breaking changes in master for 6.0 for over a month now. The only question here is, what .NET versions can we support with that kind of API. |
While the You also don't get all of the BCL overloads that take So, while switching to |
@bording thank you for the insightful response. We should file a new issue about a Let's wait for the numbers before we make the call on this change. |
Just found an already existing issue for this PR: #303 But as you wrote I'd be happy to modify this PC according your preferences, just let me know what interface parameter changes would you accept. If you prefer I can change the internal |
I don't mind the changes to the public api (BasicPublish) and I think they could be useful for a small number of users. The problem as I see it is that the internals now expect an array segment which means that the common case (where a user provides and wants to send a full buffer) requires an ArraySegment to be created. I don't know if .NET does something special in this case but this seems like an unnecessary object allocation? I'd like to see the PR cut down as @zgabi suggests to allow users to specify offset and length instead and also mirror that internally. That should satisfy the the users that want to avoid copying. |
So is it ok for everybody if I add offset and length everywhere? By the way, in this case I think this method could be changed, too: rabbitmq-dotnet-client/projects/client/RabbitMQ.Client/src/client/impl/ExtensionMethods.cs Line 68 in 646c289
Return only the byte[], the length is always ms.Position anyway. With this change all existing |
@zgabi not sure what you mean by "everywhere" but it is not OK to modify existing methods. I don't think this user-specific API element should be driving the implementation either. |
Eveywhere = where I added I don't mind how ( Another question is: |
I'm afraid the consensus (or lack thereof) around this PR is: we are not convinced such use case-specific changes should be accepted to the API. We are open to being convinced otherwise but there hasn't been much activity => closing. Thank you for taking the time, @zgabi! |
Proposed Changes
IModel.BasicPublish currently accepts only a byte array, so the library user usually needs to copy the data to a new byte array which has the required length. It is a quite big overhead and also needs more garbage collection.
This PR adds a new BasicPublish method to the IModel interface which accepts an offset and count parameters (like .NET's Stream write, etc)
Types of Changes
What types of changes does your code introduce to this project?
Put an
x
in the boxes that applyChecklist
CONTRIBUTING.md
documentI can see some exceptions when I run run-test.bat, but they are not releated to my change. I've set RABBITMQ_RABBITMQCLT_PATH but still complains.