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

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

There is a newer version: 10.2.0.105762
Show newest version

Why is this an issue?

Indexes in C# provide direct access to an element at a specific position within an array or collection. When compared to Enumerable methods, indexing can be more efficient for certain scenarios, such as iterating over a large collection, due to avoiding the overhead of checking the underlying collection type before accessing it.

This applies to types that implement one of these interfaces:

What is the potential impact?

We measured a significant improvement in execution time. For more details see the Benchmarks section from the More info tab.

How to fix it

If the type you are using implements IList, IList<T> or IReadonlyList<T>, it implements this[int index]. This means calls to First, Last, or ElementAt(index) can be replaced with indexing at 0, Count-1 and index respectively.

Code examples

Noncompliant code example

int GetAt(List<int> data, int index)
    => data.ElementAt(index);
int GetFirst(List<int> data)
    => data.First();
int GetLast(List<int> data)
    => data.Last();

Compliant solution

int GetAt(List<int> data, int index)
    => data[index];
int GetFirst(List<int> data)
    => data[0];
int GetLast(List<int> data)
    => data[data.Count-1];

Resources

Documentation

Benchmarks

Method Runtime Mean Standard Deviation

ElementAt

3,403.4 ns

28.52 ns

26.67 ns

Index

478.0 ns

6.93 ns

6.48 ns

First

6,160.0 ns

57.66 ns

53.93 ns

First_Index

485.7 ns

5.81 ns

5.15 ns

Last

6,034.3 ns

20.34 ns

16.98 ns

Last_Index

408.3 ns

2.54 ns

2.38 ns

Glossary

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

private List<byte> data;
private Random random;

[Params(1_000_000)]
public int SampleSize;

[Params(1_000)]
public int LoopSize;

[GlobalSetup]
public void Setup()
{
    random = new Random(42);

    var bytes = new byte[SampleSize];
    random.NextBytes(bytes);
    data = bytes.ToList();
}

[Benchmark]
public int ElementAt()
{
    int result = default;

    for (var i = 0; i < LoopSize; i++)
    {
        result = data.ElementAt(i);
    }

    return result;
}

[Benchmark]
public int Index()
{
    int result = default;

    for (var i = 0; i < LoopSize; i++)
    {
        result = data[i];
    }

    return result;
}

[Benchmark]
public int First()
{
    int result = default;

    for (var i = 0; i < LoopSize; i++)
    {
        result = data.First();
    }

    return result;
}

[Benchmark]
public int First_Index()
{
    int result = default;

    for (var i = 0; i < LoopSize; i++)
    {
        result = data[0];
    }

    return result;
}

[Benchmark]
public int Last()
{
    int result = default;

    for (var i = 0; i < LoopSize; i++)
    {
        result = data.Last();
    }

    return result;
}

[Benchmark]
public int Last_Index()
{
    int result = default;

    for (var i = 0; i < LoopSize; i++)
    {
        result = data[data.Count - 1];
    }

    return result;
}

Hardware configuration:

BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.4412/22H2/2022Update)
11th Gen Intel Core i7-11850H 2.50GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=8.0.301
  [Host]   : .NET 8.0.6 (8.0.624.26715), X64 RyuJIT AVX2
  .NET 8.0 : .NET 8.0.6 (8.0.624.26715), X64 RyuJIT AVX2




© 2015 - 2024 Weber Informatics LLC | Privacy Policy