Benchmarking Count() vs Count(x => true) performance in C#

Benchmarking Count() vs Count(x => true) performance in C#

Using .Count(x => true) in C# collections is generally redundant because it's equivalent to simply using .Count(). However, there are some specific use cases where it might be intentionally used:

1. Filtering with Dynamic Predicate

If you have a condition that can change dynamically, you might use .Count(x => condition), and in cases where the condition is always true, it acts as a fallback.

var items = new List<int> { 1, 2, 3, 4, 5 }; int count = items.Count(x => true); // Same as items.Count()

This might happen when a predicate is generated dynamically but isn't filtering anything in a particular scenario.

2. Preserving LINQ Method Chaining

Sometimes, you may want to keep .Count(x => true) to maintain consistent method chaining style, especially if conditions are optional.

var users = new List { new User("Alice"), new User("Bob") }; bool applyFilter = false; int count = applyFilter ? users.Count(u => u.Name.StartsWith("A")) : users.Count(x => true); // Keeps method chaining consistent

3. Placeholder for Readability

It might be used to explicitly indicate that no filter is being applied, making the intention clear.

var totalUsers = users.Count(x => true); // Explicitly counting all users

This can be useful in cases where conditions are frequently changed, and using a predicate ensures the format remains the same.

4. Avoiding Compiler Errors in Some Generic Scenarios

When working with generics where a filtering condition might sometimes be required, using .Count(x => true) ensures consistency.

public int GetItemCount(IEnumerable collection, Func? predicate = null) { return predicate != null ? collection.Count(predicate) : collection.Count(x => true); }

5. Write Benchmark Code

Install the BenchmarkDotNet NuGet package in your project.

Create a benchmarking class that compares .Count() and .Count(x => true):

public class CountPerformanceTest { private readonly List _numbers; public CountPerformanceTest() { _numbers = Enumerable.Range(1, 1_000_000).ToList(); // 1 million items } [Benchmark] public int CountDirect() { return _numbers.Count(); } [Benchmark] public int CountTrue() { return _numbers.Count(x => true); } [Benchmark] public int CountGreaterZero() { return _numbers.Count(x => x >= 0); } [Benchmark] public int EF_WhereCount() { MyDbContext context = new MyDbContext(); return context.Table1s.Where(x=>x.col1 != "").Count(); } [Benchmark] public int EF_SQL_CountTrue() { MyDbContext context = new MyDbContext(); return context.Table1s.SqlQuery("SELECT * FROM Table1 WHERE col1 <> ''").Count(x => true); } [Benchmark] public int EF_SQL_Count() { MyDbContext context = new MyDbContext(); return context.Table1s.SqlQuery("SELECT * FROM Table1 WHERE col1 <> ''").Count(); } [Benchmark] public int EF_SQL_CountWithPredicat() { MyDbContext context = new MyDbContext(); return context.Table1s.SqlQuery("SELECT * FROM Table1").Count(x => x.col1 != ""); } [Benchmark] public int EF_Count() { MyDbContext context = new MyDbContext(); return context.Table1s.Count(x => x.col1 != ""); } }

6. Explanation

  • _numbers.Count() → Uses ICollection<T>.Count directly if available (O(1) for List).
  • _numbers.Count(x => true) → Iterates through the entire collection (O(N)), making it much slower.
  • The Number's benchmark tests each method on 1 million elements to highlight performance differences.
  • The EF's benchmark tests each method on 100k elements

7. Running the Test

Run the program, and BenchmarkDotNet will generate a detailed performance report like:

Intel Core i7-10710U CPU 1.10GHz, 1 CPU, 12 logical and 6 physical cores

Method Mean Error StdDev Median
CountDirect 14.36 ns 0.350 ns 1.033 ns 14.27 ns
CountTrue 8,756,153.91 ns 414,524.776 ns 1,209,188.316 ns 8,720,592.19 ns
CountGreaterZero 7,473,755.17 ns 149,453.370 ns 358,080.756 ns 7,317,334.38 ns

EntityFramework benchmark results:

Method Mean Error StdDev
EF_WhereCount 15.22 ms 0.284 ms 0.266 ms
EF_SQL_CountTrue 354.04 ms 10.065 ms 29.520 ms
EF_SQL_Count 349.30 ms 7.712 ms 22.495 ms
EF_SQL_CountWithPredicat 574.62 ms 12.181 ms 35.339 ms
EF_Count 15.50 ms 0.136 ms 0.114 ms

Why to Use .Count()?

  • If you don't need a predicate, .Count() is more efficient because it directly retrieves the count for ICollection<T> without iterating.
  • .Count(x => true) forces iteration in IEnumerable<T> instead of using a direct count, which can be slower.

 

Conclusion

🚀 Use .Count() whenever possible.
📌 Use .Count(x => true) only if:

  • You need to maintain consistent method chaining.
  • You're working with a dynamically assigned predicate.

About us

Do you need help in services integration? Contact us to start working for your project!

Read More

Are you looking for