What’s new in .NET 8.0 [12]: FrozenSet performance

Technology

In the previous part of this series I have the class FrozenSet<T> in the namespace System.Collections.Frozen introduced, which is new in .NET 8.0. The question arises why Microsoft FrozentSet<T> also introduced. The answer to the question is, as often happens, performance.

Announcement




Dr. Holger Schwichtenberg is the technical director of the expert network www.IT-Visions.de which, with 53 renowned experts, supports numerous medium and large-sized companies through consultancy, training and software development. Thanks to his participation in numerous national and international conferences, as well as more than 90 specialist books and more than 1,500 specialist articles, Holger Schwichtenberg is one of the best-known experts on .NET and web technologies in Germany.

This time I will evaluate the speed based on a typical application example.

Data is an unordered set of numbers between 1 and 10,000. How quickly can you find a single number in the set?

The library is used to measure performance BenchmarkDotNet from Microsoft for use.

using System.Collections.Frozen;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Toolchains.InProcess.NoEmit;
 
namespace NET8_Console.Collections_Benchmark;
 
public class AntiVirusFriendlyConfig : ManualConfig
{
 public AntiVirusFriendlyConfig()
 {
  AddJob(Job.MediumRun
      .WithToolchain(InProcessNoEmitToolchain.Instance));
 }
}
 
[Config(typeof(AntiVirusFriendlyConfig))]
public class Collections_Contains_Benchmark
{
 private const int Iterations = 1000;
 private readonly List<int> list;
 private readonly ReadOnlyCollection<int> roCollection;
 private readonly FrozenSet<int> frozenSet;
 private readonly HashSet<int> hashSet;
 private readonly ImmutableList<int> immutableList;
 private readonly ImmutableHashSet<int> immutableHashSet;
 
 public Collections_Contains_Benchmark()
 {
  var array = Enumerable.Range(1, 10000).ToArray();
  Random.Shared.Shuffle<int>(array);
  list = array.ToList();
  // liefert ReadOnlyCollection<T>:
  roCollection = list.AsReadOnly(); 
  frozenSet = list.ToFrozenSet();
  hashSet = list.ToHashSet();
  immutableList = list.ToImmutableList();
  immutableHashSet = list.ToImmutableHashSet();
 }
 
 [Benchmark(Baseline = true)]
 public void ListContains()
 {
  for (var i = 0; i < Iterations; i++)
  {
   var b = list.Contains(i);
  }
 }
 
 [Benchmark]
 public void ReadOnlyCollectionContains()
 {
  for (var i = 0; i < Iterations; i++)
  {
   var b = roCollection.Contains(i);
  }
 }
 
 [Benchmark]
 public void FrozenSetContains()
 {
  for (var i = 0; i < Iterations; i++)
  {
   var b = frozenSet.Contains(i);
  }
 }
 
 [Benchmark]
 public void HashSetContains()
 {
  for (var i = 0; i < Iterations; i++)
  {
   var b = hashSet.Contains(i);
  }
 }
 
 [Benchmark]
 public void ImmutableListContains()
 {
  for (var i = 0; i < Iterations; i++)
  {
   var b = immutableList.Contains(i);
  }
 }
 
 [Benchmark]
 public void ImmutableHashSetContains()
 {
  for (var i = 0; i < Iterations; i++)
  {
   var b = immutableHashSet.Contains(i);
  }
 }
}

The benchmark shown in the following figure calls the method 1000 times Contains() on an unordered list of 10,000 numbers. The quantity of the type FrozenSet wins if viewed 1000 times Contains() compared to other sets of objects.



Figure: A set of type FrozenSet provides significantly higher performance when calling Contains() 1000 times.

(Image: Screenshot (Holger Schwichtenberg))


(myself)

To the home page

Leave a Reply

Your email address will not be published. Required fields are marked *