Почему запись в MemoryStream медленнее, чем в файл?

В моем коде роли Azure я загружаю файл 400 мегабайт, который разделен на 10 мегабайт и хранится в хранилище Blob. Я использую CloudBlob.DownloadToStream() для загрузки.

Я попробовал два варианта. Один использует FileStream - я создаю "пишу" FileStream и загружаю куски один за другим в один и тот же поток без перематывания, и поэтому я получаю исходный файл. Другой вариант - создать объект MemoryStream, передав число, немного большее, чем исходный размер файла, в качестве размера потока (чтобы избежать перераспределения) и загрузки фрагментов в этот MemoryStream - таким образом, я получаю MemoryStream сохраняя исходные данные файла.

Здесь некоторый псевдокод:

var writeStream = new StreamOfChoice( params );
foreach( uri in urisToDownload ) {
    blobContainer.GetBlobReference( uri ).DownloadToStream( writeStream );
}

Теперь единственное отличие состоит в том, что в одном случае a FileStream и a MemoryStream в другом, все остальное одно и то же. Оказывается, это занимает около 20 секунд с FileStream и около 30 секунд с MemoryStream - да, FileStream оказывается быстрее. Согласно счетчику производительности \Memory\Available Bytes виртуальная машина имеет около 1 ГБ памяти, доступную в настоящий момент до создания MemoryStream, поэтому она не из-за пейджинга.

Почему запись в файл будет быстрее, чем MemoryStream?

Ответы

Ответ 1

Jon, вероятно, находится на поле. Наиболее вероятным объяснением является

  • Память фактически выгружается гипервизором на диск.
  • Файл подкачки гипервизора находится на диске с более низкой скоростью (например, на локальном диске).
  • Файловая система VM находится на быстром корпоративном диске (скажем, SAN).

Независимо от того, быстрее или нет памяти, вы действительно не должны выделять такие большие блоки памяти. Здесь читайте о LOH vs SOH.

Ответ 2

При использовании MemoryStream в режиме отладки (VS) скорость очень медленная, даже при небольшом количестве данных. Запуск без отладки в приложении сопоставим или даже быстрее, чем FileStream.

Сначала я смутился этим и оказался здесь. Теперь я в порядке с MemoryStream.