title: C# tasks(with or without TaskContinuationOptions.ExecuteSynchronously) performance vs thread loop , .net threading is worse?
body: <p>i was thinking about the best technique of work when processing queue of actions (the order of operation was important so every operation must come after it's previous one)</p>
  
  <p>i'm pretty disappointed from the performance results of running a Task with continuation options that suppose to run on the same thread (i was expecting to have similar results as thread running in a loop).... i would appreciate any comments about these performance results, btw - it appears that maybe JIT have improved performance so that running without any threading in some cases is better than with threading, in my example below u can see that the working on array size of 450K items was faster in main thread than other thread running a loop</p>
  
  <hr>
  
  <h2><strong>The methods that were considered:</strong></h2>
  
  <ul>
  <li><strong>running in simple for loop</strong> on each action (sequential approach)</li>
  <li><strong>running a Task.ContinueWith method</strong>. this method is being executed on a thread pool thread and each other action is being also performed after it's previous (thread pool decide on which thread it runs on).</li>
  <li><strong>running a Task.ContinueWith method with TaskContinuationOptions</strong> set to TaskContinuationOptions.ExecuteSynchronously, this is causing all the tasks to be performed on the same thread</li>
  <li><strong>runing on a seperated thread</strong> - new System.Threading.Thread working with for loop on the action</li>
  </ul>
  
  <hr>
  
  <h2><strong>Method Code:</strong></h2>
  
  <p>I've created simple tester application that runs on and array and sets arr[i] = i * i
  where i is: 100,000 to 450,000 (jumps of 50,000 between each test)</p>
  
  <h2><strong>Results:</strong></h2>
  
  <blockquote>
    <p>------------------------- Running test with 100000 items &amp; iterations---------------------------</p>
    
    <p>Simple for results :<strong>24.0013 MS</strong></p>
    
    <p>Task.ContinueWith() result :<strong>691.0395 MS</strong></p>
    
    <p>Task.ContinueWith(TaskContinuationOptions.ExecuteSynchronously) result :<strong>91.0052 MS</strong></p>
    
    <p>Thread.Start result : <strong>16.0009 MS</strong></p>
    
    <p><em>{skip...skip...skip - this is too long...}</em></p>
    
    <p>------------------------- Running test with 450000 items &amp; iterations---------------------------</p>
    
    <p>Simple for results :<strong>16.0009 MS</strong></p>
    
    <p>Task.ContinueWith() result : <strong>3686.2108 MS</strong></p>
    
    <p>Task.ContinueWith(TaskContinuationOptions.ExecuteSynchronously) result:<strong>415.0238 MS</strong></p>
    
    <p>Thread.Start result : <strong>35.002 MS</strong></p>
    
    <p>Press any key to exit</p>
  </blockquote>
  
  <h2><strong>Source Code</strong></h2>
  
  <pre><code>static int max = 100000;
      static int[] array;
      static DateTime start;
      static int valueOfMax = 0;
      static void Main(string[] args)
      {
  
          for (valueOfMax = max; valueOfMax &lt; max * 5; valueOfMax += (max/2))
          {
              Console.WriteLine(string.Format("------------------------- Running test with {0} items &amp; iterations---------------------------", valueOfMax));
              array = new int[valueOfMax];
              start = DateTime.Now;
              Console.Write("Simple for results :                                                                 ");
              for (int i = 0; i &lt; valueOfMax; i++)
              {
                  doSomething(i);
              }
  
              start = DateTime.Now;
              Action&lt;int&gt; action = doSomething;
              Task lastTask = Task.Factory.StartNew(() =&gt; { int p = 4; });
              Console.Write("Task.ContinueWith() result :                                                         ");
              for (int i = 0; i &lt; valueOfMax; i++)
              {
                  var valueOfI = i;
                  lastTask = lastTask.ContinueWith((task) =&gt; doSomething(valueOfI));
              }
              lastTask.Wait();
  
              start = DateTime.Now;
              lastTask = Task.Factory.StartNew(() =&gt; { int p = 4; });
              Console.Write("Task.ContinueWith(TaskContinuationOptions.ExecuteSynchronously) result :             ");
              for (int i = 0; i &lt; valueOfMax; i++)
              {
                  var valueOfI = i;
                  lastTask = lastTask.ContinueWith((task) =&gt; doSomething(valueOfI), TaskContinuationOptions.ExecuteSynchronously);
              }
              lastTask.Wait();
  
              start = DateTime.Now;
              Thread t = new Thread(delegate()
              {
                  for (int i = 0; i &lt; valueOfMax; i++)
                  {
                      doSomething(i);
                  }
              });
              Console.Write("Thread.Start result :                                                                ");
              t.Start();
              t.Join();
          }
  
          Console.WriteLine("Press any key to exit");
          Console.ReadKey();
      }
  
      static void doSomething(int i)
      {
          array[i] = i * i;
  
          if ((i+1) == valueOfMax)
          {
              DateTime end = DateTime.Now;
              var diff = end - start;
              Console.WriteLine(string.Format("{0} MS", diff.TotalMilliseconds));
          }
      }
  </code></pre>