并行操作批处理

在TPL(任务 – 并行 – 库)中是否有内置支持用于批处理操作?

我最近玩了一个例程,使用查找表即音译在字符数组上进行字符替换:

for (int i = 0; i < chars.Length; i++) { char replaceChar; if (lookup.TryGetValue(chars[i], out replaceChar)) { chars[i] = replaceChar; } } 

我可以看到,这可能是平凡的并行化,所以跳入第一个刺,我知道会因为任务太细粒度而表现更差:

 Parallel.For(0, chars.Length, i => { char replaceChar; if (lookup.TryGetValue(chars[i], out replaceChar)) { chars[i] = replaceChar; } }); 

然后我重新编写算法以使用批处理,以便可以将工作分块到不太细粒度的批处理中的不同线程上。 这样就可以按预期使用线程,并且接近线性加速。

我确信必须内置支持TPL中的批处理。 什么是语法,我该如何使用它?

 const int CharBatch = 100; int charLen = chars.Length; Parallel.For(0, ((charLen / CharBatch) + 1), i => { int batchUpper = ((i + 1) * CharBatch); for (int j = i * CharBatch; j < batchUpper && j < charLen; j++) { char replaceChar; if (lookup.TryGetValue(chars[j], out replaceChar)) { chars[j] = replaceChar; } } }); 

更新

使用@Oliver的答案并用Parallel.ForEach和Partitioner替换Parallel.For ,代码如下:

 const int CharBatch = 100; Parallel.ForEach(Partitioner.Create(0, chars.Length, CharBatch), range => { for (int i = range.Item1; i < range.Item2; i++) { char replaceChar; if (lookup.TryGetValue(chars[i], out replaceChar)) { chars[i] = replaceChar; } } }); 

为了更好地了解您应该获得并行编程模式:了解和应用.NET Framework 4并行模式 。 它是一个很好的资源,并解释了如何使用TPL的常用方法。

看一下第26页(非常小的循环体)。 在那里你会找到这个例子:

 Parallel.ForEach(Partitioner.Create(from, to), range => { for (int i = range.Item1; i < range.Item2; i++) { // ... process i } }); 

因此,您正在搜索的缺失部分是System.Concurrent.Collections.Partitioner