Using cmd:
| Method | Mean | Error | StdDev | Allocated |
|------------------------- |---------:|---------:|---------:|----------:|
| LoggingConsole_OneChar | 182.4 us | 4.98 us | 14.69 us | 185 B |
| SystemConsole_OneChar | 182.1 us | 5.71 us | 16.74 us | - |
| LoggingConsole_10Chars | 183.4 us | 4.07 us | 11.87 us | 214 B |
| SystemConsole_10Chars | 183.0 us | 4.75 us | 13.92 us | - |
| LoggingConsole_100Chars | 184.6 us | 4.85 us | 13.99 us | 394 B |
| SystemConsole_100Chars | 194.1 us | 4.38 us | 12.70 us | - |
| LoggingConsole_1000Chars | 530.2 us | 10.60 us | 28.12 us | 2,171 B |
| SystemConsole_1000Chars | 542.6 us | 10.42 us | 30.22 us | - |
Consider 530.2us for 1000 chars. That is 1886 iterations per second for 1000 chars per iteration (2000 bytes per iteration), which is 3.6 MB/sec. Now comparing this BenchmarkDotNet speed for console logging to just using a StopWatch in a console app:
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddCustomFormatter(o =>
o.CustomPrefix = " ~~~~~ ");
});
var logger = loggerFactory.CreateLogger<Program>();
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 10000; i++)
{
logger.LogInformation(_1000Chars);
}
sw.Stop();
var elapsedForLoggingConsole = sw.ElapsedMilliseconds;
Console.Error.WriteLine($"how many bytes? {howManyBytes} * 10000 = {howManyBytes * 10000} = {howManyBytes * 10000 / (1024 * 1024)}MB");
Console.Error.WriteLine($"elapsedForLoggingConsole: {elapsedForLoggingConsole}ms");
Console.Error.WriteLine($"Speed: {(howManyBytes * 10000 / (1024 * 1024)) / (elapsedForLoggingConsole / 1000.0f)} MB/sec");
Output
how many bytes? 2000 * 10000 = 20000000 = 19MB
elapsedForLoggingConsole: 3827ms
Speed: 4.9647245MB/sec
Same experiment now for Console.WriteLine
:
var howManyBytes = _1000Chars.Length * sizeof(char);
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 10000; i++)
{
Console.WriteLine(_1000Chars);
}
sw.Stop();
var elapsedForSystemConsole = sw.ElapsedMilliseconds;
Console.Error.WriteLine($"how many bytes? {howManyBytes} * 10000 = {howManyBytes * 10000} = {howManyBytes * 10000 / (1024 * 1024)}MB");
Console.Error.WriteLine($"elapsedForSystemConsole: {elapsedForSystemConsole}ms");
Console.Error.WriteLine($"Speed: {(howManyBytes * 10000 / (1024 * 1024)) / (elapsedForSystemConsole / 1000.0f)} MB/sec");
Output
how many bytes? 2000 * 10000 = 20000000 = 19MB
elapsedForSystemConsole: 4365ms
Speed: 4.3528066MB/sec
Also note, the logging console speed increases significantly with the output piped to a file output:
> dotnet run -c Release
...
how many bytes? 2000 * 10000 = 20000000 = 19MB
elapsedForLoggingConsole: 3773ms
Speed: 5.0357804 MB/sec
> dotnet run -c Release > out.txt
how many bytes? 2000 * 10000 = 20000000 = 19MB
elapsedForLoggingConsole: 175ms
Speed: 108.571434 MB/sec
> dotnet run -c Release > nul
how many bytes? 2000 * 10000 = 20000000 = 19MB
elapsedForLoggingConsole: 39ms
Speed: 487.17947 MB/sec
when profiling for: