Is it better to call ToList() or ToArray() in LINQ queries?
I often run into the case where I want to eval a query right where I declare it. This is usually because I need to iterate over it multiple times and it is expensive to compute. For example:
string raw = "..."; var lines = (from l in raw.Split('\n') let ll = l.Trim() where !string.IsNullOrEmpty(ll) select ll).ToList();
This works fine. But if I am not going to modify the result, then I might as well call
ToArray() instead of
I wonder however whether
ToArray() is implemented by first calling
ToList() and is therefore less memory efficient than just calling
Am I crazy? Should I just call
ToArray() – safe and secure in the knowledge that the memory won’t be allocated twice?
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
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).
A couple of people have asked me about the consequence of having the extra unused memory in the
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.
Answered By – JaredPar