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

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

There is a newer version: 10.2.0.105762
Show newest version

Why is this an issue?

Both the List.Find method and IEnumerable.FirstOrDefault method can be used to find the first element that satisfies a given condition in a collection. However, List.Find can be faster than IEnumerable.FirstOrDefault for List objects. For small collections, the performance difference may be minor, but for large collections, it can make a noticeable difference. The same applies for ImmutableList and arrays too.

Applies to

What is the potential impact?

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

How to fix it

The Find method is defined on the collection class, and it has the same signature as FirstOrDefault extension method. The function can be replaced in place.

Code examples

Noncompliant code example

int GetValue(List<int> data) =>
    data.FirstOrDefault(x => x % 2 == 0);
int GetValue(int[] data) =>
    data.FirstOrDefault(x => x % 2 == 0);

Compliant solution

int GetValue(List<int> data) =>
    data.Find(x => x % 2 == 0);
int GetValue(int[] data) =>
    Array.Find(data, x => x % 2 == 0);

Resources

Documentation

Benchmarks

Method Runtime Mean Standard Deviation Allocated

FirstOrDefault

.NET 7.0

5.373 ms

0.1049 ms

125 KB

Find

.NET 7.0

1.691 ms

0.0334 ms

85.94 KB

FirstOrDefault

.NET Framework 4.6.2

5.035 ms

0.0421 ms

125.38 KB

Find

.NET Framework 4.6.2

1.779 ms

0.0107 ms

86.2 KB

Glossary

The results were generated by running the following snippet with BenchmarkDotNet:

private List<string> data;
private Random random = new Random();

[Params(1_000)]
public int N { get; set; }

[GlobalSetup]
public void Setup() =>
    data = Enumerable.Range(0, N).Select(x => Guid.NewGuid().ToString()).ToList();

[Benchmark(Baseline = true)]
public void FirstOrDefault()
{
    for (var i = 0; i < N; i++)
    {
        var value = data[random.Next(N - 1)];
        _ = data.FirstOrDefault(x => x == value);   // Enumerable.FirstOrDefault()
    }
}

[Benchmark]
public void Find()
{
    for (var i = 0; i < N; i++)
    {
        var value = data[random.Next(N - 1)];
        _ = data.Find(x => x == value);             // List<T>.Find()
    }
}

Hardware configuration:

BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2846/22H2/2022Update)
11th Gen Intel Core i7-11850H 2.50GHz, 1 CPU, 16 logical and 8 physical cores
  [Host]               : .NET Framework 4.8 (4.8.4614.0), X64 RyuJIT VectorSize=256
  .NET 7.0             : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
  .NET Framework 4.6.2 : .NET Framework 4.8 (4.8.4614.0), X64 RyuJIT VectorSize=256




© 2015 - 2024 Weber Informatics LLC | Privacy Policy