并行操作批处理

8

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.For替换为Parallel.ForEach和Partitioner后,代码如下:

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;
        }
    }
});
1个回答

20

谢谢提供链接,但你有没有对我的问题有具体的答案? - Tim Lloyd
太棒了,谢谢。完美地运作了,API也非常好 :) 我已经根据你的答案更新了我的问题,并提供了一个例子。 - Tim Lloyd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接