IEnumerable和IOobservable有什么不同

本文关键字:什么 IOobservable IEnumerable | 更新日期: 2023-09-27 18:27:59

我很好奇IEnumerableIObservable到底有什么不同。我分别理解"拉"answers"推"模式,但就内存等而言,C#如何通知订阅者(对于IObservable)它应该接收内存中的下一位数据进行处理?观察到的实例如何知道要推送给订阅者的数据发生了变化。

我的问题来自于我正在进行的一项测试,该测试是从文件中逐行读取的。该文件的总容量约为6Mb。

标准耗时:4.7秒,线路:36587

Rx耗时: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();
    }
}

IEnumerable和IOobservable有什么不同

我的直觉是,您看到的行为反映了操作系统缓存文件。我可以想象,如果你颠倒通话顺序,你会看到类似的速度差异,只是交换。

您可以通过执行一些预热运行或在测试每个测试之前使用File.Copy将输入文件复制到临时文件来改进此基准测试。这样一来,文件就不会"热",而且你会得到一个公平的比较。

我怀疑您看到了CLR的某种内部优化。它可能会在两次调用之间将文件的内容缓存在内存中,这样ToObservable就可以更快地提取内容。。。

编辑:哦,有个疯狂昵称eeh的好同事@六字母变量的速度更快,他可能是对的:与其说CLR优化,不如说是操作系统在优化。