【问题标题】:How does IEnumerable differ from IObservable under the hood?IEnumerable 与 IObservable 的本质有何不同?
【发布时间】:2012-04-02 06:07:59
【问题描述】:

我很好奇 IEnumerable 与 IObservable 的本质区别。我分别了解拉取和推送模式,但 C# 在内存等方面如何通知订阅者(对于 IObservable)它应该接收内存中的下一位数据以进行处理?观察到的实例如何知道要推送给订阅者的数据发生了变化。

我的问题来自我正在从文件中逐行读取的测试。该文件总共大约 6Mb。

标准耗时:4.7s,行数:36587

Rx 耗时:0.68s,行数: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();
    }
}

【问题讨论】:

  • 如果您在对该应用程序进行基准测试时切换他们的调用顺序,RX 是否仍然更快?
  • 时代倒退了!正在进行某种优化!事实上,Rx 的运行速度较慢(大约 5 秒)。

标签: c# system.reactive ienumerator


【解决方案1】:

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

编辑:哦,有疯狂昵称的好同事 eeh ...@sixlettervariables 更快,他可能是对的:优化的是操作系统而不是 CLR。​​

【讨论】:

    【解决方案2】:

    我的预感是您看到的行为反映了操作系统缓存文件。我想如果你颠倒调用的顺序,你会看到类似的速度差异,只是交换了。

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

    【讨论】:

    • 正确。是的,似乎正在发生一些缓存。
    • 对于 10MB 或 25Mb 的文件,它们的速度没有明显差异,之后标准将蛋糕(4 倍加速)通过直到 100MB(我测试过的最大)随机生成的数据用逗号.这包括允许 JIT 在给出实际结果之前通过运行每个方法 3 次来“预热”。与任何基准一样,它将特定于您的操作环境。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2013-06-07
    相关资源
    最近更新 更多