public void PerformanceTest([Values(1,10)] int attachCount) { var target = new EventTarget(); var sw = new Stopwatch(); var eventRaiseCalls = 10000000; var expectedCalls = attachCount * eventRaiseCalls; for (int i = 0; i < attachCount; i++) { target.OrdinaryEvent += Target_OrdinaryEvent; target.WeakEvent += Target_OrdinaryEvent; target.WeakEventSource += Target_OrdinaryEvent; } sw.Reset(); sw.Start(); RaiseEvents(eventRaiseCalls, () => target.RaiseOrdinaryEvent()); var ordinary = sw.ElapsedMilliseconds; Assert.That(target.CallCount, Is.EqualTo(expectedCalls), "call count mismatch RaiseOrdinaryEvent"); target.CallCount = 0; sw.Reset(); sw.Start(); RaiseEvents(eventRaiseCalls, () => target.RaiseWeakEventSource()); var wes = sw.ElapsedMilliseconds; Assert.That(target.CallCount, Is.EqualTo(expectedCalls), "call count mismatch RaiseWeakEventSource"); target.CallCount = 0; sw.Reset(); sw.Start(); RaiseEvents(eventRaiseCalls, () => target.RaiseWeakEvent()); var we = sw.ElapsedMilliseconds; Assert.That(target.CallCount, Is.EqualTo(expectedCalls), "call count mismatch RaiseWeakEvent"); target.CallCount = 0; var top = (wes / 100) * 103; Console.Out.WriteLine($"{nameof(EventTarget.OrdinaryEvent)} {ordinary}"); Console.Out.WriteLine($"{nameof(EventTarget.WeakEventSource)} {wes}"); Console.Out.WriteLine($"{nameof(EventTarget.WeakEvent)} {we}"); Console.Out.WriteLine($"top {top}"); Assert.That(ordinary, Is.LessThanOrEqualTo(we), "ordinary should be the fastest"); if (we < wes && we > 0) { var p = ((wes/we)*100L); Console.Out.WriteLine($"WeakEvent execution time is {p}% relative to {nameof(wes)}"); } }