C# 为什么写入MemoryStream比写入文件慢?

C# 为什么写入MemoryStream比写入文件慢?,c#,.net,file-io,azure,memorystream,C#,.net,File Io,Azure,Memorystream,在我的Azure角色代码中,我下载了一个400兆字节的文件,该文件被分成10兆字节的块并存储在Blob存储中。我使用CloudBlob.DownloadToStream()进行下载 我尝试了两种选择。一种是使用FileStream——我创建了一个“write”FileStream,并将块逐个下载到同一个流中,而无需倒带,因此我最终得到了一个原始文件。另一个选项是创建一个MemoryStream对象,方法是传递一个略大于原始文件大小的数字作为流大小(以避免重新分配),然后将块下载到MemorySt

在我的Azure角色代码中,我下载了一个400兆字节的文件,该文件被分成10兆字节的块并存储在Blob存储中。我使用
CloudBlob.DownloadToStream()
进行下载

我尝试了两种选择。一种是使用
FileStream
——我创建了一个“write”
FileStream
,并将块逐个下载到同一个流中,而无需倒带,因此我最终得到了一个原始文件。另一个选项是创建一个
MemoryStream
对象,方法是传递一个略大于原始文件大小的数字作为流大小(以避免重新分配),然后将块下载到
MemoryStream
——这样我就得到了一个
MemoryStream
保存原始文件数据的对象

下面是一些伪代码:

var writeStream = new StreamOfChoice( params );
foreach( uri in urisToDownload ) {
    blobContainer.GetBlobReference( uri ).DownloadToStream( writeStream );
}
现在唯一的区别是,在一种情况下它是
FileStream
,在另一种情况下它是
MemoryStream
,其余的都是一样的。事实证明,使用
文件流
大约需要20秒,使用
内存流
大约需要30秒-是的,
文件流
速度更快。根据
\Memory\Available Bytes
性能计数器,在创建
MemoryStream
之前,虚拟机有大约1GB的可用内存,因此这不是由于分页


为什么写入文件要比写入内存流快?

乔恩可能在那里很在行。 最可能的解释是

  • 虚拟机监控程序实际上将内存分页到磁盘
  • 虚拟机监控程序交换文件位于低速磁盘(例如本地磁盘)上
  • 虚拟机的文件系统位于快速企业磁盘(比如SAN)上

  • 不管内存是否更快,你真的不应该分配这么大的内存块。请阅读此处。

    在调试模式(VS)下使用MemoryStream时,速度非常慢,即使数据量很小。在没有附加调试程序的情况下运行,它与FileStream相当,甚至比FileStream更快


    首先我被这弄糊涂了,最后来到这里。现在我对MemoryStream很满意。

    你确定你的内存流没有交换吗?你有1 GB的物理内存还是1 GB的虚拟内存?@Servy即使是虚拟机称之为“物理”的内存,我们如何知道虚拟机运行的真实机器中发生了什么?@sharptooth,在对这个性能问题进行故障排除时,您还应该查看报告分页活动的性能计数器:(为了100%确定分页情况),我将尝试在循环中使用可用内存和分页计数器。也许可以在本地机器上试一试。在本地计算机上,您可以配置为没有页面文件。不确定这是否有助于解决Azure上的问题。但可能会验证症状是否与交换一致。如果所涉及的磁盘具有相同的速度(或相同的磁盘),我们仍然希望文件写入优于页面文件写入,因为文件写入将是顺序的,这是任何基于旋转盘片的磁盘(无论是简单磁盘还是RAID,但不包括SSD)的情况在连续的情况下,他表现得更好。分页在大多数情况下不会造成太大的伤害,因为在完成分页时会有智能进入,所以分页内存在大多数情况下都优于文件访问,但在这一种情况下则不然。我不同意。我所指的分页是Hypervisor分页,而不是OS分页。它们不是一回事。虚拟机监控程序交换的成本要高得多,因为它不知道哪些页面最适合分页。第二,在大规模部署中,虚拟机监控程序分页通常放在服务器的本地磁盘上,而不是放在速度快得多的共享存储上。1:SAN存储>高压分页。2:基于磁盘的顺序>基于磁盘的随机。它们完全可以都是真的。我更不同意后者:)Sequential on disk>randon on disk,除了虚拟化之外都是真的。这里有很多可能性。像NetApp这样的系统上的随机写入将按顺序显示,因为它是一个COW文件系统。在HDS阵列上的随机写入将等于顺序写入,因为控制器中有大型缓存,在写入磁盘之前将写入提交到备有电池的缓存中。一旦涉及到虚拟化所使用的高端存储系统,许多“标准”的说法就不再适用了。这是非常正确的。还有一个原因我不明白为什么这是我在相当长一段时间内投票率最高的答案,而你得到了我给你的单曲+1。应该完全相反。