LINQ包含vs Intersect(与其他任何东西!)

时间:2013-12-30 06:00:21

标签: c# performance linq ienumerable

我有一个大的IEnumerable EntityObjects和一个大的IEnumerable字符串,它们是对象的关键。

我想获得仅列出匹配键的对象的新列表。目前我通过Contains()这样做 - 但看起来很慢?

class Foo {
  string Key
  string Prop1
  int Prop2
  decimal Prop3
  Bar Prop4
  Thing Prop5
  Stuff Prop6
  ...more properties
}

IEnumerable<Foo> foos
IEnumerable<string> fooKeys

var matchedFoos = foos.Where(f => fooKeys.Contains(f.Key));

这可以恢复我的预期,但似乎很慢,我认为必须有更好的方法吗?我在Intersect上看到了一些帖子,但似乎是同一类型的可用数据?

有关信息:

  • foos.Count()约164,000
  • fooKeys.Count()约75,000

2 个答案:

答案 0 :(得分:3)

  1. 您应该在数据库上搜索(使用LINQ to Entities),而不是在应用程序上(使用LINQ to Objects)。

  2. 您可以将fooKeys更改为HashSet<string>(如果它还没有),以便Contains()方法调用 O(1)而不是 O(n)

    var keesSet = new HashSet<string>(fooKeys);
    var matchedFoos = foos.Where(f => keesSet.Contains(f.Key));
    

    但是如果收藏量很大,它仍然需要相当长的时间来进行搜索。

答案 1 :(得分:3)

我认为另一种变体join clause就像这样

IEnumerable<Foo> foos
IEnumerable<string> fooKeys

var matchedFoos = from foo in foos
                  join fk in fooKeys on foo.Key equals fk
                  select foo;