.net - .NET 中的 Parallel.ForEach 和有条件的正常循环
问题描述
以下是否会在 5 处对 500 个项目进行并行处理,但对 1 个项目进行正常循环(没有性能影响)。我不希望在一次执行 1 项时使用 Parallel(如果有的话)对性能造成影响。
Parallel.ForEach(scheduledMatchups, new ParallelOptions
{
MaxDegreeOfParallelism = scheduledMatchups.Count() > 500 ? 5 : 1
},
gridItem =>
{
// Process
});
解决方案
您可以重构动作和循环序列以具有两个不同的执行路径,同时仍然只定义要执行一次的动作:
Action<GridItems> action = (gridItem) =>
{
// Process
};
if (scheduledMatchups.Count < 500)
{
scheduledMatchups.ForEach(action);
// or for more control, you could iterate yourself
// with a for or foreach and call the action() manually.
//
// foreach(var gridItem in scheduledMatchups) action(gridItem);
}
else
{
Parallel.ForEach(scheduledMatchups, new ParallelOptions
{
MaxDegreeOfParallelism = 5
}, action);
}
这个关于 SO 的答案提供了一些关于内部发生了什么的见解Parallel.ForEach
,如果您最终控制了性能和实现,那么这个简单的分支逻辑仍然只以可重用的方式定义一次操作。
虽然从技术上讲存在开销,但如果您通常期望满足并行条件,那么开销通常不足以证明这种类型的工作只是为了它。
正如@Keith 在下面的评论中指出的那样,Parallel.ForEach
它不会,也不是旨在为“迭代次数有限的小循环体”提供性能改进。这在这篇关于并发和并行编程的文章中有所介绍。
如果你的动作足够轻,那么即使有很多次迭代,你最好不要并行处理。
我发现它通常是一个更好的练习,Parallel.ForEach
只有当你可以证明你正在执行的动作类型是合理的时候才使用它。如果操作本身需要一些可观察到的时间来处理,那么对于有限数量的操作,开销很可能是合理的。
与所有此类问题一样,您的情况的真正答案将始终取决于比此处实际记录的更多因素,因此您应该尝试两种代码样式,并自行确定任何一种方式的影响是否明显或可接受。
如果您以一种或另一种方式观察问题,请发布有关具体观察的信息。在并行与否之间进行选择时,您应该小心过度或过早优化最终使您的代码更难阅读或维护但对实际运行时几乎没有改进的过程。
推荐阅读
- java - 这是一种策略模式还是只是一个回调?
- apache - Stormcrawler:注入新的 URL 进行爬取,无需重启拓扑
- sdn - SDN架构理解
- jquery - 如何使用引导选择重建下拉菜单?
- python - 该操作未在 ibm watson 中返回有效字典
- go - 将地图值转换为不带括号的纯字符串?
- kubernetes - 在一个 kubernetes 集群中运行多个应用程序或每个应用程序在一个集群中运行
- ios - 如何在 iOS 11+ 中以编程方式打开设置 > 隐私 > 定位服务?
- java - SimpleAdapter 在 while 循环中显示相同的数据
- css - React 不导入全局 css;本地比较好