为什么向MemoryStream写入比写入文件慢?

15
在我的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 );
}
现在唯一的区别是一个情况下使用了FileStream,另一个情况下使用了MemoryStream,其他都相同。结果发现使用FileStream大约需要20秒钟,而使用MemoryStream则需要30秒钟 - 是的,FileStream实际上更快。根据\Memory\Available Bytes性能计数器,在创建MemoryStream之前,虚拟机当前有大约1GB的可用内存,因此这并不是由于分页造成的。
为什么写入文件比写入MemoryStream更快呢?

4
你确定你的内存流没有交换吗? - Oded
2
你有1GB的物理内存还是1GB的虚拟内存 - Servy
3
即使虚拟机称其为“物理”,我们如何知道在运行虚拟机的真实主机中发生了什么? - Jon Hanna
2
@sharptooth,在解决这个性能问题的同时,您还应该查看报告分页活动的性能计数器:http://technet.microsoft.com/en-us/library/cc958290.aspx(只是为了100%确定分页情况)。 - Sandrino Di Mattia
1
我会在循环中尝试可用内存和分页计数器。也许可以在本地机器上尝试。在本地机器上,您可以配置为没有页面文件。不确定这是否有助于解决您在Azure上的问题。但可能可以验证症状是否与交换一致。 - paparazzo
显示剩余6条评论
2个回答

3

Jon可能是正确的。

最有可能的解释是:

  1. 内存实际上被超级管理程序分页到磁盘。
  2. 超级管理程序交换文件在较低速度的磁盘上(例如本地磁盘)。
  3. 虚拟机的文件系统位于快速企业磁盘上(例如SAN)。

无论内存是否更快,您真的不应该分配如此大块的内存。在这里阅读关于LOH vs SOH


如果涉及的磁盘速度相同(或是同一块磁盘),我们仍然期望文件写入会比页面文件写入更快,因为文件写入是顺序的,这在任何基于旋转盘的磁盘上都是如此(无论是简单的还是RAID,但不包括SSD)。由于智能技术的应用,分页大多数情况下不会对性能造成太大影响,因此对于大多数情况,分页内存优于文件访问,但不包括这种情况。 - Jon Hanna
我不同意。我所提到的分页是指虚拟机监视器分页,而不是操作系统分页。它们并不相同。虚拟机监视器交换开销更大,因为它无法知道哪些页面最适合被分页出去。其次,虚拟机监视器分页经常被放置在服务器的本地磁盘上,而不是更快的共享存储中,在大规模部署中这样做。 - M Afifi
两者并不相互矛盾。1:SANS存储> HV分页。2:基于磁盘的顺序访问>基于磁盘的随机访问。它们完全可以同时成立。 - Jon Hanna
更多的是后者我不能同意 :) 在磁盘上顺序写入 > 随机写入,这是正确的,除了虚拟化。这里有很多可能性。像NetApp这样的系统上的随机写入将显示为顺序写入,因为它是一个COW文件系统。在HDS阵列上进行随机写入将等于顺序写入,因为控制器中有大型缓存,在写入磁盘之前将写入提交到电池备份缓存中。一旦涉及到虚拟化使用的高端存储系统,许多“标准”语句就不再成立了。 - M Afifi
这是非常正确的。这也是我不明白为什么这是我最近得到的最高票答案的另一个原因,而你只得到了我给你的单个+1。应该完全相反。 - Jon Hanna

1

在使用MemoryStream进行调试时(VS),即使只有少量数据,速度也非常慢。但是在不附加调试器的情况下运行,它与FileStream相比甚至更快。

一开始我对此感到困惑,最终找到了解决方案。现在我已经熟悉使用MemoryStream了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接