Both the List.TrueForAll method and the IEnumerable.All method can be used to check if all list elements satisfy a given
condition in a collection. However, List.TrueForAll can be faster than IEnumerable.All for List objects. The
performance difference may be minor for small collections, but for large collections, it can be noticeable.
It is important to enable this rule with caution, as performance outcomes can vary significantly across different runtimes. Notably, the performance improvements in .NET 9 have brought
All closer to the performance of collection-specific TrueForAll methods in most scenarios.
Applies to
We measured at least 4x improvement both in execution time. For more details see the Benchmarks section from the More
info tab.
The TrueForAll method is defined on the collection class, and it has the same signature as the All extension method. The
method can be replaced in place.
public bool AreAllEven(List<int> data) =>
data.All(x => x % 2 == 0);
public bool AreAllEven(int[] data) =>
data.All(x => x % 2 == 0);
public bool AreAllEven(List<int> data) =>
data.TrueForAll(x => x % 2 == 0);
public bool AreAllEven(int[] data) =>
Array.TrueForAll(data, x => x % 2 == 0);
| Method | Runtime | Categories | Mean | Standard Deviation | Allocated |
|---|---|---|---|---|---|
ArrayAll |
.NET 8.0 |
Array |
109.25 μs |
1.767 μs |
32 B |
ArrayTrueForAll |
.NET 8.0 |
Array |
45.01 μs |
0.547 μs |
- |
ArrayAll |
.NET 9.0 |
Array |
22.28 μs |
0.254 μs |
- |
ArrayTrueForAll |
.NET 9.0 |
Array |
37.60 μs |
0.382 μs |
- |
ArrayAll |
.NET Framework 4.8.1 |
Array |
495.90 μs |
4.342 μs |
40 B |
ArrayTrueForAll |
.NET Framework 4.8.1 |
Array |
164.52 μs |
2.030 μs |
- |
ImmutableListAll |
.NET 8.0 |
ImmutableList<T> |
940.29 μs |
5.600 μs |
72 B |
ImmutableListTrueForAll |
.NET 8.0 |
ImmutableList<T> |
679.46 μs |
2.371 μs |
- |
ImmutableListAll |
.NET 9.0 |
ImmutableList<T> |
922.43 μs |
14.564 μs |
72 B |
ImmutableListTrueForAll |
.NET 9.0 |
ImmutableList<T> |
692.31 μs |
8.897 μs |
- |
ImmutableListAll |
.NET Framework 4.8.1 |
ImmutableList<T> |
4,578.72 μs |
77.920 μs |
128 B |
ImmutableListTrueForAll |
.NET Framework 4.8.1 |
ImmutableList<T> |
4,393.49 μs |
122.061 μs |
- |
ImmutableListBuilderAll |
.NET 8.0 |
ImmutableList<T>.Builder |
970.45 μs |
13.598 μs |
73 B |
ImmutableListBuilderTrueForAll |
.NET 8.0 |
ImmutableList<T>.Builder |
687.82 μs |
6.142 μs |
- |
ImmutableListBuilderAll |
.NET 9.0 |
ImmutableList<T>.Builder |
981.17 μs |
12.966 μs |
72 B |
ImmutableListBuilderTrueForAll |
.NET 9.0 |
ImmutableList<T>.Builder |
710.19 μs |
16.195 μs |
- |
ImmutableListBuilderAll |
.NET Framework 4.8.1 |
ImmutableList<T>.Builder |
4,780.50 μs |
43.282 μs |
128 B |
ImmutableListBuilderTrueForAll |
.NET Framework 4.8.1 |
ImmutableList<T>.Builder |
4,493.82 μs |
76.530 μs |
- |
ListAll |
.NET 8.0 |
List<T> |
151.12 μs |
2.028 μs |
40 B |
ListTrueForAll |
.NET 8.0 |
List<T> |
58.03 μs |
0.493 μs |
- |
ListAll |
.NET 9.0 |
List<T> |
22.14 μs |
0.327 μs |
- |
ListTrueForAll |
.NET 9.0 |
List<T> |
46.01 μs |
0.327 μs |
- |
ListAll |
.NET Framework 4.8.1 |
List<T> |
619.86 μs |
6.037 μs |
48 B |
ListTrueForAll |
.NET Framework 4.8.1 |
List<T> |
208.49 μs |
2.340 μs |
- |
The results were generated by running the following snippet with BenchmarkDotNet:
// Explicitly cache the delegates to avoid allocations inside the benchmark.
private readonly static Func<int, bool> ConditionFunc = static x => x == Math.Abs(x);
private readonly static Predicate<int> ConditionPredicate = static x => x == Math.Abs(x);
private List<int> list;
private ImmutableList<int> immutableList;
private ImmutableList<int>.Builder immutableListBuilder;
private int[] array;
[Params(100_000)]
public int N { get; set; }
[GlobalSetup]
public void GlobalSetup()
{
list = Enumerable.Range(0, N).Select(x => N - x).ToList();
immutableList = ImmutableList.CreateRange(list);
immutableListBuilder = ImmutableList.CreateBuilder<int>();
immutableListBuilder.AddRange(list);
array = list.ToArray();
}
[BenchmarkCategory("List<T>"), Benchmark]
public bool ListAll() =>
list.All(ConditionFunc);
[BenchmarkCategory("List<T>"), Benchmark(Baseline = true)]
public bool ListTrueForAll() =>
list.TrueForAll(ConditionPredicate);
[BenchmarkCategory("ImmutableList<T>"), Benchmark(Baseline = true)]
public bool ImmutableListAll() =>
immutableList.All(ConditionFunc);
[BenchmarkCategory("ImmutableList<T>"), Benchmark]
public bool ImmutableListTrueForAll() =>
immutableList.TrueForAll(ConditionPredicate);
[BenchmarkCategory("ImmutableList<T>.Builder"), Benchmark(Baseline = true)]
public bool ImmutableListBuilderAll() =>
immutableListBuilder.All(ConditionFunc);
[BenchmarkCategory("ImmutableList<T>.Builder"), Benchmark]
public bool ImmutableListBuilderTrueForAll() =>
immutableListBuilder.TrueForAll(ConditionPredicate);
[BenchmarkCategory("Array"), Benchmark(Baseline = true)]
public bool ArrayAll() =>
array.All(ConditionFunc);
[BenchmarkCategory("Array"), Benchmark]
public bool ArrayTrueForAll() =>
Array.TrueForAll(array, ConditionPredicate);
Hardware configuration:
BenchmarkDotNet v0.14.0, Windows 11 (10.0.22631.4317/23H2/2023Update/SunValley3) 11th Gen Intel Core i7-11850H 2.50GHz, 1 CPU, 16 logical and 8 physical cores [Host] : .NET Framework 4.8.1 (4.8.9277.0), X64 RyuJIT VectorSize=256 .NET 8.0 : .NET 8.0.10 (8.0.1024.46610), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI .NET 9.0 : .NET 9.0.0 (9.0.24.47305), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI .NET Framework 4.8.1 : .NET Framework 4.8.1 (4.8.9277.0), X64 RyuJIT VectorSize=256