When you call Any(), it clearly communicates the code’s intention, which is to check if the collection is empty. Using Count()
== 0 for this purpose is less direct and makes the code slightly more complex. However, there are some cases where special attention should be
paid:
EntityFramework or other ORM query, calling Count() will cause executing a potentially
massive SQL query and could put a large overhead on the application database. Calling Any() will also connect to the database, but will
generate much more efficient SQL. Select() statements that create objects, a large amount of memory could be
unnecessarily allocated. Calling Any() will be much more efficient because it will execute fewer iterations of the enumerable. Prefer using Any() to test for emptiness over Count().
private static bool HasContent(IEnumerable<string> strings)
{
return strings.Count() > 0; // Noncompliant
}
private static bool HasContent2(IEnumerable<string> strings)
{
return strings.Count() >= 1; // Noncompliant
}
private static bool IsEmpty(IEnumerable<string> strings)
{
return strings.Count() == 0; // Noncompliant
}
private static bool HasContent(IEnumerable<string> strings)
{
return strings.Any();
}
private static bool HasContent2(IEnumerable<string> strings)
{
return strings.Any();
}
private static bool IsEmpty(IEnumerable<string> strings)
{
return !strings.Any();
}
| Method | Runtime | Mean | Standard Deviation |
|---|---|---|---|
Count |
.NET 9.0 |
2,841.003 ns |
266.0238 ns |
Any |
.NET 9.0 |
1.749 ns |
0.1242 ns |
Count |
.NET Framework 4.8.1 |
71,125.275 ns |
731.0382 ns |
Any |
.NET Framework 4.8.1 |
31.774 ns |
0.3196 ns |
The results were generated by running the following snippet with BenchmarkDotNet:
private IEnumerable<int> collection;
public const int N = 10_000;
[GlobalSetup]
public void GlobalSetup()
{
collection = Enumerable.Range(0, N).Select(x => N - x);
}
[Benchmark(Baseline = true)]
public bool Count() =>
collection.Count() > 0;
[Benchmark]
public bool Any() =>
collection.Any();
Hardware Configuration:
BenchmarkDotNet v0.14.0, Windows 10 (10.0.19045.5247/22H2/2022Update) 12th Gen Intel Core i7-12800H, 1 CPU, 20 logical and 14 physical cores [Host] : .NET Framework 4.8.1 (4.8.9282.0), X64 RyuJIT VectorSize=256 .NET 9.0 : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2 .NET Framework 4.8.1 : .NET Framework 4.8.1 (4.8.9282.0), X64 RyuJIT VectorSize=256