Last active
December 16, 2021 14:50
-
-
Save gingters/476f258e5e91f093902e1620358e49fd to your computer and use it in GitHub Desktop.
Logging Performance Benchmark (.NET 6 console test)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<OutputType>Exe</OutputType> | |
<TargetFramework>net6.0</TargetFramework> | |
<ImplicitUsings>enable</ImplicitUsings> | |
<Nullable>enable</Nullable> | |
</PropertyGroup> | |
<ItemGroup> | |
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" /> | |
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" /> | |
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" /> | |
</ItemGroup> | |
</Project> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Run with | |
dotnet run --configuration=RELEASE | |
*/ | |
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Running; | |
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.Logging; | |
BenchmarkRunner.Run<LoggingClass>(); | |
record CustomData(string SomeText, int SomeValue, DateTime SomeDate); | |
[MemoryDiagnoser] | |
public partial class LoggingClass | |
{ | |
private readonly ILogger _logger; | |
private readonly CustomData _customData; | |
public LoggingClass() | |
: this( | |
new ServiceCollection() | |
.AddLogging(o => o | |
.SetMinimumLevel(LogLevel.Information) | |
.AddProvider(new NullLoggerProvider()) | |
) | |
.BuildServiceProvider() | |
.GetRequiredService<ILogger<LoggingClass>>() | |
) | |
{ } | |
public LoggingClass(ILogger<LoggingClass> logger) | |
{ | |
_logger = logger; | |
_customData = new CustomData("SomeText", 1, DateTime.UtcNow); | |
} | |
// INTERPOLATED LOGGING USAGE | |
[Benchmark] | |
public void InterpolatedLogTrace() | |
{ | |
_logger.LogTrace(1, $"This is a sample template logging {_customData.SomeText} {_customData.SomeValue} {_customData.SomeDate} All: @{_customData}"); | |
} | |
[Benchmark] | |
public void InterpolatedLogCritical() | |
{ | |
_logger.LogCritical(1, $"This is a sample template logging {_customData.SomeText} {_customData.SomeValue} {_customData.SomeDate} All: @{_customData}"); | |
} | |
// CHECKED INTERPOLATED LOGGING USAGE | |
[Benchmark] | |
public void CheckedInterpolatedLogTrace() | |
{ | |
if (_logger.IsEnabled(LogLevel.Trace)) | |
{ | |
_logger.LogTrace(1, $"This is a sample template logging {_customData.SomeText} {_customData.SomeValue} {_customData.SomeDate} All: @{_customData}"); | |
} | |
} | |
[Benchmark] | |
public void CheckedInterpolatedLogCritical() | |
{ | |
if (_logger.IsEnabled(LogLevel.Critical)) | |
{ | |
_logger.LogCritical(1, $"This is a sample template logging {_customData.SomeText} {_customData.SomeValue} {_customData.SomeDate} All: @{_customData}"); | |
} | |
} | |
// COMMON LOGGING USAGE | |
[Benchmark] | |
public void CommonLoggingTrace() | |
{ | |
_logger.LogTrace(1, "This is a sample template logging {Text} {Value} {Date} All: @{data}", _customData.SomeText, _customData.SomeValue, _customData.SomeDate, _customData); | |
} | |
[Benchmark] | |
public void CommonLoggingCritical() | |
{ | |
_logger.LogCritical(1, "This is a sample template logging {Text} {Value} {Date} All: @{data}", _customData.SomeText, _customData.SomeValue, _customData.SomeDate, _customData); | |
} | |
// LOG LEVEL CHECKED LOGGING USAGE | |
[Benchmark] | |
public void CheckedCommonLoggingTrace() | |
{ | |
if (_logger.IsEnabled(LogLevel.Trace)) | |
{ | |
_logger.LogTrace(1, "This is a sample template logging {Text} {Value} {Date} All: @{data}", _customData.SomeText, _customData.SomeValue, _customData.SomeDate, _customData); | |
} | |
} | |
[Benchmark] | |
public void CheckedCommonLoggingCritical() | |
{ | |
if (_logger.IsEnabled(LogLevel.Critical)) | |
{ | |
_logger.LogCritical(1, "This is a sample template logging {Text} {Value} {Date} All: @{data}", _customData.SomeText, _customData.SomeValue, _customData.SomeDate, _customData); | |
} | |
} | |
// DEFINED ACTION LOGGING USAGE | |
private static readonly Action<ILogger, string, int, DateTime, CustomData, Exception?> _logActionTrace = | |
LoggerMessage.Define<string, int, DateTime, CustomData>( | |
logLevel: LogLevel.Trace, | |
eventId: 1, | |
formatString: "This is a sample template logging {Text} {Value} {Date} All: @{data}"); | |
private static readonly Action<ILogger, string, int, DateTime, CustomData, Exception?> _logActionCritical = | |
LoggerMessage.Define<string, int, DateTime, CustomData>( | |
logLevel: LogLevel.Critical, | |
eventId: 1, | |
formatString: "This is a sample template logging {Text} {Value} {Date} All: @{data}"); | |
[Benchmark] | |
public void ActionLoggingTrace() | |
{ | |
_logActionTrace(_logger, _customData.SomeText, _customData.SomeValue, _customData.SomeDate, _customData, null); | |
} | |
[Benchmark] | |
public void ActionLoggingCritical() | |
{ | |
_logActionCritical(_logger, _customData.SomeText, _customData.SomeValue, _customData.SomeDate, _customData, null); | |
} | |
// DEFINED ACTION CHECKED LOGGING USAGE | |
[Benchmark] | |
public void CheckedActionLoggingTrace() | |
{ | |
if (_logger.IsEnabled(LogLevel.Trace)) | |
{ | |
_logActionTrace(_logger, _customData.SomeText, _customData.SomeValue, _customData.SomeDate, _customData, null); | |
} | |
} | |
[Benchmark] | |
public void CheckedActionLoggingCritical() | |
{ | |
if (_logger.IsEnabled(LogLevel.Critical)) | |
{ | |
_logActionCritical(_logger, _customData.SomeText, _customData.SomeValue, _customData.SomeDate, _customData, null); | |
} | |
} | |
// SOURCE GENERATED LOGGING USAGE | |
[LoggerMessage(1, LogLevel.Trace, "This is a sample template logging {Text} {Value} {Date} All: @{data}")] | |
partial void SourcenGenLoggingTrace(string text, int value, DateTime date, CustomData data); | |
[LoggerMessage(1, LogLevel.Critical, "This is a sample template logging {Text} {Value} {Date} All: @{data}")] | |
partial void SourcenGenLoggingCritical(string text, int value, DateTime date, CustomData data); | |
// Benchmark methods | |
[Benchmark] | |
public void SourceGenLogTrace() | |
{ | |
SourcenGenLoggingTrace(_customData.SomeText, _customData.SomeValue, _customData.SomeDate, _customData); | |
} | |
[Benchmark] | |
public void SourceGenLogCritical() | |
{ | |
SourcenGenLoggingCritical(_customData.SomeText, _customData.SomeValue, _customData.SomeDate, _customData); | |
} | |
} | |
class NullLoggerProvider : ILoggerProvider | |
{ | |
public ILogger CreateLogger(string categoryName) => new NullLogger(); | |
public void Dispose() { } | |
class NullLogger : ILogger, IDisposable | |
{ | |
private int _dummy; | |
public IDisposable BeginScope<TState>(TState state) => new NullLogger(); | |
public bool IsEnabled(LogLevel logLevel) => logLevel >= LogLevel.Information; | |
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter) => _dummy++; | |
public void Dispose() { } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment