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:
We measured a significant improvement both in execution time and memory allocation. For more details see the Benchmarks section from
the More info tab.
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
Function GetMax(data As SortedSet(Of Integer)) As Integer
Return Enumerable.Max(data)
End Function
Function GetMin(data As SortedSet(Of Integer)) As Integer
Return Enumerable.Min(data)
End Function
Function GetMax(data As SortedSet(Of Integer)) As Integer
Return data.Max()
End Function
Function GetMin(data As SortedSet(Of Integer)) As Integer
Return data.Min()
End Function
| Method | Runtime | Mean | StdDev | 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 |
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