org.sonar.plugins.csharp.S6609.html Maven / Gradle / Ivy
Why is this an issue?
Both the Enumerable.Max
extension method and the SortedSet<T>.Max
property can be used to find the maximum value in
a SortedSet<T>
. However, SortedSet<T>.Max
is much faster than Enumerable.Max
. For small
collections, the performance difference may be minor, but for large collections, it can be noticeable. The same applies for the Min
property as well.
Max
and Min
in SortedSet<T>
exploit the fact that the set is implemented via a Red-Black
tree
. The algorithm to find the Max
/Min
is "go left/right whenever possible". The operation has the time complexity
of O(h)
which becomes O(ln(n))
due to the fact that the tree is balanced. This is much better than the O(n)
time complexity of extension methods.
Max
and Min
in ImmutableSortedSet<T>
exploits a tree augmentation technique, storing the
Min
, Max
and Count
values on each node of the data structure. The time complexity in this case is
O(1)
that is significantly better than O(n)
of extension methods.
Applies to:
- SortedSet<T>.Max
- SortedSet<T>.Min
- ImmutableSortedSet<T>.Max
- ImmutableSortedSet<T>.Min
- ImmutableSortedSet<T>.Builder.Max
- ImmutableSortedSet<T>.Builder.Min
What is the potential impact?
We measured a significant improvement both in execution time and memory allocation. For more details see the Benchmarks
section from
the More info
tab.
How to fix it
The Min
and Max
properties are defined on the following classes, and the extension method call can be replaced by calling
the propery instead:
-
SortedSet<T>
-
ImmutableSortedSet<T>
-
ImmutableSortedSet<T>.Builder
Code examples
Noncompliant code example
int GetMax(SortedSet<int> data) =>
data.Max();
int GetMin(SortedSet<int> data) =>
data.Min();
Compliant solution
int GetMax(SortedSet<int> data) =>
data.Max;
int GetMin(SortedSet<int> data) =>
data.Min;
Resources
Documentation
Benchmarks
Method
Runtime
Mean
Standard Deviation
Allocated
MaxMethod
.NET 7.0
68,961.483 us
499.6623 us
248063 B
MaxProperty
.NET 7.0
4.638 us
0.0634 us
-
MaxMethod
.NET Framework 4.6.2
85,827.359 us
1,531.1611 us
281259 B
MaxProperty
.NET Framework 4.6.2
67.682 us
0.3757 us
312919 B
Glossary
The results were generated by running the following snippet with BenchmarkDotNet:
private SortedSet<string> data;
[Params(1_000)]
public int Iterations;
[GlobalSetup]
public void Setup() =>
data = new SortedSet<string>(Enumerable.Range(0, Iterations).Select(x => Guid.NewGuid().ToString()));
[Benchmark(Baseline = true)]
public void MaxMethod()
{
for (var i = 0; i < Iterations; i++)
{
_ = data.Max(); // Max() extension method
}
}
[Benchmark]
public void MaxProperty()
{
for (var i = 0; i < Iterations; i++)
{
_ = data.Max; // Max property
}
}
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