.NET MemoryStream - следует ли устанавливать емкость?

Это, вероятно, действительно простой вопрос, я думаю, все, что мне нужно, это Лучшая практика для объявления нового MemoryStream

В чем разница между следующими двумя образцами:

MemoryStream myStream = new MemoryStream(0x10000);

or

MemoryStream myStream = new MemoryStream();

Очевидно, я знаю, что в первом примере была установлена ​​начальная емкость потока. Но оба они имеют автоматически изменяемую емкость.

Есть ли причина, по которой я должен использовать один метод, а не другой?


person David Hamilton    schedule 05.01.2011    source источник
comment
К вашему сведению, MemoryStream является частью .NET, а не C #   -  person John Saunders    schedule 06.01.2011
comment
Хороший момент, на самом деле, не думал, это, очевидно, применимо к VB и остальным языкам .NET.   -  person David Hamilton    schedule 06.01.2011
comment
Напоминаем, что если вы не установили его в конструкторе, вы все равно можете вызвать свойство, чтобы оно увеличивалось позже.   -  person Scott Chamberlain    schedule 18.06.2013


Ответы (7)


Есть накладные расходы, связанные с изменением размера потока памяти. Если вы знаете или иным образом имеете разумное предположение относительно ожидаемого размера, который необходимо сохранить в потоке памяти, вы захотите использовать этот размер в качестве начальной емкости. В противном случае используется размер по умолчанию, равный 0, и он будет изменяться по мере добавления данных.

person iammichael    schedule 05.01.2011
comment
Действительно ли размер по умолчанию 4096? MSDN сообщает, что это ноль - person Dave Hillier; 18.06.2013
comment
Это было долго. Я не знаю, откуда у меня этот первоначальный размер 4096. Я не могу подтвердить его сейчас. Отредактировано. - person iammichael; 18.06.2013
comment
Интересный факт для .net 4, используя ILSpy, я обнаружил, что он действительно имеет начальный размер 0, но когда вы записываете первый байт, он вызывает частную функцию EnsureCapacity, которая имеет минимальный размер 256. Каждое увеличение после этого начального 256 удваивает текущая вместимость. - person Scott Chamberlain; 18.06.2013

Старый вопрос я знаю, но для протокола;

Если вы имеете дело с действительно большим объемом данных (более одного ГБ в моем случае), установка начальной емкости была единственным способом заставить его работать в приемлемый период времени и без остановки сервера. В этом сценарии решающее значение имели накладные расходы на изменение размера.

person Felipe Pereira    schedule 19.11.2013

Если вы знаете, какой размер вам понадобится, я считаю, что его явная установка улучшит производительность, потому что фреймворку не придется изменять размер потока несколько раз.

person Ilya Kogan    schedule 05.01.2011

Если вы уже точно знаете, сколько байтов вы хотите сохранить, настройка его явно в конструкторе кажется правильным - в общем, я бы сделал это как можно проще и просто использовал конструктор по умолчанию без параметров, это просто еще одна вещь, которая у вас есть читать и понимать при сохранении кода в противном случае.

person BrokenGlass    schedule 05.01.2011

Если вы знаете, что вам потребуется 0x10000 байт данных, первый фрагмент кода гарантирует, что поток памяти будет инициализирован до этого размера и никогда не потребуется его увеличивать. Могут быть некоторые последствия для производительности в зависимости от того, как класс управляет нижележащим буфером и нужен ли ему непрерывный блок памяти; в зависимости от специфики изменение размера может оказаться дорогостоящей операцией.

person Szymon Rozga    schedule 05.01.2011
comment
[...] Никогда не нужно будет увеличивать. - У меня такое ощущение, что это ложь, если кто-то это читает. - person Zoey; 22.05.2013
comment
Да, только если вы передадите массив байтов в конструктор, MemoryStream не станет изменяемым. См. MSDN Инициализирует новый экземпляр класса MemoryStream с расширяемой емкостью, инициализированной, как указано. - person Scott Chamberlain; 18.06.2013

При изменении размера потока памяти создается новый буфер byte [] нового размера. Если эта операция выполняется часто, вы можете столкнуться с одной из двух проблем в зависимости от размера буфера: 1. Система выдает OurOfMemoryException 2. Вся память в куче фрагментируется. Это дает непредсказуемые последствия. Например, конструктор System.Drawing.Bitmap не работает с сообщением «Параметр недействителен».

person Alex    schedule 06.10.2016

В первом случае вы избегаете затрат на автоматическое изменение размера структуры, пока необходимый размер меньше значения, переданного конструктору.

person Przemysław Michalski    schedule 05.01.2011