Tracing vs Logging Performance in .NET 6

I was wondering what’s the overhead of using ILogger versus built-in tracing so I’ve made some measurements.

Despite the fact that using ILogger needs extra library and EventSource is part of the runtime, I wanted to compare what’s the performance like when using:

  • Just EventSource.
  • ILogger with no log sinks configured at all.
  • ILogger with the fastest sink available, which is EventSource (to be more honest).

Here are the results:

MethodMeanErrorStdDevMinMaxMedianGen0Allocated
EmptyILogger40.828 ns7.079 ns0.3880 ns40.468 ns41.239 ns40.776 ns0.007632 B
EventSourceILogger58.839 ns11.665 ns0.6394 ns58.196 ns59.475 ns58.845 ns0.007632 B
NativeEventSource3.588 ns1.077 ns0.0590 ns3.528 ns3.645 ns3.592 ns--

So it seems like even an empty ILogger withing nothing configured at all is 11.3 times faster. Another interesting thing is EventSource has absolutely zero memory allocations, even when using message formatting, wow!

Adding a very fast EventSource logger to ILogger makes it 16.3 times slower than EventSource. Adding other sinks is apparently even worse.

Now, this is not a critique of ILogger in any way, because ES and IL serve completely different purposes. It’s a simple comparison for a piece of mind.

For completeness, including benchmarking code below:

#LINQPad optimize+

[EventSource(Name = "Perf")]
public class PerfEventSource : EventSource {

    public static PerfEventSource Log { get; } = new PerfEventSource();

    [Event(1, Message = "a simple {0}", Level = EventLevel.Informational)]
    public void PerfPing(string p) {
        WriteEvent(1, p);
    }
}

[ShortRunJob]
[MinColumn, MaxColumn, MeanColumn, MedianColumn]
[MemoryDiagnoser]
[MarkdownExporter]
public class TracingVsLoggingBenchmark {

    Microsoft.Extensions.Logging.ILogger emptyLogger;
    Microsoft.Extensions.Logging.ILogger esLogger;

    [GlobalSetup]
    public void Setup() {
        var emptyFactory = LoggerFactory.Create(builder => {
            
        });
        
        emptyLogger = emptyFactory.CreateLogger("empty");
        
        var tracingFactory = LoggerFactory.Create(builder => {
           builder.AddEventSourceLogger(); 
        });
        
        esLogger = tracingFactory.CreateLogger("es");
    }
    
    [Benchmark]
    public void EmptyILogger() {
        emptyLogger.LogInformation("a simple {0}", "message");
    }

    [Benchmark]
    public void EventSourceILogger() {
        esLogger.LogInformation("a simple {0}", "message");
    }


    [Benchmark]
    public void NativeEventSource() {
        PerfEventSource.Log.PerfPing("message");
    }
}


void Main() {
    Util.AutoScrollResults = true;
    BenchmarkRunner.Run<TracingVsLoggingBenchmark>();
    
    
}


To contact me, send an email anytime or leave a comment below.