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