質問

TPL (Task-Parallel-Library) にはバッチ操作用のサポートが組み込まれていますか?

私は最近、ルックアップテーブルを使用して文字配列で文字置換を実行するルーチンで遊んでいた。音訳:

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 とパーティショナー コードは次のとおりです。

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top