JSC*_*JSC 37 c# foreach lambda linq-to-objects
从性能的角度来看,你应该使用"嵌套的foreach"或"lambda/linq查询"?
Jon*_*eet 59
尽可能编写最清晰的代码,然后进行基准测试和配置文件以发现任何性能问题.如果您确实遇到了性能问题,可以尝试使用不同的代码来确定它是否更快(尽可能使用尽可能真实的数据进行测量),然后判断性能的提高是否值得提高可读性击中.
一个直接foreach的办法将在许多情况下比LINQ更快.例如,考虑:
var query = from element in list
where element.X > 2
where element.Y < 2
select element.X + element.Y;
foreach (var value in query)
{
Console.WriteLine(value);
}
Run Code Online (Sandbox Code Playgroud)
现在有两个where子句和一个select子句,所以每个最终的项都必须通过三个迭代器.(显然,在这种情况下,两个where子句可以合并,但我总的来说.)
现在将它与直接代码进行比较:
foreach (var element in list)
{
if (element.X > 2 && element.Y < 2)
{
Console.WriteLine(element.X + element.Y);
}
}
Run Code Online (Sandbox Code Playgroud)
这将运行得更快,因为它可以运行更少的篮球.有可能控制台输出会使迭代器成本相形见绌,我当然更喜欢LINQ查询.
编辑:回答"嵌套的foreach"循环...通常用SelectMany或表示第二个from子句:
var query = from item in firstSequence
from nestedItem in item.NestedItems
select item.BaseCount + nestedItem.NestedCount;
Run Code Online (Sandbox Code Playgroud)
这里我们只添加一个额外的迭代器,因为我们已经在第一个序列中使用了一个额外的迭代器,因为嵌套foreach循环.还有一些开销,包括在委托中进行投影而不是"内联"(我之前没有提到过)的开销,但它仍然与嵌套的foreach性能没有太大差别.
当然,这并不是说你不能用LINQ射击自己.如果你不首先吸引你的大脑,你可以编写极其低效的查询 - 但这远非LINQ独有的......
Amy*_*y B 23
如果你这样做
foreach(Customer c in Customer)
{
foreach(Order o in Orders)
{
//do something with c and o
}
}
Run Code Online (Sandbox Code Playgroud)
您将执行Customer.Count*Order.Count迭代
如果你这样做
var query =
from c in Customer
join o in Orders on c.CustomerID equals o.CustomerID
select new {c, o}
foreach(var x in query)
{
//do something with x.c and x.o
}
Run Code Online (Sandbox Code Playgroud)
您将执行Customer.Count + Order.Count迭代,因为Enumerable.Join是作为HashJoin实现的.
Mar*_*ell 11
它更复杂.最终,LINQ-to-Objects的大部分是(幕后)一个foreach循环,但是增加了一些抽象/迭代器块等的开销.但是,除非你在两个版本中做了非常不同的事情(foreach vs LINQ) ,他们都应该是O(N).
真正的问题是:有没有更好的方法来编写您的特定算法,这意味着foreach效率低下?LINQ可以帮你吗?
例如,LINQ可以轻松地对数据进行散列/分组/排序.