2017-01-31 48 views
1

我試圖在我的課堂上發現IO瓶頸,並且出乎意料地注意到sw.Write("m"); sw.Flush()可以比將1000000個消息寫入文件時更快,然後await sw.WriteAsync("m"); Await sw.FlushAsync();。有沒有人知道爲什麼?我的賭注是StreamWriter的構造函數採取String沒有參數化爲async使用流。StreamWriter:(Write + Flush)Async似乎比同步變體慢得多

下面的代碼可以從C#交互式啓動。是的,這不是衡量速度的最好的地方,但它無論如何都會顯示在手頭的事情:

var sr = new StreamWriter("G:\\file.file"); 
var N = 1000; 
var sw = new Stopwatch(); 
sw.Start(); 

for (var i = 0; i < N; ++i) 
{ 
    sr.Write("m"); // or await sr.WriteAsync("m"); 
    sr.Flush(); // or await sr.FlushAsync("m"); 
} 

sw.Stop(); 
Console.WriteLine("Completed " + N 
    + " iterations in " + sw.ElapsedMilliseconds + " milliseconds."); 

sr.Close(); 

從C#互動推出我的家用電腦上的輸出

在1已完成1000次迭代毫秒。

爲同步代碼和

完成1000次迭代在43383毫秒。

用於異步。

更新:另外我注意到,該方案減慢內FlushAsyncWriteAsync的工作速度幾乎與同步版本相同。

歡迎發表評論。

+0

可能看到[此答案](http://stackoverflow.com/a/18335900/4372746)。另外,當然你可以等待兩個小時,形成一個完整的職位? –

+0

@Glorin Oakenfoot感謝您的鏈接。 Yeap,我的壞,但我擔心我可能會忘記它:-( –

+0

我不知道爲什麼有人會使用異​​步寫入方法。同步寫入和異步寫入之間幾乎沒有區別。很快它不支付去異步。 – jdweng

回答

4

StreamWriter當給定文件路徑時,不以異步模式打開其基礎流。這可能會導致性能損失。如果你要使用它的異步,你應該打開自己的Stream

Stream s = new FileStream("G:\\file.file", FileMode.Create, FileAccess.Write, 
          FileShare.None, 4096, 
          FileOptions.Asynchronous | FileOptions.SequentialScan); 
StreamWriter sr = new StreamWriter(s); 

額外的東西要注意的是,你的標杆似乎並沒有捕捉到真實世界的使用。你真的在寫每個字符之後寫單字符串嗎?

異步確實有一定的固定數量的內存和GC開銷,並且對於這種短暫的操作 - 特別是StreamWriter.WriteAsync當前未針對小寫操作進行優化 - 您將看到遠遠超過更常見的開銷用法。

+0

我試圖創建一個'流'手動,但它仍然是慢得多的同步版本 不,我不寫單個字符的字符串,但我正在寫一個簡短的日誌消息。異步操作在一秒鐘內被稱爲幾百萬次,並且一切都很好。 –

+1

另外我注意到真正的問題出在'FlushAs ync'。'WriteAsync'的工作速度幾乎與同步版本相同。 –

+1

不幸的是'FileStream'上的'FlushAsync'是用假異步實現的。我希望它表現不佳。 –