IQueryable.Where.ToList VS IQueryable.ToList.Where,哪个查询在性能方面更好?

sun*_*000 1 c# linq performance iqueryable

我有两个查询,两个查询都产生相同的结果,但我想知道哪一个更有效。下面是查询,我只写了查询子句。两个查询的内部条件相同。

  1. IQueryable().Where().ToList();
  2. 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();
Run Code Online (Sandbox Code Playgroud)

Dan*_*ite 5

你应该使用IQueryable.Where.ToList. 这样,过滤将在查询的上下文中进行,而不是像以前那样先收集结果并过滤内存中的所有结果IQueryable.ToList.Where

在您的示例中BindingList,它不会那么重要,但在使用Entity Framework之类的东西时确实很重要。

在 EF 的情况下,给定

Id | Name
1  | Daniel
2  | Miranda
3  | Elianna
Run Code Online (Sandbox Code Playgroud)

这样做.ToList会首先返回所有 3 条记录。Where然后对内存中的这些对象进行操作。

 var list = query.ToList();
 list.Count == 3; // true
 list.Where(i => i.Id % 2 == 0); // Returns only Miranda
Run Code Online (Sandbox Code Playgroud)

然而,对于.Where第一个,它将其转换为 SQL(此处为伪 SQL),然后收集结果。

SELECT * FROM Table WHERE Id % 2 = 0
Run Code Online (Sandbox Code Playgroud)

在 C# 中:

 var list = query.Where(i => i.Id % 2 == 0).ToList();
 list.Count == 1; // true, only Miranda
Run Code Online (Sandbox Code Playgroud)

在为什么 2 更快的情况下,你的测试是有缺陷的。这些测试并不是孤立运行的。它们在短时间内对相同的数据进行操作,这可能会导致 CPU/运行时/操作系统为您优化某些内容。