【发布时间】:2016-01-29 18:51:14
【问题描述】:
我需要将大量复杂(20 多个属性)对象过滤到多个子列表中。要创建子列表,我有一个过滤器规范列表。要求是:a) 一个项目不允许成为两个子列表的一部分,并且 b) 必须能够在处理完成后获取所有未划分的项目。
目前我使用以下算法:
- 列表项
- 将要过滤的对象放入通用列表中
- 对于每个过滤器规格:
- 创建 Where 表达式 (Expression>)
- 使用 Linq > Where 将表达式应用于对象列表
- 获取选定对象的结果 IEnumerable 并将它们与过滤器的描述一起存储在列表中
- 使用 Linq 从源列表中删除找到的项目 > 除了创建一个新列表以继续使用并防止将对象放入多个子列表中
- 检查工作列表中是否还有(未分割的)对象
我的初始对象列表可能超过 400.000 个对象,我注意到过滤和减少工作列表都需要一些时间。所以我想知道:
- 创建子列表的过滤发生在我的对象的最多 7 个属性上。有没有办法提高 Linq > Where 选择的性能?
- 有没有办法防止项目被选择到多个子列表中,而不会通过使用 except 或 RemoveAll 减少工作集合(可能的改进)?
提前致谢!
【问题讨论】:
-
这完全取决于对象列表是否按某些过滤属性排序或索引。如果不是,那么仅手动遍历列表一次 (
foreach) 并使用if elseif else语句按顺序对项目进行分类可能会快得多。 -
如何在 Linq 可以使用的对象集合上创建索引?此外,现实生活中的情况比我上面的描述更复杂。在现实生活中,不仅有一个过滤器描述列表,还有一个类别的树结构,每个类别都有自己的过滤器规范和(最终)符合过滤器规范的对象的子列表。跨度>
-
这就是我的意思。如果列表没有以任何方式索引,那么使用 Linq 的
Where扩展方法基本上无论如何都会迭代整个序列。在这种情况下,您最好只迭代一次,并在进行过程中对每个项目进行分类,从而避免昂贵的 remove 和 except 操作一起 -
对它们进行分类将是一个挑战,因为过滤器不仅包含相等测试,还包含大于、小于等测试,并且属性值不限于两个或三个值,理论上会产生比我必须过滤的对象数量更多的独特组合。
-
我不理解你。您有一个有效的算法,但您想提高性能。如果它有效,那么您就有办法在
Where子句中构建所有谓词。是什么阻止您手动执行此操作?请看下面我的回答。也许我在这里误解了一些东西。
标签: c# performance linq list large-data-volumes