.NET Exceptions performance

Hi there!

I made few measurements with cool DotNetBenchmark library written by Andrey Akinshin:
1. I’m awaiting async method that throws deep in callstack and after catching i get StackTrace
2. I’m awaiting async method that throws deep in callstack
3. [COMPARISON ONLY] I’m awaiting async method that returns deep in callstack (without exception)
4. I’m calling normal method that throws deep in callstack
5. I’m calling normal method that throws deep in callstack and after catching i get StackTrace

Code is here (don’t forget to add DotNetBenchmark library, i used 0.78 from nuget)

For stack depth = 100 results are following

Clipboard02qwe

For stack depth = 10 results are following

Clipboard03

For stack depth = 1 results are following

Clipboard013

Clipboard02

CAUTION: Logarithmic scale!

From measurements we can see:
1. Getting stacktrace can slowdown your exception handling code significantly for deep stacks.
2. awaiting methods is very slow itself and exceptions don’t influence on its performance (if not to get stacktrace)

Advertisements

.NET Finalizer performance

Hi there!

During my eternal fighting with .NET performance i decided to check what performance impact does finalizer give.
The easiest way is to write isolated test.

In short, finalizer is symmetrical to ctor optional special method that is called when object is ready to be Garbage Collected on a special finalizer thread. It should be used to free unmanaged resource, and it is better not to touch any managed resources from it, because they can be already GCed.

In my test i create 10,000,000 instances of MyClass and either
1. Store them all in list so they all get to gen2
2. or just forget about them to let GC collect then during gen0 collection

My second research dimension covers finalizability.
a. MyClass has empty Dispose
b. MyClass has empty finalizer and have GC.SuppressFinalize in Dispose
c. MyClass has empty finalizer without GC.SupressFinalize being called

______a                 b                   c

1.     1400ms       2950ms        4300ms

2.       85ms         1000ms        2850ms

The code is here
I ran it on AMD FX-6200 4.4Ghz without CPU affinity.

This shows that
1. allocating/collecting shortliving objects without finalizer is very cheap.
2. forgetting to call SupressFinalize can significantly reduce your performance (finalizer doesn’t allow collecting shortliving objects immediately (in gen0) but adds them to finalization queue and moves to gen1 where they are collected after finalizer is called)

.