我正在查看通用列表,以根据某个参数查找项目。
总的来说,最好和最快的实施是什么? 1.循环遍历列表中的每个项目并将每个匹配保存到新列表并返回
foreach(string s in list)
{
if(s == "match")
{
newList.Add(s);
}
}
return newList;
或者
2.使用FindAll方法并向其传递委托。
newList = list.FindAll(delegate(string s){return s == "match";});
难道它们都不是在~O(N)中运行?这里最好的做法是什么?
此致 乔纳森
答案 0 :(得分:46)
您绝对应该使用FindAll
方法或等效的LINQ方法。另外,如果可以,请考虑使用更简洁的lambda而不是您的委托(需要C#3.0):
var list = new List<string>();
var newList = list.FindAll(s => s.Equals("match"));
答案 1 :(得分:9)
在这种情况下,我会使用FindAll
method,因为它更简洁,而且IMO更易于阅读。
你是对的,他们几乎都会在O(N)时间内执行,虽然foreach
statement 不必执行委托调用(委托会产生轻微的开销,而不是直接调用方法)。
我必须强调这种差异是多么微不足道,除非你在大量列表上进行大量操作,否则它很可能永远不会有所作为
与往常一样,测试瓶颈在哪里并采取相应的行动。
答案 2 :(得分:5)
乔纳森,
您可以在Linq To Action的第5章(性能考虑因素)中找到一个很好的答案。
他们为每次执行大约50次的搜索测量a,并且每个周期得出foreach = 68ms / List.FindAll =每个周期62ms。真的,你可能只想创建一个测试并亲自看看。
答案 3 :(得分:4)
List.FindAll为O(n),将搜索整个列表。
如果你想用foreach运行你自己的迭代器,我建议使用yield语句,如果可能的话返回一个IEnumerable。这样,如果你最终只需要你收藏的一个元素,它会更快(因为你可以停止你的调用者而不会耗尽整个集合)。
否则,请坚持使用BCL界面。
答案 4 :(得分:3)
任何表演差异都会非常小。我建议FindAll是为了清晰,或者,如果可能的话,我建议使用Enumerable.Where。我更喜欢使用Enumerable方法,因为它允许重构代码的更大灵活性(你不依赖于List<T>
)。
答案 5 :(得分:2)
是的,他们两个实现都是O(n)。他们需要查看列表中的每个元素以查找所有匹配项。在可读性方面,我也更喜欢FindAll。出于性能考虑,请查看LINQ in Action(第5.3节)。如果您使用的是C#3.0,则还可以应用lambda表达式。但这只是锦上添花:
var newList = aList.FindAll(s => s == "match");
答案 6 :(得分:1)
我和Lambdas
List<String> newList = list.FindAll(s => s.Equals("match"));
答案 7 :(得分:0)
除非C#团队改进了LINQ
和FindAll
的效果,否则以下文章似乎表明for
和foreach
将胜过LINQ
和对象枚举FindAll
:LINQ on Objects Performance。
这个艺术可以追溯到2009年3月,就在这篇帖子最初提出之前。