2012-03-28 20 views
5

當我向文件寫入大量數據< 2GB時遇到問題。首先〜1.4GB數據寫入速度快(100 MB/s),而代碼變得非常慢(0-2 MB/s)。將大數據寫入文件緩存問題

我的代碼(簡化)是:

//FileOptions FILE_FLAG_NO_BUFFERING = (FileOptions)0x20000000; 
    FileOptions fileOptions = FileOptions.SequentialScan; 

    int fileBufferSize = 1024 * 1024; 
    byte[] Buffer = new byte[32768]; 

    Random random = new Random(); 
    long fileSize = 2588490188; 
    long totalByteWritten = 0; 

    using (FileStream fs = File.Create(@"c:\test\test.bin", fileBufferSize, fileOptions)) 
    { 
     while (totalByteWritten < fileSize) 
     { 
      random.NextBytes(Buffer); 
      fs.Write(Buffer, 0, Buffer.Length); 
      totalByteWritten += Buffer.Length; 
      //Thread.Sleep(10); 
     } 
    } 

我認爲這是在「快寫性能」 RAM使用增加以及,當內存佔用停止增加有相關的緩存問題,其實是一個問題是表現下降。

我曾嘗試:

  • 改變異步寫入 - >無顯著改變

  • 變化陣列緩衝區大小 - >無顯著改變

  • 變化fileBufferSize - >沒有明顯的變化,但有一個大的緩衝區~100MB,寫入性能很快,當內存使用停止增加時,寫入p erformance變爲0,比,一段時間後,又回到100MB,它煤層高速緩存緩衝區「刷新」

  • 變化fileOptionWriteThrough - >性能總是慢..

  • 後加入XX循環fs.Flush(true) - >無顯著改變

  • 取消註釋Thread.Sleep(10) - >寫入速度總是好的.....這是奇怪的

+0

它似乎是thread.sleep幫助內存被清除並轉儲到磁盤。你可以做你的高寫入速度的基準嗎?我認爲在開始時,一切都寫到內存中,直到它已滿,然後兩個窗口頁面文件正在寫入(因爲你最大化了內存)並且你的文件繼續寫入,所以性能越來越差。但我可能是錯的:) – Dementic 2012-03-28 07:46:34

+0

有任何機會在系統上運行一些防病毒軟件,在RAM填滿並且數據開始寫入磁盤後性能下降? – 2012-03-28 08:03:42

+0

嗯,根據我的理解,'FileOptions.SequentialScan'在你的場景中根本沒有用處。當*從光盤不讀寫*時,這將是重要的。據我瞭解,這只是一個簡化的代碼片段,所以我猜'random.NextBytes'只是你真實數據的佔位符。真實數據來自哪裏?收集真實數據是罪魁禍首嗎? – 2012-03-28 08:25:50

回答

0

在完成寫入前面的塊並且陷入混亂之前,它是否以某種方式嘗試寫入? (看起來不太可能,但奇怪的是Thread.Sleep應該加快速度,這也許可以解釋它)。如果修改using語句中的代碼來鎖定文件流,會發生什麼情況?

using (FileStream fs = File.Create(@"c:\testing\test.bin", fileBufferSize, fileOptions)) 
{ 
    while (fs.Position < fileBufferSize) 
    { 
    lock(fs) // this is the bit I have added to try to speed it up 
    { 
     random.NextBytes(Buffer); 
     fs.Write(Buffer, 0, Buffer.Length); 
    } 
    } 
} 

編輯:我已經優化了你的例子代碼,以使得它寫的正確大小的文件所需的while循環。

順便說一句,當我運行示例代碼時,它會非常快速地使用或不使用lock語句,並且添加睡眠會顯着降低睡眠速度。