Some decompiler observations
In both scenarios, a different overload of the System.Data.DataRowCollection.Add method is being used.
The first approach uses:
public void Add(DataRow row)
{
this.table.AddRow(row, -1);
}
The second approach will use:
public DataRow Add(params object[] values)
{
int record = this.table.NewRecordFromArray(values);
DataRow dataRow = this.table.NewRow(record);
this.table.AddRow(dataRow, -1);
return dataRow;
}
Now, take a look at this little beast:
internal int NewRecordFromArray(object[] value)
{
int count = this.columnCollection.Count;
if (count < value.Length)
{
throw ExceptionBuilder.ValueArrayLength();
}
int num = this.recordManager.NewRecordBase();
int result;
try
{
for (int i = 0; i < value.Length; i++)
{
if (value[i] != null)
{
this.columnCollection[i][num] = value[i];
}
else
{
this.columnCollection[i].Init(num);
}
}
for (int j = value.Length; j < count; j++)
{
this.columnCollection[j].Init(num);
}
result = num;
}
catch (Exception e)
{
if (ADP.IsCatchableOrSecurityExceptionType(e))
{
this.FreeRecord(ref num);
}
throw;
}
return result;
}
Especially, note the this.columnCollection[i][num] = value[i];, which will call:
public DataColumn this[int index]
{
get
{
DataColumn result;
try
{
result = (DataColumn)this._list[index];
}
catch (ArgumentOutOfRangeException)
{
throw ExceptionBuilder.ColumnOutOfRange(index);
}
return result;
}
}
Moving forward, we discover that actually _list is an ArrayList:
private readonly ArrayList _list = new ArrayList();
Conclusion
In order to summarize the above, if you are using dtDeptDtl.Rows.Add(); instead of dtDeptDtl.Rows.Add(dr2);, you will get a performance degradation which will increase exponentially, as the number of columns grows. The responsible line for the degradation is call to the NewRecordFromArray method, which iterates over an ArrayList.
Note: This can be easily tested if you add, let's say, 8 columns to the table and make some tests in a for looping 1000000 times.
foreach (var item in arr2){ dtDeptDtl.Rows.Add(item);}