Why is LastOrDefault(predicate) in LINQ faster than FirstOrDefault(predicate)
steve16351 pointed out in a deleted comment that, in .NET Core, Last
has the following optimization:
if (source is IList<TSource> list)
{
for (int i = list.Count - 1; i >= 0; --i)
{
TSource result = list[i];
if (predicate(result))
{
found = true;
return result;
}
}
}
but First
does not and ends up running:
foreach (TSource element in source)
{
if (predicate(element))
{
found = true;
return element;
}
}
It is quite possible that the accessing of the list elements by indexer is faster than using a foreach
and iterator. By contrast, .NET Standard does not have this optimization for Last
, instead iterating through the complete input, and Last
runs more slowly than First
as you would expect.