The biggest performance TRAP of LINQ in C# | .NET Tips 4

preview_player
Показать описание
Let's take a look at the biggest performance trap of LINQ in C# and .NET
Рекомендации по теме
Комментарии
Автор

This can be especially scary if you pass an enumerable from domain to application layer and then to UI layer, cause the domain will start enumerating when the UI starts using the enumerable.

SelmirAljic
Автор

Where i work we just decided we are List<T> people. Performance isn't that mission critical and we use the list convenience methods enough to make it worth it.

logantcooper
Автор

Rider actually suggests about possible multiple enumerations.

MercifulDeth
Автор

General advice: Make sure you understand what code you are actually writing, and what you want to do.
Indeed, iterating multiple times when not needed is not a great idea. But otherwise, unecessary storing into an array or list can be a wasteful memory allocation when iterating only once.
For this reason, when you write a dedicated method that does any kind of LINQ or yield return (both do technically the same thing of creating an Enumerator), you almost always want to directly return the IEnumerable, and not an Array or List. You want to leave that choice to the caller, which can then decide to do a ToArray or ToList or to iterate directly.

jongeduard
Автор

I just remembered one crutchy code I wrote yesterday and was about to die from anxiety, but then remembered I've converted enumerable to dictionary before using it multiple times. Whew, what a relief 😂

dmitriynaumov
Автор

So that's what Sonar has been yelling at me for.

milos
Автор

Thank you, I was having exactly these issues - including multiple calls to my MongoDB - that I didn't notice until watching this! This was why. 🙂👍

tjzIsMe
Автор

ReSharper Always Teller me that problem of multiple enumeration and with that short video it is nicely explained what the consequences of it are XD
Thanks for that

reneBrandy
Автор

Worth mentioning too is that some IEnumerables cannot be iterated multiple times. As in first time is fine, but the 2nd nets you a ObjectDisposedException, or completely different results.
For example, I made a IEnumerable wrapper for SqlDataReader to stream the data into my application by calling Read() and doing a yield return; it ends by calling NextResult(), and disposing the reader if that failed.
While this was deliberately designed for multiple iteration, each will return rows for a different ResultSet.

Also with counts, C#10 introduced TryGetNonEnumeratedCount(), which is worth using if you're not sure if the IEnumerable is backed by a Collection.

billybob
Автор

What's the tool you're using to draw those arrows from the red cursor?

timmartensson
Автор

so is it also safe abd betterif I convert to list a huge IEnunerable string? before I iterate or count them?

zacky
Автор

What's that drawing thing you use for arrows and boxes? I want it, it looks so useful!

Zooiest
Автор

Well, there’s that, but I’ve often seen massive linq queries that assume to be working with an iqueriable type, but is really an enumerable and causes issues if .tolist() is called too early.

echuck
Автор

This also applies to method return types of IEnumerable?

RaminMT
Автор

Tbh whenever the IDE suggests I add linq I just refactor. Never felt I needed it.

ar_xiv
Автор

But, there is a bool "TryGetNonEnumeratedCount(out int count)" extension method, as it names said, it try to get the count whitout forcing enumeration, i just tested it ones, so i do not know in which cases getting the count by enumerating is forced.

guillermosantos
Автор

I name those with "Query" on the end to remind that it's not a collection. It gets run.

SecondFinale
Автор

C#/Java: let me just hide the true nature of the iterator/iterable from you so that performance can be a 🎉surprise🎉

qmster
Автор

There was another youtuber on here that listed a "riddle" question just like this.
I made the same asssetion about evaluating the collection into something more final like a List or Array to avoid the issue.
I also recommended Tasks.Parallel, because in their example they used "Enumerable.Range" to queue some tasks that would never run as expected.

asteinerd
Автор

I don't use linq often, but I just assume every method call allocates a collection.

ApacheSenior