A lot of the developers I work with feel more comfortable working with a List
as opposed to IEnumerable
(for example). I am wondering whether there is any performance impact for ToList()
overuse. For example, or, will use ToList()
after ordering to get a list back out again i.e.
private void ListThinger(List<T> input)
{
input = input.OrderBy(s => s.Thing).ToList();
foreach(var thing in input)
{
// do things
}
}
My question is:
ToList()
method? Will it create a new list and how much memory does that take, assuming the contents are POCOs? Does this change if its a value type rather than a POCO?ToList()
?IEnumerable
and then ToList()
is called on it, will it just return the original object?P.s. I understand that a single use of ToList won't break any backs, but we are building a highly concurrent system that is currently CPU bound so I am looking for little wins that, when scaled, will add up to a big improvement
ToList , the code calls Enumerable. ToList() which is an extension method that return new List<TSource>(source) . In the corresponding constructor, under the worst circumstance, it goes through the item container and add them one by one into a new container. So its behavior affects little on performance.
ToList() makes a shallow copy. The references are copied, but the new references still point to the same instances as the original references point to.
The ToList<TSource>(IEnumerable<TSource>) method forces immediate query evaluation and returns a List<T> that contains the query results. You can append this method to your query in order to obtain a cached copy of the query results.
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.
How efficient is the ToList() method? Will it create a new list and how much memory does that take, assuming the contents are POCOs? Does this change if its a value type rather than a POCO?
The ToList()
method materializes the given collection by creating a new list and populating it with the items of the given collection. Linq.ToList()
implementation:
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
if (source == null) throw Error.ArgumentNull("source");
return new List<TSource>(source);
}
By doing so you are not gaining the power of deffered execution if needed
Will the size of the list determine efficiency or does size of list not determine cost of ToList()?
As it calls List
s copy constructor and it creates a new list then it'll work on each of the items. So it'll run in O(n)
- meaning that list's size matters. MSDNs documentation about the operation of the copy constructor:
Initializes a new instance of the List class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.
As @Jason mentioned in the comment bellow the Copy Constructor is smart and is efficient but doing it when not needed is still an O(n)
operation that doesn't have to happen
If a list is cast to an IEnumerable and then ToList() is called on it, will it just return the original object?
No. It will create a new list as seen above
As for your example code:
input = input.OrderBy(s => s.Thing).ToList();
foreach(var thing in input)
{
// do things
}
As you are getting a materialized list (rather than an IQueriable
/IEnumerable
that might perform in deffered execution) adding the ToList
after the adding gives you no benefit.
You can look here, might also help: When to use LINQ's .ToList() or .ToArray()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With