LINQ中的方法调用select(效率)

时间:2014-01-06 18:57:50

标签: c# asp.net linq foreach performance

我有一个关于LINQ与标准foreach循环的基于效率的问题。

我有一个方法,大致如下

var foos = users.Select(this.GenerateNullableFoo).Where(foo => foo != null);

由于某种原因,事实证明这是非常缓慢的。使用时间戳,我能够确定缓慢的点恰好在select的迭代(从最终返回语句到下一个方法调用的开始的时间)比其他任何东西慢得多(13秒)(总时间< = 14秒)。

当用以下内容替换时,每次迭代整个处理时间减少到不到1秒。

新代码:

var foos= new List<Foo>();

foreach (var user in users)
{
    var foo = GenerateNullableFoo(user);

        foo.IfNotNull(f => foos.Add(foo));
}

据我所知,我的代码工作正常并且新代码没有任何问题,但是,我完全不知道为什么使用上面的Select比看似相同的foreach慢10倍以上处理。是否有任何见解可以解释这个差异?

此外,整个列表不会保存,直到之后表示select / foreach,此时才会对db进行批量调用。

编辑:从起点到终点(和终止)的整个代码块如下:

//Code snippet pictured above
_repo.SaveFoo(Foos);
//at this point, the code terminates and is finished

1 个答案:

答案 0 :(得分:1)

正如其他人所说,LINQ表达式不会被投射到结果集,直到它被代码迭代,这意味着你所做的就是声明逻辑。

您发布的代码会导致投射LINQ表达式,很可能会多次。

解决此问题的最简单方法是将 .ToList()添加到表达式中,这将立即投影表达式,这意味着其他代码可以使用内存和已投影的列表,而不会导致其他投影/ calculate / etc等。

干杯,亚伦