title: Huge Performance Difference with HashSet between .NET Framework 4.8 and .NET 5
body: <p>I have the problem where the application is very slow because there are events with thousands of handlers attached to it and removing those handlers is really slow. My application runs as .NET Framework 4.8 process,</p>
  <p>I wrote a test Programm (but with .NET 5) where I replaced the event with an own implementation where I used a HashSet to store the handlers and implement the add / remove handlers of the event by myself.</p>
  <p>My test application worked great, but after applying this solution to my real application, the performance was still bad.</p>
  <p>I than realized that the runtime difference seems to be the reason. The following sample program runs fast (approx. 1 second  on .NET 5, but runs several minutes if run the same code in a .NET Framework 4.8 Application):</p>
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Diagnostics;
  using System.Linq;
  
  namespace EventPerformaneMeasurement
  {
      class Program
      {
          private static void Main()
          {
              var sw = new Stopwatch();
              var mc = new MyClass();
              var list = Enumerable.Range(1, 1_000_000).Select(x =&gt; new PropertyChangedEventHandler((_, _) =&gt; { Console.WriteLine($&quot;Handler {x} called&quot;); })).ToList();
              
              sw.Restart();
              list.ForEach(handler=&gt;mc.PropertyChangedNew += handler); 
             
              sw.Stop();
              Console.WriteLine(sw.ElapsedMilliseconds);
              
              sw.Restart();
              list.ForEach(handler=&gt;mc.PropertyChangedNew -= handler); 
              
              sw.Stop();
              Console.WriteLine(sw.ElapsedMilliseconds);
          }
      }
  
      class MyClass
      {
          private HashSet&lt;PropertyChangedEventHandler&gt; _handlers = new();
          
          public event PropertyChangedEventHandler PropertyChangedNew
          {
              add =&gt; _handlers.Add(value);
              remove =&gt; _handlers.Remove(value);
          }
      }
  }
  </code></pre>
  <p>I created two .NET fiddles to reproduce this behavior, the .NET fiddle required me to change the syntax of my sample code a little bit and to reduce from 1000000 to 15000 iterations, but the performance difference is still visible:</p>
  <ul>
  <li><a href="https://dotnetfiddle.net/2Gxm3j" rel="nofollow noreferrer">.NET 4.7.2</a></li>
  <li><a href="https://dotnetfiddle.net/eVdtZc" rel="nofollow noreferrer">.NET 5</a></li>
  </ul>
  <p>I can't believe that there is a such big difference between .NET 5 and .NET Framework 4.x regarding HashSet performance.</p>
  <p>Does anyone know more about this effect or where I'm maybe stuck? Is there a way to get the same   performance in .NET 4.8 with another way?</p>