I tried to find out if setting the list throughput in the constructor can smooth out the already insignificant performance differences between using List<T>(IEnumerable<T>)vs List<T>()+ AddRange(IEnumerable<T>).
I found that setting the capacity before AddRange()actually leads to about the same performance of building a list with the original collection.
But there is more. What if you use Add()instead AddRange()? For some reason, performance improves by 32% .
So what if I use Add()without initializing a list constructor with initial capacity? It seems that the performance is worse than the previous Add () approach, but still better than that AddRange(): a 26% increase in performance.
It is rather strange for me to wonder if my test was valid; therefore, I am sending the tests that I have done (it runs in release mode without a debugger).
Can anyone confirm this?
int items = 100000;
int cycles = 10000;
var collectionToCopy = Enumerable.Range( 0, items );
var sw0 = new Stopwatch();
sw0.Start();
for( int i = 0; i < cycles; i++ )
{
List<int> list = new List<int>( collectionToCopy );
}
sw0.Stop();
Console.WriteLine( sw0.ElapsedMilliseconds );
var sw1 = new Stopwatch();
sw1.Start();
for( int i = 0; i < cycles; i++ )
{
List<int> list = new List<int>( items );
list.AddRange( collectionToCopy );
}
sw1.Stop();
Console.WriteLine( sw1.ElapsedMilliseconds );
var sw4 = new Stopwatch();
sw4.Start();
for( int i = 0; i < cycles; i++ )
{
List<int> list = new List<int>();
list.AddRange( collectionToCopy );
}
sw4.Stop();
Console.WriteLine( sw4.ElapsedMilliseconds );
var sw2 = new Stopwatch();
sw2.Start();
for( int i = 0; i < cycles; i++ )
{
List<int> list = new List<int>( items );
foreach( var item in collectionToCopy )
list.Add( item );
}
sw2.Stop();
Console.WriteLine( sw2.ElapsedMilliseconds );
var sw3 = new Stopwatch();
sw3.Start();
for( int i = 0; i < cycles; i++ )
{
List<int> list = new List<int>();
foreach( var item in collectionToCopy )
list.Add( item );
}
sw3.Stop();
Console.WriteLine( sw3.ElapsedMilliseconds );
Results:
13400 - constructor initialized by collection
13423 - constructor initialized with capacity + AddRange (collection)
14857 - parameterless constructor + AddRange (collection)
9003 - constructor initialized by capacity + Add (element)
9841 - constructor without parameters + Add (element)