All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.plugins.csharp.S6603.html Maven / Gradle / Ivy

There is a newer version: 10.5.0.109200
Show newest version

Why is this an issue?

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

What is the potential impact?

We measured at least 4x improvement both in execution time. For more details see the Benchmarks section from the More info tab.

How to fix it

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.

Code examples

Noncompliant code example

public bool AreAllEven(List<int> data) =>
    data.All(x => x % 2 == 0);
public bool AreAllEven(int[] data) =>
    data.All(x => x % 2 == 0);

Compliant solution

public bool AreAllEven(List<int> data) =>
    data.TrueForAll(x => x % 2 == 0);
public bool AreAllEven(int[] data) =>
    Array.TrueForAll(data, x => x % 2 == 0);

Resources

Documentation

Benchmarks

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

-

Glossary

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy