Is it better to do ToList () before ToDictionary?

Should I do ToList () before executing GroupBy () and ToDictionary () twice, like in the example below. Can ToList () maximize performance when creating a dictionary? Without ToList () Resharper screams for 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));
}

      

+3


source to share


4 answers


Is it better to do ToList

before ToDictionary

?

No, it Enumerable.ToDictionary

lists all the elements anyway, so there is no benefit. The opposite is true, you need to populate another collection in a loop for no reason

Is it better to do ToList () before ToDictionary

if I need multiple dictionaries?



Maybe. It depends on the type of sequence. It could be a database query that takes a long time to complete. Without, ToList

you will complete it several times. But it could be a collection or a very cheap request. Resharper wants you to think about it.

There's another subtle difference that has nothing to do with performance. If you are not storing the sequence in the collection (fe c ToList

), you might be in a deferred execution context (for example, if oldItems

is a database query). This means that whenever you execute this query, you will get the current result, which may differ from the previous execution result. This may be desirable, you just have to keep this in mind.

+7


source


Resharper warns you that the next IEnumerable can be consumed twice when you intend only once. Placing items in a list consumes the IEnumerable in the list. You can enumerate the list as many times as you like, where IEnumerable will give the next element. collection

can be consumed in the first usual ways, so the behavior might be unexpected for the second use.



+1


source


Without ToList

your collection

is SelectEnumerator

over oldItems

, which will be listed twice for both dict1

and for dict2

. This means it i => new item()

will be called twice for each item oldItems

.

0


source


I would say it's simple - don't list IEnumerable multiple times. Just don't do it. If you need to iterate multiple times, you can define an IList / IReadOnlyList interface. Btw. you can build a second dictionary with the values ​​of the first in this case.

0


source







All Articles