我正在尝试解析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);
}
答案 0 :(得分:4)
正如Mark所说,当你致电First()
时,整个查询都会被重复。 First()
中的每个项目都会调用qd
一次 - 这意味着qd
中的每个项目都会解析整个文件一次。
要解决此问题,您可以ToList()
qd_desc
,并在该列表上执行First()
。然后它只会被评估一次。
即
var qd_desc = qc.Where( c => c.c.StartsWith("Description:") ).Select( d => d.i ).ToList();
答案 1 :(得分:3)
当您调用First()
时,将执行整个查询(即,迭代序列)。当您致电Skip()
,Where()
,Select()
或任何返回IEnumerable
的运算符时,在迭代序列之前,查询将不会执行。它在First()
(或任何返回单个项目的运算符)上发生的原因是您当时要求特定项目,因此要运行查询 以生成该结果