加快大量项目的枚举

时间:2016-01-18 09:27:27

标签: c# linq optimization parallel-processing

一些快速背景 - 我编写了一些代码,根据Permutations, Combinations, and Variations using C# Generics

中的优秀(并且似乎是高效的)组合库生成项目组合

如果你用最简单的形式写出我想要做的事情,那就是:

var items = dataService.GetAllItems();

PreFilters.ForEach(filter => items = filter.ApplyFilter(items));

var combinations = from item1 in items
                   from item2 in items
                   from item3 in items
                   from item4 in items
                   select new SpecialContainer(new List<Item>(){item1, item2, item3, item4});
combinations = combinations.Distinct().ToList();

PostFilters.ForEach(filter => combinations = filter.ApplyFilter(combinations));

...其中SpecialContainer可以根据Id中的Item字段计算组合的唯一键(按字面顺序排序Id并连接成{{} 1 {} string}。

虽然4组合的表现并不差(280k项目,实际240ms),但一旦我们达到8组合(896mil,16mins投射),事情就会慢下来。理想情况下我也喜欢做12的组合,但考虑到有一个巨大的项目从4跳到8,从8跳到12可能意味着按顺序计算多年的时间。

我根据其他标准过滤这些组合,这有助于在组合过程之前降低组合的复杂性/数量(事先根据已知标准取消资格),并且在整个列表被列举后如代码示例所示。< / p>

所以我的问题:

  • 我正在使用的组合库将自身公开为Id1:Id2:Id3:Id4,并仅在枚举时生成组合。无论如何,我可以利用IEnumerable<T>处理,同时使用上面显示的AsParallel类枚举和丢弃不相关的,非唯一的组合?
  • 我一直在Filter类内部使用'ToList()'在每个阶段将Filter转换为IEnumerable<T> - 我是否应该将它们保留为List<T>直到最后?

更新

产生问题的实际调用如下:

IEnumerable<T>

上述代码中的var combinator = new Combinations<Item>(items, 8, GenerateOption.WithRepetition); var combinations = combinator.Select(x => new SpecialContainer(x)).ToList(); 是花费时间的调用。

更新2:

昨晚,我确保所有ToList()项都没有在PostFilter实施中调用ToList(),而ApplyFilter调用也没有“纯粹”{{1}在我将它绑定到UI之前,直到最后一次调用。我还在设置流程之前添加了额外的combinations.Distinct()

所以新代码如下:

IEnumerable<T>

这背后的原因是允许编译器潜在地优化生成的AsParallel()操作堆栈。昨天晚上10点我把它踢掉了,虽然工作肯定是在不同的线程上进行的,但整个过程还没有在今天早上6点完成(之前的性能大约是16分钟)。

但是,阅读关于LINQ Performancehow PLINQ can affect performance的其他一些文章,我认为尝试在并行编程模式中优化这一点的下一步是更改我的过滤器以针对返回的单个对象运行一个var combinations = combinator.Select(x => new SpecialContainer(x))); combinations = combinations.Distinct().AsParallel(); PostFilters.ForEach(filter => combinations = filter.ApplyFilter(combinations)); var finalList = combinations.ToList(); ,所以我的代码最终会像:

IEnumerable<T>

0 个答案:

没有答案