2012-08-17 57 views
15

在我的Azure角色代碼中,我下載了一個400兆字節的文件,該文件被分割成10兆字節塊並存儲在Blob存儲中。我使用CloudBlob.DownloadToStream()進行下載。爲什麼寫入MemoryStream比文件慢?

我試了兩個選項。一個是使用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之前有大約1千兆字節的可用內存,因此它不是由於分頁導致的。

爲什麼寫入文件的速度比寫入文件的速度要快?MemoryStream

+4

你確定你的內存流不交換? – Oded 2012-08-17 13:26:29

+0

有趣的問題,如果沒有進行MemoryStream的分頁應該快得多。您使用的實例大小是多少?你可以發佈一些代碼(即使這可能無關緊要,因爲你只是簡單地調用Storage Client庫)。 – 2012-08-17 13:28:59

+2

你有1 GB *物理*內存或1 GB *虛擬*內存嗎? – Servy 2012-08-17 13:29:03

回答

3

喬恩很可能在那裏。 的有可能的解釋是,

  1. 內存由管理程序到磁盤的實際調出。
  2. 管理程序交換文件位於速度較低的磁盤(如本地磁盤)上。
  3. VM的FileSystem位於快速企業磁盤(如SAN)上。

無論內存是否更快,你都不應該分配這麼大的內存塊。在這裏閱讀有關LOH vs SOH

+0

好吧,如果涉及的磁盤速度相同(或同一磁盤),我們仍然期望文件寫入打敗頁面文件寫入,因爲文件寫入將是連續的,這是基於任何基於旋轉磁盤的磁盤磁盤(無論是簡單還是RAID,但不包括SSD)在順序案例中效果更好。在大多數情況下,分頁往往不會造成太大的影響,因爲在完成分詞時,分頁內存會跳過文件訪問,但不是這一次。 – 2012-08-17 14:26:28

+0

我不同意。我指的分頁是Hypervisor分頁,而不是OS分頁。他們不是同一件事。虛擬機管理程序交換實際上比較昂貴,因爲它無法知道哪些頁面最適合被分頁。其次,虛擬機管理程序分頁常常放在服務器本地磁盤上的大規模部署中,而不是放在速度更快的共享存儲上。 – 2012-08-17 14:49:04

+0

這兩個都不同意其他。 1:SANS存儲> HV分頁。 2:基於磁盤的順序>基於磁盤的隨機。他們完全可以是真實的。 – 2012-08-17 14:52:47

1

在調試模式(VS)下使用MemoryStream時,即使數據量很小,速度也很慢。無需連接調試器即可運行,與FileStream相比甚至更快。

首先我被這個弄糊塗了,最後在這裏。現在我用MemoryStream很好。

相關問題