Open lukebakken opened 11 months ago
We need to be careful with comparisons here.
If you think about stream operations, they don't copy the whole message (or any part of it). It's the responsibility of the caller to not modify that memory.
Microsoft.Data.SqlClient allows some columns to be read as Stream
. (see SqlDataReader.GetStream(Int32) Method). No way to write parameter values as Stream
, though.
But both SqlDataReader
and SqlParameter
can work with SqlBytes
that provide direct access to different byte sources/destinations.
APIs are becoming more mindful of memory usage and taking advantage of the new types introduced to avoid memory allocation and copying.
If other libraries are not doing the same, maybe they should.
I really like how the new NATS .NET Client v2 does things for (de)serializing data. Take a look at this: https://nats-io.github.io/nats.net.v2/documentation/serialization.html
By default they both accept and return a NatsMemoryIDisposable
object that takes care of renting/returning memory, which is then automatically done when the objects go out of scope if it hasn't been manually dispose with for example a using
block. This is similar to how MemoryOwner<T>
works in the core runtime and makes it easy to use memory efficiently. They also do not buffer commands to the server with a Channel, but just write struct objects/commands directly to the Pipelines.
It's pretty impressive in it's low memory overheads without sacrificing usability or making it easy to hang on to memory too long.
Reference:
https://github.com/rabbitmq/rabbitmq-dotnet-client/pull/1445
In that PR,
BasicPublishAsync
is modified to conditionally copy data from the client application. @paulomorgado then followed up with this comment.Someone should take a look at libraries like these to see what is done in this scenario: