c# - 为什么在将 First() 应用于投影时此 linq 代码会呈指数级变慢?

标签 c# linq performance profiling

我正在尝试解析一个 500K 的文本文件。

这更像是一种学习练习 - 我知道还有其他方法可以获得我的结果。

我可能会错误地使用 linq-go,因为我对它还是有点陌生​​。

我的电脑很快。

我确定我在这里犯了一个“经典错误”——所以我的问题是:这是哪一个,我可以纠正我的逻辑,还是这不适合 Linq?

    var lines = File.ReadAllLines(@"C:\Users\aanodide\Desktop\APIUserGuide.txt");
    // add line numbers
    var qa = lines
        .Select((c,i) => new
        {
            i = i,
            c = c
        }); 
    var qb = qa.Skip(2312); // defs start at > 2312
    var qc = qb.Where( c => Regex.IsMatch(c.c, @"(\w+): ([a-zA-Z])?(.*)") );
    var qd = qc.Where( c => c.c.StartsWith("API Name:") );
    var qd_desc = qc.Where( c => c.c.StartsWith("Description:") ).Select( d => d.i );
     var qe = qd.Select( c => new {
        i = c.i,
        c = c.c,
        d = qd_desc.First(e => e > c.i) // --> IF I COMMENT OUT THIS, IT RUNS FAST, IN A FRACTION OF A SECOND<--
    }); 
     // Take(1) -> .013s
     // Take(10) -> .070s
     // Take(20) -> .446s
     // Take(40) -> 1.63s
     // Take(80) -> 6.49s
    foreach (var element in qe.Take(50))
    {
        Console.WriteLine (element.i);
    }

最佳答案

正如 Mark 所指出的,当您调用 First() 时,整个查询将被迭代。 First()qd 中的每个项目调用一次 - 这意味着整个文件为 qd 中的每个项目解析一次。

要修复它,您可以ToList() qd_desc,然后在该列表上执行First()。然后它只会被评估一次。

var qd_desc = qc.Where( c => c.c.StartsWith("Description:") ).Select( d => d.i ).ToList();

关于c# - 为什么在将 First() 应用于投影时此 linq 代码会呈指数级变慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5150308/

相关文章:

linq - 在 Linq 中处理 IDisposable

c# - MongoDB LinQ "Select"方法真的只会检索字段的子集吗?

c# - .net 比 java 快

c# - LINQ 的 Join 操作产生零项

C# 到 C++ 多线程,会出现什么问题?

c# - C#套接字阻止行为

c# - LINQ:如何使用 group by 子句获取 Max Id?

C#MVC : Return ViewModel or Model Class?

c# - 如何使用 C# 运行远程计算机程序 'run as administrator'

C# 查询 - 非静态方法需要目标