C# 通用列表 FindAll() 与 foreach

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/674632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 12:55:52  来源:igfitidea点击:

Generic list FindAll() vs. foreach

c#.netgenerics

提问by jon37

I'm looking through a generic list to find items based on a certain parameter.

我正在查看通用列表以根据某个参数查找项目。

In General, what would be the best and fastest implementation?
1. Looping through each item in the list and saving each match to a new list and returning that

一般来说,最好和最快的实现是什么?
1. 循环遍历列表中的每个项目并将每个匹配项保存到一个新列表中并返回

foreach(string s in list)
{ 
    if(s == "match")
    {
       newList.Add(s);
    }
} 

return newList;

Or
2. Using the FindAll method and passing it a delegate.

或者
2. 使用 FindAll 方法并将委托传递给它。

newList = list.FindAll(delegate(string s){return s == "match";});

Don't they both run in ~ O(N)? What would be the best practice here?

他们不是都在 ~ O(N) 中运行吗?这里的最佳做法是什么?

Regards, Jonathan

问候, 乔纳森

采纳答案by Egil Hansen

You should definitely use the FindAllmethod, or the equivalent LINQ method. Also, consider using the more concise lambda instead of your delegate if you can (requires C# 3.0):

您绝对应该使用该FindAll方法或等效的 LINQ 方法。此外,如果可以,请考虑使用更简洁的 lambda 而不是您的委托(需要 C# 3.0):

var list = new List<string>();
var newList = list.FindAll(s => s.Equals("match"));

回答by casperOne

I would use the FindAllmethodin this case, as it is more concise, and IMO, has easier readability.

在这种情况下,我会使用该FindAll方法,因为它更简洁,而且 IMO 更易于阅读。

You are right that they are pretty much going to both perform in O(N) time, although the foreachstatementshouldbe slightlyfaster given it doesn't have to perform a delegate invocation (delegates incur a slight overhead as opposed to directly calling methods).

你是正确的,他们是非常要在两者O(N)时间内执行,虽然foreach声明稍微快给它不具有执行委托调用(委托承担,而不是直接调用方法略有开销) .

I have to stress how insignificant this difference is, it's more than likely never going to make a difference unless you are doing a massivenumber of operations on a massivelist.

我要强调这种差异是如何微不足道,它的更可能永远不会有所作为,除非你正在做一个大规模的一个上操作的数量庞大的名单。

As always, test to see where the bottlenecks are and act appropriately.

与往常一样,测试以查看瓶颈所在并采取适当的行动。

回答by Reed Copsey

List.FindAll is O(n) and will search the entire list.

List.FindAll 是 O(n) 并将搜索整个列表。

If you want to run your own iterator with foreach, I'd recommend using the yield statement, and returning an IEnumerable if possible. This way, if you end up only needing one element of your collection, it will be quicker (since you can stop your caller without exhausting the entire collection).

如果您想使用 foreach 运行您自己的迭代器,我建议您使用 yield 语句,并在可能的情况下返回 IEnumerable。这样,如果您最终只需要集合中的一个元素,它会更快(因为您可以在不耗尽整个集合的情况下停止调用者)。

Otherwise, stick to the BCL interface.

否则,坚持使用 BCL 界面。

回答by Daniel Pratt

Any perf difference is going to be extremely minor. I would suggest FindAll for clarity, or, if possible, Enumerable.Where. I prefer using the Enumerable methods because it allows for greater flexibility in refactoring the code (you don't take a dependency on List<T>).

任何性能差异都将非常小。为了清楚起见,我建议 FindAll,或者,如果可能的话,Enumerable.Where。我更喜欢使用 Enumerable 方法,因为它允许在重构代码时具有更大的灵活性(您不依赖于List<T>)。

回答by matt_dev

Jonathan,

乔纳森,

A good answer you can find to this is in chapter 5 (performance considerations) of Linq To Action.

您可以在Linq To Action 的第 5 章(性能考虑)中找到一个很好的答案。

They measure a for each search that executes about 50 times and that comes up with foreach = 68ms per cycle / List.FindAll = 62ms per cycle. Really, it would probably be in your interest to just create a test and see for yourself.

他们为每次执行大约 50 次的搜索测量 a,得出 foreach = 68ms per cycle / List.FindAll = 62ms per cycle。真的,创建一个测试并亲自查看可能符合您的利益。

回答by olli-MSFT

Yes, they both implementations are O(n). They need to look at every element in the list to find all matches. In terms of readability I would also prefer FindAll. For performance considerations have a look at LINQ in Action(Ch 5.3). If you are using C# 3.0 you could also apply a lambda expression. But that's just the icing on the cake:

是的,它们的实现都是 O(n)。他们需要查看列表中的每个元素以找到所有匹配项。在可读性方面,我也更喜欢 FindAll。出于性能考虑,请查看LINQ in Action(Ch 5.3)。如果您使用的是 C# 3.0,您还可以应用 lambda 表达式。但这只是锦上添花:

var newList = aList.FindAll(s => s == "match");

回答by MRFerocius

Im with the Lambdas

我和 Lambdas

List<String> newList = list.FindAll(s => s.Equals("match"));

回答by William Niu

Unless the C# team has improved the performance for LINQand FindAll, the following article seems to suggest that forand foreachwould outperform LINQand FindAllon object enumeration: LINQ on Objects Performance.

除非C#团队已经提高了性能LINQFindAll,下面的文章似乎表明,forforeach将跑赢大市LINQ,并FindAll在对象列举:对对象性能LINQ

This artilce was dated back to March 2009, just before this post originally asked.

这篇文章的历史可以追溯到 2009 年 3 月,就在这篇文章最初提出之前。