Back in the days, I was always told to use AddRange
whenever possible because of the performance gain over Add
. Today, I wanted to validate this statement prior to using it with the output of a List<T>.Select(x => ...)
call but from the decompiled code of List<T>
, I am under the impression the foreach {add}
loop should be faster.
The main reasons I see are the numerous additional checks that are done in the process since it is not an ICollection
- null-check on the new items collection
- boundary check on the index (since AddRange is in fact a call to InsertRange with index
_size
- try type cast to
ICollection
- type check to know if it is an
ICollection
(which it isn't after theselect
call) - another boundary check when calling
Insert
- capacity check (this one also exists in
Add
) - position check (since
Insert
can also put data prior or within the actual list)
Has anyone ever done reliable benchmarking on this?
Edit: Added Code samples of the two options
var clientsConfirmations = new List<ClientConfirmation>();
foreach (var client in Clients)
{
var clientConf = new ClientConfirmation(client.Id, client.Name,
client.HasFlag ?? false);
clientsConfirmations.Add(clientConf);
}
Versus
var clientsConfirmations = new List<ClientConfirmation>();
clientsConfirmations.AddRange(
Clients.Select(client =>
new ClientConfirmation(client.Id, client.Name, client.HasFlag ?? false)
)
);