C # – Why is AddRange faster than using the Foreach?

var fillData = new List();
for (var i = 0; i <100000; i++)
{
fillData.Add(i);
}

var stopwatch1 = new Stopwatch();
stopwatch1.Start();
var autoFill = new List();
autoFill.AddRange(fillData);
stopwatch1.Stop();

var stopwatch2 = new Stopwatch();
stopwatch2.Start() ;
var manualFill = new List();
foreach (var i in fillData)
{
manualFill.Add(i);
}
stopwatch2.Stop();

When I get 4 results from stopwach1 and stopwach2, the value of stopwatch1 is always lower than stopwatch2. This means that addrange is always faster than foreach.
Yes Who knows why?

Potentially, AddRange can check where the value passed to it implements IList or IList< T >. If so, it can find out how many values ​​are in the range and therefore how much space needs to be allocated… and the foreach loop may need to be re-allocated several times.

In addition, even after the allocation ,List can use IList.CopyTo to perform batch copy to the underlying array (of course, for the scope of implementing IList).

I doubt you You will find that if you try the test again, but use Enumerable.Range(0,100000) to represent fillData instead of List, then both will take about the same time.

var fillData = new List();
for (var i = 0; i <100000; i++)
{
fillData.Add(i) ;
}

var stopwatch1 = new Stopwatch();
stopwatch1.Start();
var autoFill = new List();
autoFill.AddRange(fillData);
stopwatch1.Stop();

var stopwatch2 = new Stopwatch();
stopwatch2.Start();
var manualFill = new List();
foreach (var i in fillData)
{
manualFill.Add(i);
}
stopwatch2.Stop() ;

When I get 4 results from stopwach1 and stopwach2, the value of stopwatch1 is always lower than stopwatch2. This means that addrange is always faster than foreach.
Does anyone know why?

Potentially, AddRange can check where the value passed to it implements IList or IList. If so, it can find out the range How many values ​​are there, and therefore how much space needs to be allocated… and the foreach loop may need to be re-allocated several times.

In addition, even after the allocation, List< T> can use IList< T>.CopyTo to perform batch copying to the underlying array (of course, for the range that implements IList).

I doubt you will find out if you try to test again, but use Enumerable .Range(0,100000) to represent fillData instead of List, then the two will take about the same time.

Leave a Comment

Your email address will not be published.