[英]How does IEnumerable differ from IObservable under the hood?
我很好奇IEnumerable
與IObservable
到底有何不同。 我分別理解了pull和push模式,但是在內存等方面,C#如何通知訂戶(對於IObservable)它應該接收內存中的下一部分數據進行處理? 被觀察的實例如何知道它已發生數據更改以推送到訂閱服務器。
我的問題來自於我正在從文件中逐行讀取的測試。 該文件總共約為6Mb。
標准時間:4.7秒,行:36587
接收時間:0.68秒,行:36587
Rx如何在文件的每一行上大幅度改善常規迭代?
private static void ReadStandardFile()
{
var timer = Stopwatch.StartNew();
var linesProcessed = 0;
foreach (var l in ReadLines(new FileStream(_filePath, FileMode.Open)))
{
var s = l.Split(',');
linesProcessed++;
}
timer.Stop();
_log.DebugFormat("Standard Time Taken: {0}s, lines: {1}",
timer.Elapsed.ToString(), linesProcessed);
}
private static void ReadRxFile()
{
var timer = Stopwatch.StartNew();
var linesProcessed = 0;
var query = ReadLines(new FileStream(_filePath, FileMode.Open)).ToObservable();
using (query.Subscribe((line) =>
{
var s = line.Split(',');
linesProcessed++;
}));
timer.Stop();
_log.DebugFormat("Rx Time Taken: {0}s, lines: {1}",
timer.Elapsed.ToString(), linesProcessed);
}
private static IEnumerable<string> ReadLines(Stream stream)
{
using (StreamReader reader = new StreamReader(stream))
{
while (!reader.EndOfStream)
yield return reader.ReadLine();
}
}
我的直覺是您所看到的行為反映了OS將文件緩存。 我可以想象,如果您調換了呼叫順序,那么您會看到類似的速度差異,只是交換了一下。
您可以通過執行一些預熱運行或通過在測試每個文件之前使用File.Copy
將輸入文件復制到臨時文件中來提高此基准。 這樣,文件就不會“很熱”,您將得到一個公平的比較。
我懷疑您正在看到CLR的某種內部優化。 它可能在兩次調用之間將文件的內容緩存在內存中,以便ToObservable
可以更快地提取內容...
編輯:哦,擁有瘋狂昵稱eeh的好同事... @sixlettervariables更快,他可能是正確的:操作系統而不是CLR進行了優化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.