我最初有一个方法,其中包含一个返回int[]
的LINQ查询,然后以类似于以下的方式使用它:
int[] result = something.Where(s => previousarray.Contains(s.field));
在第一个数组被检索为本地IQueryable<int>
之前,结果非常缓慢。它现在运行得非常快,但是我想知道如果我从其他地方提供int[]
然后必须按上述方式使用,我将如何处理这种情况。
在这种情况下,有没有办法加快查询速度?转换为列表似乎没有帮助。
答案 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]。所以你应该尝试使用它。