In this article, we are going to learn the main differences between Any and Count methods from LINQ.

We work with different collections in C# all the time, and we often need to check if there are any records inside the collection or if it is empty. Both methods can help us to achieve that. We are going to see how each method works internally and compare the efficiency of each approach to determine which one we should use in specific use cases.

To download the source code for this article, you can visit our GitHub repository.

Let’s dive into it.

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!

What are Any() and Count() Methods Used For?

Both Any() and Count() methods are part of the LINQ (Language Integrated Query), which is a uniform query language introduced with .NET 3.5.

The main purpose of LINQ is to retrieve data from different data sources, while Any() and Count() are one of the most popular LINQ methods we use in our everyday coding with C#.

How Does Any() Method Work?

We use the Any() method to determine if at least one element is present in the data source. If the data source is not empty, the method will return true. Otherwise, it will return false

There are two different overloads of the Any() method that we can use to check if a data source contains data or not:

public static bool Any<TSource> (this IEnumerable<TSource> source);

This is the extension method that doesn’t accept any additional parameters.

We can use the second overload of the method to determine if there are any records in the collection that satisfy the given condition:

public static bool Any<TSource> (this IEnumerable<TSource> source, Func<TSource,bool> predicate);

In this case, we can provide a Func<TSource,bool> predicate as a parameter to specify the condition we want to check.

How Does Count() Method Work?

On the other hand, we use the Count() extension method to count the number of records in the collection. Similar to the Any() method, the Count() method has two different overloads.

The first overload is the parameterless method which will return the number of elements present in the collection:

public static int Count<TSource> (this IEnumerable<TSource> source);

We can use the other method with the Func<TSource,bool> predicate to specify the condition. This method will return a number based on the elements in the collection that satisfy a condition:

public static int Count<TSource> (this IEnumerable<TSource> source, Func<TSource,bool> predicate);

Prepare the Environment

Now, let’s prepare our environment for comparison between the two methods.

First, let’s create a new class that we will use to perform different operations with Any() and Count() methods:

[Orderer(SummaryOrderPolicy.FastestToSlowest)]
public class PerformanceBenchmark

Here we create the PerformanceBenchmark class with the Orderer annotation added to order the results from fastest to slowest.

Then, let’s add our collection to the class and initialize it with the Range() static method from Enumerable:

private static readonly IEnumerable<int> _numbersEnumerable = Enumerable.Range(1, 1000);

Here we populate the data with numbers from 1 to 1000.

We will use the _numbersEnumerable member to perform different operations with Any() and Count() methods.

Any() without Condition

Next, let’s create our first benchmark method inside the PerformanceBenchmark class:

[Benchmark]
public bool CheckWithAny()
{
    return _numbersEnumerable.Any();
}

In this simple method, we return the bool type, based on the _numbersEnumerable value. Here we use the Any() method without parameters, so it will return true if there are any records in the IEnumerable. We use the Benchmark annotation from the BenchmarkDotNet library to mark the method for benchmark comparison.

Any() with Condition

Let’s now check how we can implement the Any() method by passing the predicate into the method:

[Benchmark]
public bool CheckWithAnyAndCondition()
{
    return _numbersEnumerable.Any(num => num > 500);
}

In the CheckWithAnyAndCondition() method, we check if we have any values in the _numberEnumerable that are greater than 500. If that is the case, the method will return true. Otherwise, it will return false.

Count() without Condition

Now, let’s look at the Count() method without parameters. This method returns an int value based on the number of elements in the collection. To perform the same logic as with the Any() method, we need to check if the return value of the Count() method is greater than zero:

[Benchmark]
public bool CheckWithCount()
{
    return _numbersEnumerable.Count() > 0;
}

Here we implement the CheckWithCount() method that returns the bool value. The method will return true if there are any elements in the _numbersEnumerable. Otherwise, it will return false.

Count() with Condition

With that, let’s now use the Count() method with the parameter:

[Benchmark]
public bool CheckWithCountAndCondition()
{
    return _numbersEnumerable.Count(num => num > 500) > 0;
}

Same as on the previous Any() example, here we return true if there are any elements in the _numbersEnumerable greater than 500.

Any vs Count Benchmark

With all of our methods ready, we’re going to perform a benchmark with the BenchmarkDotNet library to measure the time performance for each approach.

For that, let’s modify our Program class:

BenchmarkRunner.Run<PerformanceBenchmark>();

Here we execute the Run method that will perform the comparison on all methods from our PerformanceBenchmark class.

Benchmark Comparison with 1000 Records

