title: Parallel Operation Batching
body: <p>Is there built-in support in the TPL (Task-Parallel-Library) for batching operations?</p>
  
  <p>I was recently playing with a routine to carry out character replacement on a character array using a lookup table i.e. transliteration:</p>
  
  <pre><code>for (int i = 0; i &lt; chars.Length; i++)
  {
      char replaceChar;
  
      if (lookup.TryGetValue(chars[i], out replaceChar))
      {
          chars[i] = replaceChar;
      }
  }
  </code></pre>
  
  <p>I could see that this could be trivially parallelized, so jumped in with a first stab which I knew would perform worse as the tasks were too fine-grained:</p>
  
  <pre><code>Parallel.For(0, chars.Length, i =&gt;
  {
      char replaceChar;
  
      if (lookup.TryGetValue(chars[i], out replaceChar))
      {
          chars[i] = replaceChar;
      }
  });
  </code></pre>
  
  <p>I then reworked the algorithm to use batching so that the work could be chunked onto different threads in less fine-grained batches. This made use of threads as expected and I got some near linear speed up.</p>
  
  <p>I'm sure that there must be built-in support for batching in the TPL. What is the syntax, and how do I use it?</p>
  
  <pre><code>const int CharBatch = 100;
  int charLen = chars.Length;
  
  Parallel.For(0, ((charLen / CharBatch) + 1), i =&gt;
  {
      int batchUpper = ((i + 1) * CharBatch);
  
      for (int j = i * CharBatch; j &lt; batchUpper &amp;&amp; j &lt; charLen; j++)
      {
          char replaceChar;
  
          if (lookup.TryGetValue(chars[j], out replaceChar))
          {
              chars[j] = replaceChar;
          }
      }
  });
  </code></pre>
  
  <p><strong>Update</strong></p>
  
  <p>After using @Oliver's answer and replacing <code>Parallel.For</code> with a <a href="http://msdn.microsoft.com/en-us/library/dd991604.aspx" rel="noreferrer">Parallel.ForEach and a Partitioner</a> the code is as follows: </p>
  
  <pre><code>const int CharBatch = 100;
  
  Parallel.ForEach(Partitioner.Create(0, chars.Length, CharBatch), range =&gt;
  {
      for (int i = range.Item1; i &lt; range.Item2; i++)
      {
          char replaceChar;
  
          if (lookup.TryGetValue(chars[i], out replaceChar))
          {
              chars[i] = replaceChar;
          }
      }
  });
  </code></pre>