title: Extreme performance difference when using DataTable.Add
body: <p>Take a look at the program below. It's pretty self-explanatory, but I'll explain anyway :)</p>
  
  <p>I have two methods, one fast and one slow. These methods do the exact same thing: they create a table with 50,000 rows and 1000 columns. I write to a variable number of columns in the table. In the code below I've picked 10 (<code>NUM_COLS_TO_WRITE_TO</code>).</p>
  
  <p>In other words, only 10 columns out of the 1000 will actually contain data. OK. The <em>only</em> difference between the two methods is that the fast populates the columns and <em>then</em> calls <code>DataTable.AddRow</code>, whereas the slow one does it <em>after</em>. That's it.</p>
  
  <p>The performance difference however is <em>shocking</em> (to me anyway). The fast version is almost completely unaffected by changing the number of columns we write to, whereas the slow one goes up linearly. For example, when the number of columns I write to is 20, the fast version takes 2.8 seconds, but the slow version takes over a <em>minute</em>. </p>
  
  <p>What in the world could possibly be going on here?</p>
  
  <p>I thought that maybe adding <code>dt.BeginLoadData</code> would make a difference, and it did to some extent, it brought the time down from 61 seconds to ~50 seconds, but that's still a <em>huge</em> difference.</p>
  
  <p>Of course, the obvious answer is, "Well, don't do it that way." OK. Sure. But what in world is causing this? Is this expected behavior? I sure didn't expect it. :) </p>
  
  <pre><code>public class Program
  {
      private const int NUM_ROWS = 50000;
      private const int NUM_COLS_TO_WRITE_TO = 10;
      private const int NUM_COLS_TO_CREATE = 1000;
  
      private static void AddRowFast() {
          DataTable dt = new DataTable();            
          //add a table with 1000 columns
          for (int i = 0; i &lt; NUM_COLS_TO_CREATE; i++) {
              dt.Columns.Add("x" + i, typeof(string));
          }
          for (int i = 0; i &lt; NUM_ROWS; i++) {                
              var theRow = dt.NewRow();
              for (int j = 0; j &lt; NUM_COLS_TO_WRITE_TO; j++) {
                  theRow[j] = "whatever";
              }
  
              //add the row *after* populating it
              dt.Rows.Add(theRow);                
          }
      }
  
      private static void AddRowSlow() {
          DataTable dt = new DataTable();
          //add a table with 1000 columns
          for (int i = 0; i &lt; NUM_COLS_TO_CREATE; i++) {
              dt.Columns.Add("x" + i, typeof(string));
          }
          for (int i = 0; i &lt; NUM_ROWS; i++) {
              var theRow = dt.NewRow();
              //add the row *before* populating it
              dt.Rows.Add(theRow);
  
              for (int j=0; j&lt; NUM_COLS_TO_WRITE_TO; j++){
                  theRow[j] = "whatever";
              }                
          }
      }
  
      static void Main(string[] args)
      {
          var sw = Stopwatch.StartNew();
          AddRowFast();
          sw.Stop();
          Console.WriteLine(sw.Elapsed.TotalMilliseconds);
  
          sw.Restart();
          AddRowSlow();
          sw.Stop();
          Console.WriteLine(sw.Elapsed.TotalMilliseconds);
  
          //When NUM_COLS is 5
          //FAST: 2754.6782
          //SLOW: 15794.1378
  
          //When NUM_COLS is 10
          //FAST: 2777.431  ms
          //SLOW 32004.7203 ms
  
          //When NUM_COLS is 20
          //FAST:  2831.1733 ms
          //SLOW: 61246.2243 ms
      }
  }
  </code></pre>
  
  <p><strong>Update</strong></p>
  
  <p>Calling <code>theRow.BeginEdit</code> and <code>theRow.EndEdit</code> in the slow version makes the slow version more or less constant (~4 seconds on my machine). If I actually <em>had</em> some constraints on the table, I guess this might make sense to me.</p>