【发布时间】:2012-12-11 15:44:25
【问题描述】:
我们在使用 LINQ 的一段代码中遇到了轻微的性能问题,它提出了一个关于 LINQ 在查找方面如何工作的问题
我的问题是这样的(请注意,我已经更改了所有代码,因此这是代码的指示性示例,而不是真实场景):
给定
public class Person {
int ID;
string Name;
DateTime Birthday;
int OrganisationID;
}
如果我有一个包含 10 万个 Person 对象的列表,然后是一个日期列表,比如说 1000,我运行以下代码:
var personBirthdays = from Person p in personList
where p.OrganisationID = 123
select p.Birthday;
foreach (DateTime d in dateList)
{
if (personBirthdays.Contains(d))
Console.WriteLine(string.Format("Date: {0} has a Birthday", d.ToShortDateString()));
}
生成的代码将是以下代码的迭代:
100k(需要执行的循环以查找组织 ID 为 123 的用户)
乘以
1000(列表中的日期数量)
乘以
x(当日要检查组织ID 123 的用户数量)
这是很多迭代!
如果我将 personBirthdays 的代码更改为:
List<DateTime> personBirthdays =
(from Person p in personList
where p.OrganisationID = 123
select p.Birthday).ToList();
这应该将 100k 作为倍数删除,并且只执行一次?
所以你会得到 100k + (1000 * x) 而不是 (100k * 1000 * x)。
问题是这似乎太容易了,我确信 LINQ 在某处做了一些聪明的事情,这应该意味着这不会发生。
如果没有人回答,我会进行一些测试并报告。
清晰度更新:
我们不考虑数据库查找,personList 对象是内存中列表对象。这都是 LINQ-to-Objects。
【问题讨论】:
-
@HamletHakobyan 鉴于他提出的问题,没关系。
-
是的。在第一个 sn-p 中,您有
dateList.CountpersonBirthdays的迭代。 -
嘿伙计,通过传递
dateList作为参数,搜索使用EF 生成IN 查询的解决方案,如果您的dateList长度不是很长,这将固有地解决您的问题。跨度> -
@Jani 我们不知道他是否使用 EF。他可能正在对对象进行 linq,或者使用其他提供程序。
-
@Servy ,如果
personList是IQueryable,personBirthdays将被转换为适当的上下文查询,并且在foreach循环中它将是dateList.Count查询数据库而不是 100k 迭代IEnumerable<Person>.
标签: c# linq linq-to-objects