0

I have a Benchmark.NET project that runs my benchmarks and produces the latency output exactly how I want it but outputs no memory information.
When I added the [MemoryDiagnoser] annotation to the class no data for this diagnoser gets output, it's like it ignores it completely. I have this setup to run the benchmarks:

public class Program
{
    public static void Main(string[] args)
    {
        RunBenchmarks();
    }

    public static void RunBenchmarks()
    {
        var config = new ManualConfig()
            .AddDiagnoser(new MemoryDiagnoser(new MemoryDiagnoserConfig(true)))
            .AddLogger(ConsoleLogger.Default)
            .AddColumn(TargetMethodColumn.Method, StatisticColumn.Median, StatisticColumn.StdDev,
                StatisticColumn.Q1, StatisticColumn.Q3, new ParamColumn("Size"));
        BenchmarkDotNet.Running.BenchmarkRunner.Run<SerialiserBenchmarks>(config);

    }
}

I added the columns because it wasn't producing any output at all otherwise. The output to the console looks like this, which you can see contains all the explicitly added columns above:

|                           Method |             Size |    StdDev |    Median |        Q1 |        Q3 |
|--------------------------------- |----------------- |----------:|----------:|----------:|----------:|
|         StringSerialiseJsonEvent |            Small | 0.0817 us |  6.616 us |  6.603 us |  6.679 us |

at the moment. I have my benchmark class annotated as follows:

[ShortRunJob]
[MemoryDiagnoser]
public class SerialiserBenchmarks
{
   ...
}

Can someone please explain what the correct set of annotations/setup code is for me to get the memory diagnoser output (allocations, gcs and generations)?

Markus Meyer
  • 3,327
  • 10
  • 22
  • 35
ekke
  • 1,280
  • 7
  • 13

1 Answers1

0

You can solve it with a custom class derived from ManualConfig.

From the documentation:

Below is a sample output from the GC and Memory Allocation diagnoser, note the extra columns on the right-hand side ("Gen 0", "Gen 1", "Gen 2" and "Allocated"):

Config class based on your example:

public class SerialiserBenchmarksConfig : ManualConfig
{
    public SerialiserBenchmarksConfig()
    {
        AddDiagnoser(MemoryDiagnoser.Default);
        AddLogger(ConsoleLogger.Default);
        AddColumn(TargetMethodColumn.Method, StatisticColumn.Median, StatisticColumn.StdDev,
     StatisticColumn.Q1, StatisticColumn.Q3, new ParamColumn("Size"));
    }
}

Just add this config as attribute to your class:

[Config(typeof(SerialiserBenchmarksConfig))]

Class with benchmarks:

[ShortRunJob]
[Config(typeof(SerialiserBenchmarksConfig))]
public class SerialiserBenchmarks
{
    [Benchmark]
    public void Lorem()
    {
        Console.WriteLine(DateTime.Now.Ticks);
    }
}

The program:

internal class Program
{
    static void Main(string[] args)
    {
        var summary = BenchmarkRunner.Run<SerialiserBenchmarks>();
    }
}

Result:

| Method | Size |     Mean |    Error |   StdDev |   Median |       Q1 |       Q3 | Allocated |
|------- |----- |---------:|---------:|---------:|---------:|---------:|---------:|----------:|
|  Lorem |    ? | 105.6 us | 210.7 us | 11.55 us | 99.50 us | 98.92 us | 109.2 us |      64 B |

enter image description here

Markus Meyer
  • 3,327
  • 10
  • 22
  • 35