Reputation: 1499
Is it worth to do the ToList() before doing the GroupBy() and ToDictionary() twice as in example below. Does the ToList() may maximize the performance when creating the dictionary? Without ToList() Resharper is yelling about possible multiple enumeration.
public void SomeMethod(IEnumerable<oldItem> oldItems)
{
var collection = oldItems.Select(i => new item()).ToList();
var dict1 = collection.ToDictionary(i => i.Key);
var dict2 = collection
.GroupBy(i => i.FieldA)
.ToDictionary(g => g.Key, g => new Flags(g.ToArray));
}
Upvotes: 4
Views: 1718
Reputation: 6103
I would state it simply - do not enumerate IEnumerable multiple times. Just do not do that. If you need to iterate over multiple times, you can define IList/IReadOnlyList interface. Btw. you can construct the second dictionary from values of the first in this case.
Upvotes: 0
Reputation: 460058
Is it better to do
ToList
beforeToDictionary
?
No, Enumerable.ToDictionary
enumerates all items anyway so there is no benefit. The opposite is true, you need to fill another collection in a loop for no reason
Is it better to do ToList() before
ToDictionary
if i need multiple dictionaries?
Probably. It depends on the type of the sequence. It could be a database query that takes ages to execute. Without ToList
you will execute it multiple times. But it could also be a collection or very cheap query. Resharper wants you to think about it.
There's another subtle difference which has nothing to do with performance. If you don't store the sequence in a collection(f.e with ToList
) you could be in a deferred execution context(f.e. if oldItems
is a database query). That means whenever you execute this query you will get the current result which could be different to the previous execution's result. That might be desired, you just have to keep that in mind.
Upvotes: 9
Reputation: 18013
Without the ToList
your collection
is a SelectEnumerator
around the oldItems
, which will be enumerated twice for both dict1
and dict2
.
This means that i => new item()
will be called twice for each elements of oldItems
.
Upvotes: 0
Reputation: 1034
Resharper warns you that the next item of the IEnumerable may be consumed twice when you intend only once. Putting the items in a list consumes the IEnumerable into a list. You can enumerate over a list as many times you want, where IEnumerable will yield the next item. collection
may be consumed by the first usages, therefore the behaviour may be unexpected for the second use.
Upvotes: 1