Skip to content

Commit f372668

Browse files
authored
Allow users to hide Gen X columns (#1764)
* don't display Gen X collumn if there were no collections for X generation * add MemoryDiagnoserConfig, allow users to customize MemoryDiagnoser
1 parent 8f81b5b commit f372668

File tree

12 files changed

+45
-9
lines changed

12 files changed

+45
-9
lines changed

src/BenchmarkDotNet/Attributes/MemoryDiagnoserAttribute.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ public class MemoryDiagnoserAttribute : Attribute, IConfigSource
99
{
1010
public IConfig Config { get; }
1111

12-
public MemoryDiagnoserAttribute()
12+
/// <param name="displayGenColumns">Display Garbage Collections per Generation columns (Gen 0, Gen 1, Gen 2). True by default.</param>
13+
public MemoryDiagnoserAttribute(bool displayGenColumns = true)
1314
{
14-
Config = ManualConfig.CreateEmpty().AddDiagnoser(MemoryDiagnoser.Default);
15+
Config = ManualConfig.CreateEmpty().AddDiagnoser(new MemoryDiagnoser(new MemoryDiagnoserConfig(displayGenColumns)));
1516
}
1617
}
1718
}

src/BenchmarkDotNet/Columns/MetricColumn.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class MetricColumn : IColumn
1616
public string Legend => descriptor.Legend;
1717
public bool AlwaysShow => true;
1818
public ColumnCategory Category => ColumnCategory.Metric;
19-
public int PriorityInCategory => 0;
19+
public int PriorityInCategory => descriptor.PriorityInCategory;
2020
public bool IsNumeric => true;
2121
public UnitType UnitType => descriptor.UnitType;
2222

src/BenchmarkDotNet/Configs/ImmutableConfig.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ internal ImmutableConfig(
9292
public IAnalyser GetCompositeAnalyser() => new CompositeAnalyser(analysers);
9393
public IDiagnoser GetCompositeDiagnoser() => new CompositeDiagnoser(diagnosers);
9494

95-
public bool HasMemoryDiagnoser() => diagnosers.Contains(MemoryDiagnoser.Default);
95+
public bool HasMemoryDiagnoser() => diagnosers.OfType<MemoryDiagnoser>().Any();
9696

9797
public bool HasThreadingDiagnoser() => diagnosers.Contains(ThreadingDiagnoser.Default);
9898

src/BenchmarkDotNet/Diagnosers/AllocatedNativeMemoryDescriptor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ internal class AllocatedNativeMemoryDescriptor : IMetricDescriptor
1212
public UnitType UnitType => UnitType.Size;
1313
public string Unit => SizeUnit.B.Name;
1414
public bool TheGreaterTheBetter => false;
15+
public int PriorityInCategory => 0;
1516
}
1617

1718
internal class NativeMemoryLeakDescriptor : IMetricDescriptor
@@ -23,5 +24,6 @@ internal class NativeMemoryLeakDescriptor : IMetricDescriptor
2324
public UnitType UnitType => UnitType.Size;
2425
public string Unit => SizeUnit.B.Name;
2526
public bool TheGreaterTheBetter => false;
27+
public int PriorityInCategory => 0;
2628
}
2729
}

src/BenchmarkDotNet/Diagnosers/MemoryDiagnoser.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ public class MemoryDiagnoser : IDiagnoser
1515
{
1616
private const string DiagnoserId = nameof(MemoryDiagnoser);
1717

18-
public static readonly MemoryDiagnoser Default = new MemoryDiagnoser();
18+
public static readonly MemoryDiagnoser Default = new MemoryDiagnoser(new MemoryDiagnoserConfig(displayGenColumns: true));
1919

20-
private MemoryDiagnoser() { } // we want to have only a single instance of MemoryDiagnoser
20+
public MemoryDiagnoser(MemoryDiagnoserConfig config) => Config = config;
21+
22+
public MemoryDiagnoserConfig Config { get; }
2123

2224
public RunMode GetRunMode(BenchmarkCase benchmarkCase) => RunMode.NoOverhead;
2325

@@ -33,9 +35,13 @@ public void Handle(HostSignal signal, DiagnoserActionParameters parameters) { }
3335

3436
public IEnumerable<Metric> ProcessResults(DiagnoserResults diagnoserResults)
3537
{
36-
yield return new Metric(GarbageCollectionsMetricDescriptor.Gen0, diagnoserResults.GcStats.Gen0Collections / (double)diagnoserResults.GcStats.TotalOperations * 1000);
37-
yield return new Metric(GarbageCollectionsMetricDescriptor.Gen1, diagnoserResults.GcStats.Gen1Collections / (double)diagnoserResults.GcStats.TotalOperations * 1000);
38-
yield return new Metric(GarbageCollectionsMetricDescriptor.Gen2, diagnoserResults.GcStats.Gen2Collections / (double)diagnoserResults.GcStats.TotalOperations * 1000);
38+
if (diagnoserResults.GcStats.Gen0Collections > 0 && Config.DisplayGenColumns)
39+
yield return new Metric(GarbageCollectionsMetricDescriptor.Gen0, diagnoserResults.GcStats.Gen0Collections / (double)diagnoserResults.GcStats.TotalOperations * 1000);
40+
if (diagnoserResults.GcStats.Gen1Collections > 0 && Config.DisplayGenColumns)
41+
yield return new Metric(GarbageCollectionsMetricDescriptor.Gen1, diagnoserResults.GcStats.Gen1Collections / (double)diagnoserResults.GcStats.TotalOperations * 1000);
42+
if (diagnoserResults.GcStats.Gen2Collections > 0 && Config.DisplayGenColumns)
43+
yield return new Metric(GarbageCollectionsMetricDescriptor.Gen2, diagnoserResults.GcStats.Gen2Collections / (double)diagnoserResults.GcStats.TotalOperations * 1000);
44+
3945
yield return new Metric(AllocatedMemoryMetricDescriptor.Instance, diagnoserResults.GcStats.GetBytesAllocatedPerOperation(diagnoserResults.BenchmarkCase));
4046
}
4147

@@ -50,6 +56,7 @@ private class AllocatedMemoryMetricDescriptor : IMetricDescriptor
5056
public UnitType UnitType => UnitType.Size;
5157
public string Unit => SizeUnit.B.Name;
5258
public bool TheGreaterTheBetter => false;
59+
public int PriorityInCategory => GC.MaxGeneration + 1;
5360
}
5461

