簡體   English   中英

IEnumerable與IObservable在幕后有何不同?

[英]How does IEnumerable differ from IObservable under the hood?

我很好奇IEnumerableIObservable到底有何不同。 我分別理解了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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM