我有ArrayList ids
个包含String
个ID的对象,另一个ArrayList objs
包含具有字符串ID字段的对象。现在我有代码,找到ids
中objs
没有匹配的代码,如下所示:
var missing = new List<string>();
foreach (MyObj obj in objs)
{
if (!ids.Contains(obj.ID))
{
missing.Add(obj.ID);
}
}
这很好用。但是我把它改写成了一个更好的“在LINQ中思考”的练习:
var missing = objs.Cast<MyObj>().Select(x => x.ID).Except(ids.Cast<string>());
I expected this LINQ to be slower比foreach
+ Contains
方法(特别是由于Cast
调用),但LINQ运行得更快。什么是LINQ方法以不同的方式提供性能优势?
答案 0 :(得分:5)
LINQ Except
在内部使用HashSet
,其 O(1) Contains
方法性能,当它 O(n ){/ 1>} ArrayList
。这就是为什么它会更快。
但正如 Tim 在他的评论中指出的那样,你的Except
方法并没有真正产生任何结果。它只是定义了一个查询。只要需要结果,就会执行查询。它可能会被执行多次。您应该明确地添加ToList()
来获取List<T>
:
var missing = objs.Cast<MyObj>().Select(x => x.ID).Except(ids.Cast<string>()).ToList();
顺便说一下,为什么使用ArrayList
代替通用List<T>
?
答案 1 :(得分:1)
Except
使用HashSet<T>
(或类似的东西)来有效地找到哪些对象是相同的,而您的代码使用效率较低的List<T>.Contains
(或类似)方法。