Создаём BinaryData из MemoryStream без Копирования
При работе с BinaryData и MemoryStream в .NET может потребоваться преобразование данных потока в экземпляр BinaryData. Типичный подход с использованием BinaryData.FromStream() предполагает копирование всего буфера, что может повлиять на производительность и увеличить объем выделяемой памяти. Однако существует более эффективный способ достижения этой цели без копирования памяти.
Проблема с BinaryData.FromStream()
Стандартный способ создания BinaryData из потока прост, но сопряжен с затратами:
var stream = new MemoryStream();
stream.Write([1, 2, 3]);
stream.Seek(0, SeekOrigin.Begin);
// Это требует копирования памяти
var data = BinaryData.FromStream(stream);
При вызове метода BinaryData.FromStream(), метод считывает поток и копирует его содержимое в новый буфер. Для больших потоков или приложений, где производительность критична, это дополнительное копирование может быть неэффективным.
Подход без копирования
Если вы работаете с MemoryStream, вы можете напрямую получить доступ к его базовому буферу и создать экземпляр BinaryData без копирования:
var stream = new MemoryStream();
stream.Write([1, 2, 3]);
// Это не требует копирования памяти
var data = new BinaryData(stream.GetBuffer().AsMemory(0, (int)stream.Position));
Этот подход использует GetBuffer() для доступа к базовому массиву байт MemoryStream, а затем оборачивает его в срез Memory<byte>, представляющий только записанную часть. Конструктор BinaryData принимает ReadOnlyMemory<byte>, поэтому преобразование происходит неявно.
Предупреждение: Изменчивость буфера: поскольку вы используете общий буфер, любые изменения исходного буфера MemoryStream могут повлиять данные в BinaryData. Убедитесь, что вы закончили запись в поток, прежде чем создавать BinaryData.
Интересно, что сама реализация BinaryData.FromStream создаёт новый экземпляр BinaryData таким же образом.
Источник: https://www.meziantou.net/zero-copy-binarydata-creation-from-memorystream-in-dotnet.htm