C# 为什么分页的LINQ IQueryable性能如此差? List deviceList=GetDevices();//这些已作为列表加载到内存中 IQueryable IDevices=deviceList.AsQueryable(); deviceList=IDevices.Where(i=>i.StatusID==2).OrderBy(j=>j.lastCommunicationed).Skip(recordsToSkip).Take(pageSize).ToList();

C# 为什么分页的LINQ IQueryable性能如此差? List deviceList=GetDevices();//这些已作为列表加载到内存中 IQueryable IDevices=deviceList.AsQueryable(); deviceList=IDevices.Where(i=>i.StatusID==2).OrderBy(j=>j.lastCommunicationed).Skip(recordsToSkip).Take(pageSize).ToList();,c#,performance,linq,iqueryable,C#,Performance,Linq,Iqueryable,根据上面的代码,我在列表中有大约1000台设备被查询。第三个语句非常慢。如果它已经加载到内存中,不是应该很快吗?我知道在大多数情况下,您会将整个查询应用于数据库调用,但在我的情况下,我已经在内存中加载了设备。第一次和第二次通话非常快 IQueryable在这一点上是不相关的。您看到的性能问题是每个链返回一个新的迭代器 那么这个, List<Device> deviceList = GetDevices(); // these are loaded in memory already

根据上面的代码,我在列表中有大约1000台设备被查询。第三个语句非常慢。如果它已经加载到内存中,不是应该很快吗?我知道在大多数情况下,您会将整个查询应用于数据库调用,但在我的情况下,我已经在内存中加载了设备。第一次和第二次通话非常快

IQueryable
在这一点上是不相关的。您看到的性能问题是每个链返回一个新的迭代器

那么这个,

List<Device> deviceList = GetDevices(); // these are loaded in memory already as a list

IQueryable<Device> IDevices = deviceList.AsQueryable<Device>();

deviceList = IDevices.Where(i => i.StatusID == 2).OrderBy(j => j.LastCommunicated).Skip(recordsToSkip).Take(pageSize).ToList();
这是一个循序渐进的过程。首先,
其中执行
。这将迭代整个列表。然后,
OrderBy
执行,正如您所想象的,这是相当密集的<代码>跳过然后迭代,直到找到您想要的索引<代码>获取然后在形成新列表之前迭代n个项目


尽管如此。。如果您直接对数据库运行此查询,它会快得多。

您所说的“非常慢”到底是什么意思?你能把你的尺寸贴出来吗?更好的是,你能发布分析代码的结果吗?这个调用不应该“非常慢”。而不是只有1000个项目在这个列表中。StatusID或LastID是CPU密集型的吗?返回4个迭代器本身不应该是问题。Take和skip(根据我的直觉和汇编知识)是非常快速的操作。@Dave,请不要将您的问题改写为“我现在明白了”。这将帮助0个未来用户。我明白了。我想,既然数据已经在内存中,我就能够快速排序。“每个链返回一个新列表”-这是不正确的-每个链返回一个新的迭代器。@DStanley表示歉意。如果您已经有内存中的整表,那么您可能应该考虑再次从DB中获取数据。Ofc。如果是与数据库相关的情况。@Dave您将永远无法编写与具有各种索引功能的数据库的速度相匹配的代码(除非您自己实现)。在内存集合中使用LINQ时尤其如此。
IDevices
    .Where(i => i.StatusID == 2) // iterates over 1000 items
    .OrderBy(j => j.LastCommunicated) // orders however many items have a StatusID of 2
    .Skip(recordsToSkip) // iterates "recordsToSkip" number of times
    .Take(pageSize) // iterates "pageSize" times