Why You Shouldn't Use ToArray or ToList

added by KodefuGuru
8/9/2012 5:50:35 PM

8 Kicks, 1012 Views

The IEnumerable(T) extension methods ToList and ToArray are commonly used at boundaries to prevent a potential performance impact from consumers iterating a sequence more than once. This is due to the lazy evaluation strategy used by the LINQ extension methods to IEnumerable(T) which provides better performance as you are constructing your query since each modification to the query is not forcing the sequence to be iterated. However, are these two methods used correctly?


4 comments

dpeterson
8/9/2012 5:48:38 PM
So if the problem is that ToList *may* cause lazy evaluation, then I think the solution would be to use ToList as close to when you actually need the list as possible, or am I misunderstanding? Thanks for the post, I never thought about the implications of not knowing when ToList would be evaluated.

KodefuGuru
8/9/2012 6:16:00 PM
We *know* that ToList will create a stateful list with eager evaluation. We assume that it will always be this way, and although this is likely to be true, it is still an assumption. I claim the method you use should depend on your intent: if you intend to retrieve an instance of List(T), use ToList(); if you intend to materialize the sequence (causing the sequence to be evaluated), use a Materialize

My argument is as follows :

Assuming your intent is to materialize a sequence and you are using ToList for the implication that the sequence will be materialized.

Using a Materialize method instead:
1) makes your intent clear
2) prevents misinterpretation due to other implications
3) provides one location to change the implementation details for materializing a sequence

Please note this is different than a Memoize function, which isn't as eager. Memoize would cache the results upon evaluation so subsequent traversal will not cause evaluation.

dpeterson
8/9/2012 6:22:17 PM
Ah ok, I wasn't sure if you meant that what ToList would actually perform was unclear, or just the developers intention when seeing it in the code. Thanks for the follow up.

KodefuGuru
8/13/2012 4:59:45 PM
I dig a little deeper into it here and introduce memoization: http://www.kodefuguru.com/post/2012/08/13/Caching-LINQ-Results.aspx