Closed
Description
Description
The new Logging generators for LoggerMessage
cause the generated implementations to allocate due to usage of a method group which the generator assigns to Func<TState, Exception?, string> formatter
in a ILogger.Log
call. This is due to a fact that method groups are not cached whereas lambdas are (which is not always obvious, see dotnet/roslyn#5835).
Configuration
- 10.0.19043.1319 (21H1/May2021Update)
- .NET 6.0.0 (6.0.21.48005), X64 RyuJIT
- Intel Core i7-4770S CPU 3.10GHz (Haswell)
Data
Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Allocated |
---|---|---|---|---|---|---|---|
NoLevel | 21.37 ns | 0.454 ns | 0.558 ns | 1.00 | 0.00 | - | - |
WithLevel | 20.95 ns | 0.431 ns | 0.443 ns | 0.98 | 0.04 | 0.0153 | 64 B |
FixedWithLevel | 13.94 ns | 0.260 ns | 0.231 ns | 0.65 | 0.03 | - | - |
Fix suggestion
Instead of generating a Format
method like this:
public static string Format(__StateStruct state, global::System.Exception? ex) => state.ToString();
Generate it like this:
public static readonly Func<__StateStruct, global::System.Exception?, string> Format = (state, ex) => state.ToString();
But generally speaking, fixing the compiler and/or the runtime would be a better way everybody can benefit from 😉.
Note
As can be seen from the benchmarks below, generated calls without LogLevel
can be further improved by using a similar structure as with the state as calls with LogLevel
are using to achieve better performance.