LINQ中的速度提升Where(Array.Contains)

时间:2013-10-14 11:24:59

标签: c# arrays linq

我最初有一个方法,其中包含一个返回int[]的LINQ查询,然后以类似于以下的方式使用它:

int[] result = something.Where(s => previousarray.Contains(s.field));

在第一个数组被检索为本地IQueryable<int>之前,结果非常缓慢。它现在运行得非常快,但是我想知道如果我从其他地方提供int[]然后必须按上述方式使用,我将如何处理这种情况。

在这种情况下,有没有办法加快查询速度?转换为列表似乎没有帮助。

2 个答案:

答案 0 :(得分:14)

在LINQ-SQL中,Contains将转换为SELECT ... WHERE field IN(...)并且应该相对较快。但是,在LINQ对象中,如果源是ICollection<T>.Contains,它将调用ICollection<T>

当LINQ-SQL结果被视为IEnumerable而不是IQueryable时,您将丢失linq提供程序 - 即,任何进一步的操作都将在内存中完成,而不是在数据库中。< / p>

至于为什么内存慢得多:

Array.Contains()是一个O(n)操作,所以

something.Where(s => previousarray.Contains(s.field));

是O(p * s),其中 p 的大小为previousarray s 的大小为something

另一方面,

HashSet<T>.Contains()是O(1)操作。如果您首先创建一个哈希集,您将看到.Contains操作的重大改进,因为它将是O(s)而不是O(p * s)。

示例:

var previousSet = new HashSet<int>(previousarray);
var result = something.Where(s => previousSet.Contains(s.field));

答案 1 :(得分:0)

Lists / Arrays / IEnumarables等上的是O [N]操作。在 HashSet 上为O [~1]。所以你应该尝试使用它。