Is it better to call ToList() or ToArray() in LINQ queries?
The performance difference will be insignificant, since List<T>
is implemented as a dynamically sized array. Calling either ToArray()
(which uses an internal Buffer<T>
class to grow the array) or ToList()
(which calls the List<T>(IEnumerable<T>)
constructor) will end up being a matter of putting them into an array and growing the array until it fits them all.
If you desire concrete confirmation of this fact, check out the implementation of the methods in question in Reflector -- you'll see they boil down to almost identical code.
Unless you simply need an array to meet other constraints you should use ToList
. In the majority of scenarios ToArray
will allocate more memory than ToList
.
Both use arrays for storage, but ToList
has a more flexible constraint. It needs the array to be at least as large as the number of elements in the collection. If the array is larger, that is not a problem. However ToArray
needs the array to be sized exactly to the number of elements.
To meet this constraint ToArray
often does one more allocation than ToList
. Once it has an array that is big enough it allocates an array which is exactly the correct size and copies the elements back into that array. The only time it can avoid this is when the grow algorithm for the array just happens to coincide with the number of elements needing to be stored (definitely in the minority).
EDIT
A couple of people have asked me about the consequence of having the extra unused memory in the List<T>
value.
This is a valid concern. If the created collection is long lived, is never modified after being created and has a high chance of landing in the Gen2 heap then you may be better off taking the extra allocation of ToArray
up front.
In general though I find this to be the rarer case. It's much more common to see a lot of ToArray
calls which are immediately passed to other short lived uses of memory in which case ToList
is demonstrably better.
The key here is to profile, profile and then profile some more.