1

我有一个ArrayList ids包含StringID 的对象,另一个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>());

我预计此 LINQ 会foreach+Contains方法慢(尤其是由于Cast调用),但 LINQ 运行速度要快得多。LINQ 方法有何不同之处可以带来性能优势?

4

2 回答 2

5

LINQ在内部Except使用HashSet,它具有O(1) Contains方法性能,当它是O(n)ArrayList。这就是为什么它更快。

但正如蒂姆在他的评论中指出的那样,你的Except方法并没有真正产生任何结果。它只是定义了一个查询。只要您需要结果,就会执行查询。并且它可能被执行不止一次。您应该明确添加ToList()调用 get :List<T>

var missing = objs.Cast<MyObj>().Select(x => x.ID).Except(ids.Cast<string>()).ToList();

顺便说一句,你为什么使用ArrayList而不是 generic List<T>

于 2013-10-22T20:43:36.707 回答
1

Except使用 a HashSet<T>(或类似的东西)来有效地查找相同的对象,而您的代码使用效率较低List<T>.Contains(或类似)的方法。

于 2013-10-22T20:43:56.633 回答