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

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

There is a newer version: 10.2.0.105762
Show newest version

Why is this an issue?

It is important to be careful when searching for characters within a substring. Let’s consider the following example:

if (str.SubString(startIndex).IndexOf(char1) == -1) // Noncompliant: a new string is going to be created by "Substring"
{
   // ...
}

A new string object is created with every call to the Substring method. When chaining it with any of the following methods, it creates a new object for one-time use only:

What is the potential impact?

Creating a new object consumes significant system resources, especially CPU and memory. When using Substring repeatedly, such as in a loop, it can greatly impact the overall performance of the application or program.

To mitigate the creation of new objects while searching for characters within a substring, it is possible to use an overload of the mentioned methods with a startIndex parameter:

if (str.IndexOf(char1, startIndex) == -1)           // Compliant: no new instance of string is created
{
   // ...
}

Using these methods gives the same result while avoiding the creation of additional string objects.

Resources

Documentation

Benchmarks

Method Runtime StringSize Mean StdDev Ratio Allocated

SubstringThenIndexOf

.NET 7.0

10

11.234 ms

0.1319 ms

1.00

40000008 B

IndexOfOnly

.NET 7.0

10

2.477 ms

0.0473 ms

0.22

2 B

SubstringThenIndexOf

.NET Framework 4.6.2

10

8.634 ms

0.4195 ms

1.00

48141349 B

IndexOfOnly

.NET Framework 4.6.2

10

1.724 ms

0.0346 ms

0.19

-

SubstringThenIndexOf

.NET 7.0

100

14.651 ms

0.2977 ms

1.00

176000008 B

IndexOfOnly

.NET 7.0

100

2.464 ms

0.0501 ms

0.17

2 B

SubstringThenIndexOf

.NET Framework 4.6.2

100

13.363 ms

0.2044 ms

1.00

176518761 B

IndexOfOnly

.NET Framework 4.6.2

100

1.689 ms

0.0290 ms

0.13

-

SubstringThenIndexOf

.NET 7.0

1000

78.688 ms

2.4727 ms

1.00

1528000072 B

IndexOfOnly

.NET 7.0

1000

2.456 ms

0.0397 ms

0.03

2 B

SubstringThenIndexOf

.NET Framework 4.6.2

1000

75.994 ms

1.2650 ms

1.00

1532637240 B

IndexOfOnly

.NET Framework 4.6.2

1000

1.699 ms

0.0216 ms

0.02

-

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

private string theString;
private int iteration = 1_000_000;

[Params(10, 100, 1_000)]
public int StringSize { get; set; }

[GlobalSetup]
public void Setup() =>
    theString = new string('a', StringSize);

[Benchmark(Baseline = true)]
public void SubstringThenIndexOf()
{
    for (var i = 0; i < iteration; i++)
    {
        _ = theString.Substring(StringSize / 4).IndexOf('a');
    }
}

[Benchmark]
public void IndexOfOnly()
{
    for (var i = 0; i < iteration; i++)
    {
        _ = theString.IndexOf('a', StringSize / 4) - StringSize / 4;
    }
}

Hardware configuration:

BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2965/22H2/2022Update)
12th Gen Intel Core i7-12800H, 1 CPU, 20 logical and 14 physical cores
.NET SDK=7.0.203
  [Host]               : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
  .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