To answer your question objectively, LINQ makes heavy use of delegates and iterators, which has the overhead of instantiations (delegates and iterators) and method calls (delegate invocation and MoveNext()
on iterators). Now, a foreach
(on a List<T>
) will have the overhead of the iterator, but not the overhead of delegates. So it's expected that LINQ will be slower here than a foreach
.
Likewise, iterating through the list using the [i]
indexer is expected to be faster still because it also doesn't have the overhead of the iterator. Even faster is not using a List<T>
but an array. But even that has the overhead of array bounds checks (the bit that throws an IndexOutOfRangeException
if you try to go outside array bounds) and that can be avoided by using raw memory access through pointers, or by simply iterating the entire list (for(var i = 0; i < array.Length; i++) { Console.WriteLine(array[i]); }
won't have bounds checks because the compiler can prove this loop will never go out of bounds).
Those are the varying degrees of overhead that the various ways of iteration bring with them. Do those overheads matter? If you're doing 10,000 x 10,000 matrix multiplication, then yes. Otherwise, probably not unless you've measured it to be (which is a tired old answer, but no less valid).
However, aside from those facts it also matters how you use them. Say you want a list of customers who were born after 1980 from a larger pile of customers and do further processing on them. Without LINQ, you be would pretty much forced to foreach
the original customer list and create an intermediate list that you put the customers who were born after 1980 into. With LINQ, you won't need the intermediate list which saves quite a lot of overhead (creating the list, calling Add
on it, resizing it several times most likely as it grows) and is likely to be faster. And it's certainly more memory efficient, as the customers born after 1980 are 'streamed' in one by one without the intermediate list taking up memory. With LINQ, you can potentially process an infinitely long sequence.
Another performance reason to use LINQ is that parallelization of certain operations becomes trivial with the AsParallel()
call at the end of a query.
So to answer your question if there's a performance disadvantage to using LINQ:
It depends.