C# LINQ select内部的方法调用(效率)

C# LINQ select内部的方法调用(效率),c#,asp.net,linq,foreach,performance,C#,Asp.net,Linq,Foreach,Performance,我有一个关于LINQ和标准foreach循环的基于效率的问题 我有一个方法,它大致执行以下操作 var foos = users.Select(this.GenerateNullableFoo).Where(foo => foo != null); 结果,出于某种原因,这是一个极其缓慢的过程。使用时间戳,我能够确定慢度点正好在select的迭代时(从最终返回语句到下一个方法调用开始的时间),它比其他任何方法都慢得多(13秒)(total time正如其他人所说,LINQ表达式在被代码迭代

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

我有一个方法,它大致执行以下操作

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

结果,出于某种原因,这是一个极其缓慢的过程。使用时间戳,我能够确定慢度点正好在select的迭代时(从最终返回语句到下一个方法调用开始的时间),它比其他任何方法都慢得多(13秒)(total time正如其他人所说,LINQ表达式在被代码迭代之前不会投影到结果集,这意味着您所做的只是声明逻辑

您发布的未发布的代码会导致LINQ表达式被投影,而且很可能会被多次投影

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


干杯,Aaron

您如何使用您的查询?例如,如果您对结果进行多次迭代,这将很容易解释行为。您是否尝试过
var foos=users.Select(this.GenerateNullableFoo).Where(foo=>foo!=null)
.ToList()
?这将创建更类似于
foreach
的代码。为什么顶部有
foo!=null
,而
foo.IfNotNull(…)
在底部?这两个不相等。第二个构建了一个列表,其中第一个创建了一个IEnumerable。正如其他注释所指出的,多次使用第一个的结果将导致多次执行。该列表将在后续使用时简单地在集合上迭代。我不确定我的代码将如何使用结果多次选择的ts。这些代码段之后的唯一代码是批量保存_repo.SaveAll(Foos);然后代码完成并完全终止该过程。@TimS.where子句对生成的foo起作用,以确保其不为null,这与在底部IfNotNull子句中所做的相同。这两项都只是检查“如果foo不为null,请将其保留在列表中/将其添加到列表中”
var foos= new List<Foo>();

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

        foo.IfNotNull(f => foos.Add(foo));
}
//Code snippet pictured above
_repo.SaveFoo(Foos);
//at this point, the code terminates and is finished