5562
private class GarbageCollectionsMetricDescriptor : IMetricDescriptor
@@ -63,6 +70,7 @@ private GarbageCollectionsMetricDescriptor(int generationId)
6370
Id = $"Gen{generationId}Collects";
6471
DisplayName = $"Gen {generationId}";
6572
Legend = $"GC Generation {generationId} collects per 1000 operations";
73+
PriorityInCategory = generationId;
6674
}
6775

6876
public string Id { get; }
@@ -72,6 +80,7 @@ private GarbageCollectionsMetricDescriptor(int generationId)
7280
public UnitType UnitType => UnitType.Dimensionless;
7381
public string Unit => "Count";
7482
public bool TheGreaterTheBetter => false;
83+
public int PriorityInCategory { get; }
7584
}
7685
}
7786
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using JetBrains.Annotations;
2+
3+
namespace BenchmarkDotNet.Diagnosers
4+
{
5+
public class MemoryDiagnoserConfig
6+
{
7+
/// <param name="displayGenColumns">Display Garbage Collections per Generation columns (Gen 0, Gen 1, Gen 2). True by default.</param>
8+
[PublicAPI]
9+
public MemoryDiagnoserConfig(bool displayGenColumns = true)
10+
{
11+
DisplayGenColumns = displayGenColumns;
12+
}
13+
14+
public bool DisplayGenColumns { get; }
15+
}
16+
}

src/BenchmarkDotNet/Diagnosers/PmcMetricDescriptor.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ internal PmcMetricDescriptor(PreciseMachineCounter counter)
2020
public string NumberFormat => "N0";
2121
public UnitType UnitType => UnitType.Dimensionless;
2222
public string Unit => "Count";
23+
public int PriorityInCategory => 0;
2324
}
2425
}

src/BenchmarkDotNet/Diagnosers/ThreadingDiagnoser.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ private class CompletedWorkItemCountMetricDescriptor : IMetricDescriptor
6161
public UnitType UnitType => UnitType.Dimensionless;
6262
public string Unit => "Count";
6363
public bool TheGreaterTheBetter => false;
64+
public int PriorityInCategory => 0;
6465
}
6566

6667
private class LockContentionCountMetricDescriptor : IMetricDescriptor
@@ -74,6 +75,7 @@ private class LockContentionCountMetricDescriptor : IMetricDescriptor
7475
public UnitType UnitType => UnitType.Dimensionless;
7576
public string Unit => "Count";
7677
public bool TheGreaterTheBetter => false;
78+
public int PriorityInCategory => 0;
7779
}
7880
}
7981
}

src/BenchmarkDotNet/Disassemblers/DisassemblyDiagnoser.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ private class NativeCodeSizeMetricDescriptor : IMetricDescriptor
169169
public UnitType UnitType => UnitType.Size;
170170
public string Unit => SizeUnit.B.Name;
171171
public bool TheGreaterTheBetter => false;
172+
public int PriorityInCategory => 0;
172173
}
173174
}
174175
}

src/BenchmarkDotNet/Reports/Metric.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public interface IMetricDescriptor
3232
[PublicAPI] string Unit { get; }
3333

3434
[PublicAPI] bool TheGreaterTheBetter { get; }
35+
36+
[PublicAPI] int PriorityInCategory { get; }
3537
}
3638

3739
public class MetricDescriptorEqualityComparer : EqualityComparer<IMetricDescriptor>

0 commit comments

Comments
 (0)