Why the .Any() Method Can Be Faster Than .Count() in C#
In C#, two primary tools exist for determining if a collection contains elements. The .Count() property tells you exactly how many items are in a collection, while the .Any() LINQ extension method returns true when a collection contains at least one item. While .Count() seems like the obvious pick, there are situations where .Any() is much faster. Read on to see why.
The .Count() property usually does very little work. For collections that implement the ICollection interface (e.g., List, Dictionary, etc.), the actual count of items is usually stored internally. Checking .Count() is an O(1) operation, which means it takes constant time, regardless of the collection’s size.
The .Any() method takes a different tack. It iterates through a collection, applying an optional predicate (condition), if one was provided. Crucially, .Any() stops iterating as soon as it finds an item matching the condition (or any item at all, if no condition was provided). This is where its potential performance edge comes from.
For very large collections, .Count() must visit every item to give you an accurate result. However, .Any() can save time by stopping the moment it locates the first matching item.
If the item you’re looking for is likely to be located near the beginning of a collection, .Any() has a good shot at finding it quickly. By contrast, .Count() must always visit the end.
In Entity Framework and similar database access technologies, .Any() often translates into far more efficient SQL queries (e.g., IF EXISTS(…)), while .Count() often necessitates retrieving and counting all matching records.
Suppose you have a database table of millions of customer records and want to check if a customer with a specific email address exists.
.Count(x => x.Email == "user@example.com") > 0
could require the database to scan the entire table,
a potentially slow operation.
.Any(x => x.Email == "user@example.com")
might instruct the database to stop as soon as it finds a single
matching record, significantly boosting speed.
In .NET 6, the .Any() implementation got a big boost. Now tries to be more intelligent and attempts to call ICollection.Count under the covers. So, with even a modicum of luck, in .NET 6 and later, .Any() is frequently just as fast as, or possibly even faster than, .Count().
While .Count() is fast as blazes in many cases, remember:
If you need to know only whether some elements exist in the collection and don’t need to know exactly how many there are, .Any() usually delivers as good or better performance.
The more elements you have in your collection (or if you’re working with a database), the bigger the benefit from using .Any().
In short, in .NET 6+, .Any() is a great choice that provides a very nice mix of both speed and utility.
If you like to check the code of benchmark you find following next link.
Recommendations are validated through the benchmark results. It’s established that .AnyWithConditionEarlyExit() is in all cases faster that .ManualCountWithCondition(), but becomes relatively ever faster as collection sizes increase.
First, for small collections, .Any() allows us to finish quicker than .ManualCountWithCondition(). This gap increases with collection sizes, and allows us to confirm that .Any() is the way forward when it comes to checking if elements that satisfies a condition exist in the collection.
Originally published at https://www.admirmujkic.com.