Finally, let’s run our console application in the release configuration with the dotnet run -c Release command and get the results:

|                     Method |        Mean |      Error |     StdDev |
|--------------------------- |------------:|-----------:|-----------:|
|               CheckWithAny |    10.38 ns |   0.209 ns |   0.196 ns |
|             CheckWithCount |    11.66 ns |   0.255 ns |   0.340 ns |
|   CheckWithAnyAndCondition | 2,734.07 ns |  52.861 ns |  70.568 ns |
| CheckWithCountAndCondition | 5,505.87 ns | 108.016 ns | 120.059 ns |

Here we can see our benchmark results based on the IEnumerable with 1000 records.

Both Any() and Count() methods are faster without the condition. Without the condition, both methods are pretty close, with the Any() method being slightly faster. On the other hand, we can see that the Any() method with the condition performs much better as it takes 2,734 ns, while the Count() method with the condition takes 5,505 ns.

Benchmark Comparison with 50,000 Records

We should always check the performance of the methods with different sizes, so let’s change the size of IEnumerable:

private static readonly IEnumerable<int> _numbersEnumerable = Enumerable.Range(1, 50000);

Now, let’s run our program again and see how methods perform with 50,000 records:

|                     Method |          Mean |        Error |       StdDev |
|--------------------------- |--------------:|-------------:|-------------:|
|               CheckWithAny |      10.77 ns |     0.214 ns |     0.200 ns |
|             CheckWithCount |      11.83 ns |     0.210 ns |     0.196 ns |
|   CheckWithAnyAndCondition |   2,839.01 ns |    56.751 ns |    75.761 ns |
| CheckWithCountAndCondition | 292,231.08 ns | 5,135.502 ns | 7,527.553 ns |

Again, we see similar results. Both Any() and Count() methods perform similarly when working without the condition. On the other hand, we can see that the Any() method performs multiple times faster when checking through the 50,000 records with the specified condition.

That said, if we want to check if there are any records in the IEnumerable type, we should go with the Any() method.

Count Property

In some cases, when our IEnumerable is actually an ICollection like List for example, we can use the Count property:

public int Count { get; }

This is different from the Count() extension method that works on any IEnumerable and iterates through each element to determine how many elements are there.

On the other hand, the Count property uses the _size private variable inside the ICollection type which is maintained by Add() or Remove() methods to increase/decrease the value based on the operation. That means that this operation is O(1) or instant, while the Count() method needs to iterate through all elements – O(n).

We should note that the LINQ code has underlying optimizations to detect if there is a Count property. One limitation of the Count property is that we cannot use it with the condition.

If we work with arrays, we can use the Length property in the same way.

Count Property Benchmark

Let’s add another private field to our PerformanceBenchmark class:

private static readonly ICollection<int> _numbersList = Enumerable.Range(1, 50000).ToList();

Here we add the _numbersList field with the Range() method. The only difference from our _numbersEnumerable is that we call the ToList() method to convert the data to the List type, which will have access to the Count property.

Then, let’s add a new method to check if there are any records in the list with the Count property:

[Benchmark]
public bool CheckWithCountProperty()
{
    return _numbersList.Count > 0;
}

Finally, let’s run our benchmark again with 50,000 records and check the results:

|                     Method |            Mean |         Error |        StdDev |
|--------------------------- |----------------:|--------------:|--------------:|
|     CheckWithCountProperty |       0.2891 ns |     0.0359 ns |     0.0657 ns |
|               CheckWithAny |      10.7252 ns |     0.2266 ns |     0.2225 ns |
|             CheckWithCount |      11.8063 ns |     0.2618 ns |     0.4152 ns |
|   CheckWithAnyAndCondition |   2,813.2671 ns |    54.9630 ns |    61.0913 ns |
| CheckWithCountAndCondition | 287,027.1517 ns | 4,533.0244 ns | 4,240.1939 ns |

Awesome, here we can see that the CheckWithCountProperty() method executes almost instantly.

Conclusion

In this article, we’ve learned a lot about the differences between Any() and Count() methods from LINQ. We also had a look at the Count property that we can use on all ICollection types in C#. With different methods and conditions, we got different performance results.

The main conclusion is that we should always use the Count property when possible and when we don’t need to perform any additional conditions. Otherwise, when we use the types from IEnumerable that don’t have the Count property or we want to use conditions, we should go with the Any() method.

The Any() method will enumerate over a single item, while the Count() method causes complete enumeration. Another good reason to use Any() most of the time is to clarify the intent of the developer since the name of the method says what we want to check.

With that, this is a simpler and cleaner option to optimize our C# code.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!