【问题标题】:Linq performance: Any vs. Contains [duplicate]Linq 性能:任何与包含 [重复]
【发布时间】:2013-06-22 12:44:57
【问题描述】:

这个问题和this one有关,但不完全一样我认为

给定:

class Foo
{
  public string Bar { get; set; }
}
...
var c1 = new List<Foo>() { ... };
var c2 = new List<Foo>() { ... };

以下 2 个循环给出相同的结果:

  foreach (var item in c2.Where(f => c1.Any(f1 => f1.Bar.Equals(f.Bar))))
  { ... }

  foreach (var item in c2.Where(f => c1.Select(f1 => f1.Bar).Contains(f.Bar)))
  { ... }

它们是否同样快?

the other question 的区别在于,这里额外的Select 语句是否改变了底层集合性质的重要性。

换句话说:这是否包含:

foos.Contains(foo1)

作用于与此相同的“集合类型”

foos.Select(f=>f.Bar).Contains(foo1.Bar)

我可能的 - 天真的想法可能是:“一旦我们在 Linq 的 Select 后面,一切都只是'列表',所以 Any 和 Contains 都是 O(n)。”

【问题讨论】:

  • 非常接近您的问题:stackoverflow.com/questions/4445219/…
  • 其实你自己回答了(你可以在调试中通过断点得到确认...
  • 这两种情况略有不同,您正在检查字符串是否相等,而另一种情况您正在检查一个字符串是否包含另一个字符串。
  • 您应该使用Join 来执行此操作。这两种提议的解决方案都表现不佳,因为它们都在f1 上对c2 中的每个项目进行线性搜索。 Join 可以避免这种情况,并在 O(n+m) 时间内完成,而不是 O(n*m) 时间。
  • @Kevin 否。在一种情况下,他查看是否至少有一个项目的两个字符串相等,在第二种情况下,他查看序列是否包含特定项目,其中 contains 表示存在是至少一项与提供的项相同的项。这两个查询在功能上没有区别。

标签: c# performance linq


【解决方案1】:

这两个查询从根本上实现了相同的算法。它们将分别为c2 中的每个项目迭代c1,比较两个对象的Bar 属性,并在找到匹配项时立即返回。这两种情况的渐近复杂度是相同的,这意味着随着这两种情况的大小增加,它们的扩展性都一样好(或同样糟糕,视情况而定)。

在与另一种方法相关的开销方面,两者之间可能存在微小差异,但差异不会很大,并且随着集合大小的增加,它们会越来越小。没有任何真正的性能理由来选择两者中的一个。

有一个您没有显示的选项比其中任何一个都快很多。您可以使用Join 查找c1 中也存在于c2 中的所有项目,而无需对序列进行线性搜索:

var query = from first in c1
    join second in c2
    on first.Bar equals second.Bar
    select first;

另一种选择是使用HashSet 而不是List,因为这样更容易搜索:

var set = new HashSet<string>(c1.Select(item => item.Bar));

var query = c2.Where(item => set.Contains(item.Bar));

(这个解决方案非常接近 Join 在内部所做的。)

这两种解决方案都比您提出的任何一种解决方案都快很多

【讨论】:

    【解决方案2】:

    您的第一种方法将迭代和比较一次并返回结果。

    第二个查询会比较慢,因为它会迭代并将Bar 属性提取到一个集合中,然后迭代并与f.Bar 进行比较以创建最终结果。

    【讨论】:

    • 这是错误的。 Linq 查询是懒惰地评估的。它只会根据需要提取Bar 属性,并且不会创建中间集合。
    • @p.s.w.g 谢谢,这回答了我问题的最后一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-11
    相关资源
    最近更新 更多