如何从IEnumerable范围选取均等块用于Parallel For循环并分块数值范围?
针对你的两个技术问题,我给你一套简洁的解决方案:
1. 按处理器数量划分Double数值范围为起始/结束元组列表
核心思路是根据处理器数量动态计算每个块的步长,用LINQ一行代码生成元组列表,完全不需要提前确定元组数量:
假设你已经有了总范围的起始值totalStart和结束值totalEnd,直接这样写:
using System; using System.Collections.Generic; using System.Linq; // 定义总范围 double totalStart = 0.0; double totalEnd = 100.0; int chunkCount = Environment.ProcessorCount; // 自动获取处理器数量 // 生成块的起始/结束元组列表 var rangeChunks = Enumerable.Range(0, chunkCount) .Select(i => Tuple.Create( totalStart + i * (totalEnd - totalStart) / chunkCount, // 最后一块直接用总结束值,避免浮点数精度误差 i == chunkCount - 1 ? totalEnd : totalStart + (i + 1) * (totalEnd - totalStart) / chunkCount )) .ToList();
这段代码的优势:
- 完全动态:chunkCount由
Environment.ProcessorCount自动获取,不需要硬编码 - 处理精度:最后一块直接绑定
totalEnd,避免因为浮点数累加导致的末尾偏差 - 代码极简:用LINQ链式调用完成,不需要额外循环
2. 给Parallel For循环划分IEnumerable的均等块
如果是要把元素集合(而非数值范围)划分成块给Parallel For用,同样可以用LINQ快速实现,同时处理元素总数不能被处理器数量整除的情况:
方法一:直接生成索引范围块(适合Parallel.For)
如果你的集合是可索引的(比如List
var items = new List<double> { /* 你的元素列表 */ }; int totalItems = items.Count; int chunkSize = (int)Math.Ceiling((double)totalItems / Environment.ProcessorCount); Parallel.For(0, Environment.ProcessorCount, chunkIndex => { int startIndex = chunkIndex * chunkSize; int endIndex = Math.Min(startIndex + chunkSize, totalItems); // 处理当前块的元素 for (int i = startIndex; i < endIndex; i++) { var item = items[i]; // 你的业务逻辑 } });
方法二:扩展方法拆分元素块(适合Parallel.ForEach)
如果要把IEnumerable
public static class EnumerableExtensions { public static IEnumerable<IEnumerable<T>> SplitIntoChunks<T>(this IEnumerable<T> source, int chunkCount) { var sourceList = source.ToList(); int itemsPerChunk = (int)Math.Ceiling((double)sourceList.Count / chunkCount); return sourceList.Select((item, index) => new { Item = item, Index = index }) .GroupBy(x => x.Index / itemsPerChunk) .Select(group => group.Select(x => x.Item)); } } // 使用方式 var itemChunks = items.SplitIntoChunks(Environment.ProcessorCount); Parallel.ForEach(itemChunks, chunk => { foreach (var item in chunk) { // 你的业务逻辑 } });
这样不管集合元素总数是否能被处理器数量整除,最后一块都会自动包含剩余的元素,保证所有元素都被处理到。
内容的提问来源于stack exchange,提问作者JacobIRR
相关产品推荐
相关产品推荐

