Significant allocations writing F# types using Console.Logger
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 22h
- Merged PRs (30d)
- 144
Description
### Description
I've been working on reducing memory allocation across my app after migrating to .net 8, and after I was done with the majority of C# codebase I've stumbled across huge memory allocation produced by logging.
### Configuration
```xml
Exe
net6.0
```
```fsharp
module Program
open System
open BenchmarkDotNet.Attributes
open BenchmarkDotNet.Jobs
open BenchmarkDotNet.Running
open Microsoft.AspNetCore.Builder
open Microsoft.Extensions.Logging
open Microsoft.Extensions.DependencyInjection
type StoreError =
| Exception of exn
| ErrorDuringReadingChannelFromDatabase of channel: string
| AlreadyExists of Guid
| NotFound of Guid
with member this.SerializeError (): obj =
match this with
| Exception ex -> ex
| ErrorDuringReadingChannelFromDatabase channel -> $"ErrorDuringReadingChannelFromDatabase: {channel}"
| AlreadyExists id -> $"AlreadyExists: {id}"
| NotFound id -> $"NotFound: {id}"
let sampleNotFound = NotFound(Guid.NewGuid())
let sampleException = Exception(new Exception("Test"))
[]
[]
[]
[]
type Benchmark() =
[] val mutable logger : ILogger
[]
member this.Setup() =
let builder = WebApplication.CreateBuilder();
let app = builder.Build();
this.logger <- app.Services.GetRequiredService>()
[]
member this.One() =
this.logger.LogError("Hello world {Error}", sampleNotFound);
[]
member this.Two() =
this.logger.LogError("Hello world {Error}", sampleNotFound.SerializeError())
[]
member this.Three() =
this.logger.LogError("Hello world {Error}", sampleException);
[]
member this.Four() =
this.logger.LogError("Hello world {Error}", sampleException.SerializeError());
[]
let Run (args: string array) =
BenchmarkRunner.Run() |> ignore
0
```
### Regression?
| Method | Job | Runtime | Mean | Error | StdDev | Gen0 | Allocated |
|---------------------- |------------------ |--------- |---------:|----------:|---------:|-------:|----------:|
| 'Raw NotFound' | ShortRun-.NET 6.0 | .NET 6.0 | 221.7 us | 78.49 us | 4.30 us | 0.2441 | 36.43 KB |
| 'Processed NotFound' | ShortRun-.NET 6.0 | .NET 6.0 | 210.7 us | 23.75 us | 1.30 us | - | 1.89 KB |
| 'Raw Exception' | ShortRun-.NET 6.0 | .NET 6.0 | 210.8 us | 94.25 us | 5.17 us | 0.2441 | 35.6 KB |
| 'Processed Exception' | ShortRun-.NET 6.0 | .NET 6.0 | 214.6 us | 141.40 us | 7.75 us | - | 1.51 KB |
| 'Raw NotFound' | ShortRun-.NET 7.0 | .NET 7.0 | 213.3 us | 21.77 us | 1.19 us | 0.2441 | 36.64 KB |
| 'Processed NotFound' | ShortRun-.NET 7.0 | .NET 7.0 | 215.6 us | 211.11 us | 11.57 us | - | 1.8 KB |
| 'Raw Exception' | ShortRun-.NET 7.0 | .NET 7.0 | 213.5 us | 170.31 us | 9.34 us | 0.2441 | 35.82 KB |
| 'Processed Exception' | ShortRun-.NET 7.0 | .NET 7.0 | 210.5 us | 55.88 us | 3.06 us | - | 1.41 KB |
| 'Raw NotFound' | ShortRun-.NET 8.0 | .NET 8.0 | 174.3 us | 772.66 us | 42.35 us | - | 36.65 KB |
| 'Processed NotFound' | ShortRun-.NET 8.0 | .NET 8.0 | 207.2 us | 147.52 us | 8.09 us | - | 1.8 KB |
| 'Raw Exception' | ShortRun-.NET 8.0 | .NET 8.0 | 174.7 us | 680.77 us | 37.32 us | - | 35.83 KB |
| 'Processed Exception' | ShortRun-.NET 8.0 | .NET 8.0 | 217.6 us | 73.26 us | 4.02 us | - | 1.41 KB |
Contributor guide
Assessment
This issue has not been assessed yet.