Zero-copy BinaryData creation from MemoryStream in .NET

 
 
  • Gérald Barré

When working with BinaryData and MemoryStream in .NET, you might need to convert stream data into a BinaryData instance. The typical approach using BinaryData.FromStream() involves copying the entire buffer, which can impact performance and increase memory allocations. However, there's a more efficient way to achieve this with zero memory copies.

#The problem with BinaryData.FromStream()

The standard way to create BinaryData from a stream is straightforward but comes with a performance cost:

C#
var stream = new MemoryStream();
stream.Write([1, 2, 3]);
stream.Seek(0, SeekOrigin.Begin);

// This requires a memory copy
var data = BinaryData.FromStream(stream);

When you call BinaryData.FromStream(), the method reads the stream and copies its contents into a new buffer. For large streams or performance-critical applications, this additional copy can be wasteful.

#The zero-copy approach

If you're working with a MemoryStream, you can access its underlying buffer directly and create a BinaryData instance without copying:

C#
var stream = new MemoryStream();
stream.Write([1, 2, 3]);

// This does not require a memory copy
var data = new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position));

This approach uses GetBuffer() to access the underlying byte array of the MemoryStream, then wraps it in a Memory<byte> slice that represents only the written portion. The BinaryData constructor accepts ReadOnlyMemory<byte>, so the conversion happens implicitly.

Interestingly, the BinaryData implementation itself uses a similar optimization. When you look at the source code, you can see that BinaryData.FromStream() checks if the stream is a MemoryStream and tries to use TryGetBuffer() to avoid copying when possible.

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?Buy Me A Coffee💖 Sponsor on GitHub