Search code examples
c#linqcsc

Will the compiler optimise a comparison against IEnumerable<T>.Count()?


As a naive tip, you often hear to use IEnumerable.Any() because then the entire enumerable does not necessarily need to be traversed.

I just wrote a little segment of code that tries to see if the Enumerable contains a single item or multiple.

if (reportInfo.OrebodyAndPits.SelectMany(ob => ob.Pits).Count() > 1)
{
    ws.Cells[row, col++].Value = "Pits";
}
else
{
    ws.Cells[row, col++].Value = "Pit";
}

That made me wonder, will the comparison be compiled into a form that is smart enough to return false as soon as it enumerates past the first item?

If not, is there a way to write a linq extension method that would do that?

(Please note, I'm not terribly interested in the performance impact of this piece of code. I'm mainly curious.)


Solution

  • No, it will not. Your code will count all the items in the sequence. This is because LINQ statements are not optimized by the compiler, what you write is what you get.

    An equivelent, more efficient way of checking whether a sequence contains more than 1 item is:

    reportInfo.OrebodyAndPits.SelectMany(ob => ob.Pits).Skip(1).Any();
    

    This will check, after skipping the first item, whether there are any items left.