【发布时间】:2017-08-09 04:43:50
【问题描述】:
我有两个查询,都产生相同的结果,但我想知道哪个更有效。下面是查询,我只写了查询子句。两个查询的内部条件相同。
- IQueryable().Where().ToList();
- IQueryable().ToList().Where();
最后我尝试了下面的代码,它显示“IQueryable().ToList().Where();”更好。有几个问题我不明白: 1.没有看到我下面的临时代码,哪个查询更有效? 2. 据我所知,IQueryable 非常适合查询远程数据。那么,首先过滤掉项目然后使用 ToList 以便我们不需要对不相关的项目执行 ToList 功能不是更好吗? (如果是这种情况,为什么下面的代码说查询 2 更有效?)
Stopwatch st1 = new Stopwatch();
Stopwatch st2 = new Stopwatch();
int counter = 10000;
IEnumerable<Employee> iEmp = null;
IQueryable<Employee> qEmp = null;
BindingList<Employee> bList = new BindingList<Employee>();
for (int i = 1; i <= counter; ++i)
{
bList.Add(new Employee
{
Department = $"Dept - {i}",
EmployeeID = i,
EmployeeName = $"Employee - {i}",
Salary = i + 10000
});
}
iEmp = bList.AsEnumerable<Employee>();
qEmp = bList.AsQueryable<Employee>();
st1.Start();
var t = qEmp.Where(x => x.EmployeeID % 2 == 0).ToList();
st1.Stop();
Console.WriteLine($"Queryable-Where-ToList: {st1.ElapsedTicks}");
st2.Start();
var t1 = qEmp.ToList().Where(x => x.EmployeeID % 2 == 0);
st2.Stop();
Console.WriteLine($"Queryable-ToList-Where: {st2.ElapsedTicks}");
Console.ReadKey();
【问题讨论】:
-
@DavidG 我不知道你有没有看代码,但他已经在用秒表自己看。
-
ToList在内存中创建一个列表并填充它。如果你之后使用Where,你就无缘无故地创建了这个列表。因为它不再被引用,所以它已准备好被垃圾收集。所以总是使用Where(...).ToList()(如果你需要一个列表)。如果你想强制使用Linq-To-Objects,你应该使用AsEnumerable而不是ToList。 -
所以
IQueryable基于Expression<T>并用于数据库(一般来说)。那么,您是否在问是否编译 where 表达式并执行它是否比要求返回所有项目并在内存中应用 where 更快?因为这两件事不能等同 -
@sunil20000 如果您想知道代码在使用 EF 时的行为,请使用 EF 进行测试。
标签: c# performance linq iqueryable