Performance difference of Any() and Count()

Asked

Viewed 437 times

12

When I need to check whether a Collection has or has not elements which of the two methods will be faster, .Count() =! 0 or .Any()?

I’ve heard that the .Count() may be faster in some cases. But by checking the source code, the method Any() it seemed better to be used.

There is also the possibility of having a condition within the method, in which case it can change which of the two is faster?

And when it’s used in a DbSet, to query generated by .Any() is different from .Count() I imagine. But in terms of performance, Any() is still ahead?

2 answers

12

Depends on the type of enumeration.

If it is based on ICollection<T>, .Count (property, not method) is faster because the value is already previously calculated within the structure (optimized). .Any() requires using the sequence GetEnumerator() / MoveNext() / Dispose().

Already in any other enumerations, .Count() (now method) iterates all elements. Any() has the flow stopped when locating the first sequence, so it’s faster than .Count()

In short, Any() behaves better in most cases.

  • 2

    It seems to me that there is often confusion between . Count and . Count() so maybe many people find . Count() faster. But all this just confirms what I imagined.

11


You’re right. By the way these methods work, analyzing item by item from a collection, there are more advantages to using the Any() (source) when you can do it.

With the Count() (source) you are saying that you want to know how many items there are within the collection (or a subset of it that has already been decided by other LINQ methods). The only way to know this is to go through all the items.

People often use this form because they are used to pure collections where you can ask the Count (the property and not method) and has the answer virtually no cost, after all in the pure collection, without having gone through a LINQ expression, the quantity of items is something controlled by the class and is there available always reliably and quickly.

In LINQ it does not have this facility, it has to go through everything and count, at least in subsets. Of course there may be optimizations that take the count stored in the collection but not in the standard implementation (LINQ-to-Objects does this). And you might want the count anyway, in which case use it.

But often people just want to know if there is at least one item. The way everyone gets used to it is to check that the count is greater than zero. Very intuitive, works and in pure collections is fast.

But let’s face it, if you want to know if there’s only one item, you don’t want to know how many you have, just find the first item and you have your answer. You do not need to look at the other entries. The answer will already be true and nothing that happens in the other entries can change the result.

In the worst case of Any(), which is to find nothing, the performance will be the same as the Count(). In all others it will be better, in many, absurdly better.

The Count() LINQ, without optimizations, will always be linear complexity, already the Any() will be between constant and linear, which changes a lot.

The fact of having a condition that is a substitute for the Where() does not affect anything directly. Indirectly can help the Any() because it makes it easier for him to have a condition to end the search first. In the case of the optimization I mentioned above, it is also not possible when there is a condition as a parameter, just as it would no longer be if I used a previous condition with a Where(), for example.

I couldn’t find a reliable source and I don’t know the Entity Framework well enough to get an answer, but by the nature of how it works, I believe it remains valid in most cases. The LINQ query will be transformed into an SQL query that will have to traverse the lines to count or find an existing one. However, a specific database may know how to optimally catch the line count in some situations. Here the Count() can possibly be faster. But note that it depends on the bank used, the LINQ provider of it and the specific situation. Don’t count on it too much, consider it lucky when it happens.

If you really need the performance, realize that it’s critical and you can make gains, you’ll have to make a code to manage the choice. By default always go from Any() when all you want to know is if it exists.

  • And when it is used in a Dbset, the query generated by . Any() is still better?

  • 1

    @Hokos good question, I’ll try to find out for you . What I can already say is that it can vary even. Remembering that these LINQ methods are contextual according to the type of collection you are using, so the Dbset implementation may possibly not be the same as the one you listed.

  • I’ll edit the question and when I find out you supplement your answer.

  • 1

    Today is negative days on me. I hope there’s a reason. I hope the person shows what’s wrong.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.