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 theselectcall) - another boundary check when calling
Insert - capacity check (this one also exists in
Add) - position check (since
Insertcan 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)
)
);