Home > OS >  Completely remove method call at runtime
Completely remove method call at runtime

Time:05-09

Is it possible to completely remove the effects of a method call at runtime, including any performance effects?

I am working on a real-time C# application and would like to add verbose/debug level logs to some hot code, which is run at least 60 times per second. Ideally, these logs would have zero effect on the performance, when not used. Obviously, I can use preprocessor directives or [Conditional] to compile out these logs. However, this removes the possibility to enable them at runtime in a compiled application.

Is my best bet to just use a simple if in the log method and take the hit of the method call and comparison, or is there a way to achieve zero overhead of a log level that is deactivated?

CodePudding user response:

If the log is not critical, you can use an async wrapper around your logger.

Like this one for serilog.

https://www.nuget.org/packages/Serilog.Sinks.Async/

You can use two loggers one for critical logs like crashes and another that will be a blocking log and one for business logs that can be fully asynchronous.

CodePudding user response:

The cost of a disabled logging statement in Serilog, and no doubt in other loggers, is very very small.

For example, this program with ten million Debug() calls and an Information-level logger:

using System.Diagnostics;
using Serilog;

using var logger = new LoggerConfiguration()
    .WriteTo.Console()
    .CreateLogger();

logger.Information("Starting up");

var sw = Stopwatch.StartNew();

var max = 0;
for (var i = 0; i < 10_000_000;   i)
{
    logger.Debug("Counter is {Counter}", i);
    max = i;
}

logger.Information("Completed in {Elapsed} ms, max {Max}", sw.ElapsedMilliseconds, max);

Takes ~10 ms on my machine:

> dotnet run -c Release
[13:16:05 INF] Starting up
[13:16:05 INF] Completed in 10 ms, max 9999999

With the Debug() statement commented out entirely, the same loop takes 7 ms, putting the cost of a disabled logging statement right down there in the sub-nanosecond range.

Although it's a completely unscientific benchmark, Serilog's conditional logging performance is probably fine for the kind of scenario you're describing, and should be comparable to handwritten if.

  • Related