From 40b17d6e8f7e242a3ef137bd8ad5a60e85830cdb Mon Sep 17 00:00:00 2001 From: Mark Plesko Date: Thu, 11 Jul 2024 14:47:50 -0700 Subject: [PATCH 1/5] draft --- .../GC.Infrastructure/Notebooks/Reports.dib | 222 ++++++++++++------ 1 file changed, 145 insertions(+), 77 deletions(-) diff --git a/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib b/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib index 111be377515..a2705bcdae7 100644 --- a/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib +++ b/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib @@ -445,9 +445,11 @@ public class Metric : BaseMetric AxisCountOffset = axisCountOffset; } + private double? BaseExtract(TSource gc) => base.DoExtract(gc); + public double? DoExtract(TSource gc, int count) { - double? value = base.DoExtract(gc); + double? value = BaseExtract(gc); if (value.HasValue) { if (value > Cap) @@ -463,6 +465,7 @@ public class Metric : BaseMetric } private Metric Copy() => new(ExtractFunc, Title, Unit, Cap); + public Metric WithTitle(string title) => new (ExtractFunc, title, Unit, Cap, AxisCountOffset); public Metric WithCap(double cap) => new(ExtractFunc, Title, Unit, cap, AxisCountOffset); public Metric WithOffset(double offset) => new(ExtractFunc, Title, Unit, Cap, offset); @@ -485,6 +488,20 @@ public class Metric : BaseMetric => new(extract: source => aggregation.Func(oldExtract(source).Select(metric.ExtractFunc).Where(NotNull).Select(value => value.Value)), title: $"{aggregation.Title} of {metric.Title}", unit: aggregation.UnitOverride ?? metric.Unit); + + public static Metric operator +(Metric m1, Metric m2) + => new(extract: source => m1.BaseExtract(source) + m2.BaseExtract(source), + title: $"Sum of {m1.Title} and {m2.Title}", + unit: m1.Unit + // ignoring cap/offset for now + ); + + public static Metric operator -(Metric m1, Metric m2) + => new(extract: source => m1.BaseExtract(source) - m2.BaseExtract(source), + title: $"Diff of {m1.Title} and {m2.Title}", + unit: m1.Unit + // ignoring cap/offset for now + ); } public static class Metrics @@ -500,6 +517,22 @@ public static class Metrics public static Metric Promote(Metric metric, Aggregation aggregation) => Metric.Promote(metric, data => data.Runs.Values, aggregation); + public static Metric ToMB(Metric m) + { + double conversion = m.Unit switch + { + "bytes" => 0.000_001, + "MB" => 1, + _ => throw new Exception("Not convertible to MB") + }; + + return new(extract: source => conversion * m.DoExtract(source), + title: m.Title, + unit: "MB" + // Cap/offset handled by original metric + ); + } + public static class X { public static BaseMetric<(string, TraceGC), XValue> GCIndex { get; } = new(pair => new XValue(pair.Item2.Number), "GC Index"); @@ -513,18 +546,44 @@ public static class Metrics public static Metric AllocedSinceLastGCMB = new(gc => gc.AllocedSinceLastGCMB, title: "Allocated", unit: "MB"); // AllocRateMBSec is MB/s but this puts it on same y-axis as plain MB public static Metric AllocRateMBSec = new(gc => gc.AllocRateMBSec, title: "Allocation rate", unit: "MB"); - public static Metric CommittedAfterTotalBookkeeping = new(gc => gc.CommittedUsageAfter.TotalBookkeepingCommitted, title: "Committed Book (after)", unit: "MB"); - public static Metric CommittedAfterInFree = new(gc => gc.CommittedUsageAfter.TotalCommittedInFree, title: "Committed In Free (after)", unit: "MB"); - public static Metric CommittedAfterInGlobalDecommit = new(gc => gc.CommittedUsageAfter.TotalCommittedInGlobalDecommit, title: "Committed In Global Decommit (after)", unit: "MB"); - public static Metric CommittedAfterInGlobalFree = new(gc => gc.CommittedUsageAfter.TotalCommittedInGlobalFree, title: "Committed In Global Free (after)", unit: "MB"); - public static Metric CommittedAfterInUse = new(gc => gc.CommittedUsageAfter.TotalCommittedInUse, title: "Committed In Use (after)", unit: "MB"); + + public static Metric CommittedAfterTotalBookkeeping = new(gc => gc.CommittedUsageAfter.TotalBookkeepingCommitted, title: "Committed Book (after)", unit: "bytes"); + public static Metric CommittedAfterInFree = new(gc => gc.CommittedUsageAfter.TotalCommittedInFree, title: "Committed In Free (after)", unit: "bytes"); + public static Metric CommittedAfterInGlobalDecommit = new(gc => gc.CommittedUsageAfter.TotalCommittedInGlobalDecommit, title: "Committed In Global Decommit (after)", unit: "bytes"); + public static Metric CommittedAfterInGlobalFree = new(gc => gc.CommittedUsageAfter.TotalCommittedInGlobalFree, title: "Committed In Global Free (after)", unit: "bytes"); + public static Metric CommittedAfterInUse = new(gc => gc.CommittedUsageAfter.TotalCommittedInUse, title: "Committed In Use (after)", unit: "bytes"); public static List> CommittedAfterMetrics = ML(CommittedAfterTotalBookkeeping, CommittedAfterInFree, CommittedAfterInGlobalDecommit, CommittedAfterInGlobalFree, CommittedAfterInUse); - public static Metric CommittedBeforeTotalBookkeeping = new(gc => gc.CommittedUsageBefore.TotalBookkeepingCommitted, title: "Committed Book (before)", unit: "MB"); - public static Metric CommittedBeforeInFree = new(gc => gc.CommittedUsageBefore.TotalCommittedInFree, title: "Committed In Free (before)", unit: "MB"); - public static Metric CommittedBeforeInGlobalDecommit = new(gc => gc.CommittedUsageBefore.TotalCommittedInGlobalDecommit, title: "Committed In Global Decommit (before)", unit: "MB"); - public static Metric CommittedBeforeInGlobalFree = new(gc => gc.CommittedUsageBefore.TotalCommittedInGlobalFree, title: "Committed In Global Free (before)", unit: "MB"); - public static Metric CommittedBeforeInUse = new(gc => gc.CommittedUsageBefore.TotalCommittedInUse, title: "Committed In Use (before)", unit: "MB"); + public static Metric CommittedAfterEitherFree = (CommittedAfterInFree + CommittedAfterInGlobalFree).WithTitle("Committed In Either Free (after)"); + public static Metric CommittedAfterFreeOrDecommit = CommittedAfterEitherFree + CommittedAfterInGlobalDecommit; + + public static Metric CommittedBeforeTotalBookkeeping = new(gc => gc.CommittedUsageBefore.TotalBookkeepingCommitted, title: "Committed Book (before)", unit: "bytes"); + public static Metric CommittedBeforeInFree = new(gc => gc.CommittedUsageBefore.TotalCommittedInFree, title: "Committed In Free (before)", unit: "bytes"); + public static Metric CommittedBeforeInGlobalDecommit = new(gc => gc.CommittedUsageBefore.TotalCommittedInGlobalDecommit, title: "Committed In Global Decommit (before)", unit: "bytes"); + public static Metric CommittedBeforeInGlobalFree = new(gc => gc.CommittedUsageBefore.TotalCommittedInGlobalFree, title: "Committed In Global Free (before)", unit: "bytes"); + public static Metric CommittedBeforeInUse = new(gc => gc.CommittedUsageBefore.TotalCommittedInUse, title: "Committed In Use (before)", unit: "bytes"); public static List> CommittedBeforeMetrics = ML(CommittedBeforeTotalBookkeeping, CommittedBeforeInFree, CommittedBeforeInGlobalDecommit, CommittedBeforeInGlobalFree, CommittedBeforeInUse); + public static Metric CommittedBeforeEitherFree = (CommittedBeforeInFree + CommittedBeforeInGlobalFree).WithTitle("Committed In Either Free (before)"); + public static Metric CommittedBeforeFreeOrDecommit = CommittedBeforeEitherFree + CommittedBeforeInGlobalDecommit; + + public static Metric CommittedChangeInGlobalFree = (CommittedAfterInGlobalFree - CommittedBeforeInGlobalFree).WithTitle("Change in Committed In Global Free"); + + private static double? GetTotalCommittedBefore(TraceGC gc) + { + long? total = gc.CommittedUsageBefore?.TotalBookkeepingCommitted + gc.CommittedUsageBefore?.TotalCommittedInFree + gc.CommittedUsageBefore?.TotalCommittedInGlobalDecommit + + gc.CommittedUsageBefore?.TotalCommittedInGlobalFree + gc.CommittedUsageBefore?.TotalCommittedInUse; + if (total.HasValue) return total; + return 1_000_000 * gc.HeapSizeBeforeMB + gc.PerHeapHistories.Select(h => h.ExtraGen0Commit).Sum(); + } + public static Metric TotalCommittedBefore = new(GetTotalCommittedBefore, title: "Total Committed (before)", unit: "bytes"); + private static double? GetTotalCommittedAfter(TraceGC gc) + { + long? total = gc.CommittedUsageAfter?.TotalBookkeepingCommitted + gc.CommittedUsageAfter?.TotalCommittedInFree + gc.CommittedUsageAfter?.TotalCommittedInGlobalDecommit + + gc.CommittedUsageAfter?.TotalCommittedInGlobalFree + gc.CommittedUsageAfter?.TotalCommittedInUse; + if (total.HasValue) return total; + return 1_000_000 * gc.HeapSizeAfterMB + gc.PerHeapHistories.Select(h => h.ExtraGen0Commit).Sum(); + } + public static Metric TotalCommittedAfter = new(GetTotalCommittedAfter, title: "Total Committed (after)", unit: "bytes"); + public static Metric DurationMSec = new(gc => gc.DurationMSec, "Duration", "ms"); public static Metric GCCpuMSec = new(gc => gc.GCCpuMSec, "GC CPU", "ms"); public static Metric Gen0Budget = new(gc => gc.GenBudgetMB(Gens.Gen0), "Gen0 budget", "MB"); @@ -622,7 +681,16 @@ public static class Metrics // TODO: Remaining are less comprehensive public static Metric PauseDuration = new((gc => gc.PauseDurationMSec), "GC pause", "ms"); public static Metric PausePercent = new((gc => gc.PauseTimePercentageSinceLastGC), "GC pause %", "%"); + public static Metric EndOfSegAllocated = new(gc => gc.PerHeapHistories.Sum(p => p.EndOfSegAllocated), title: "EndOfSegAllocated", unit: "?"); + public static Metric ExtraGen0Committed = new(gc => gc.PerHeapHistories.Sum(p => p.ExtraGen0Commit), "Committed - extra gen0", "bytes"); + + public static Metric Heap0Gen0Budget = new(gc => gc.PerHeapHistories[0].GenData[(int) Gens.Gen0].Budget, "H0/Gen0 Budget", "bytes"); + public static Metric Heap0Gen1Budget = new(gc => gc.PerHeapHistories[0].GenData[(int) Gens.Gen1].Budget, "H0/Gen1 Budget", "bytes"); + public static Metric Heap0Gen2Budget = new(gc => gc.PerHeapHistories[0].GenData[(int) Gens.Gen2].Budget, "H0/Gen2 Budget", "bytes"); + public static Metric Heap0GenLargeBudget = new(gc => gc.PerHeapHistories[0].GenData[(int) Gens.GenLargeObj].Budget, "H0/GenLarge Budget", "bytes"); + public static Metric Heap0GenPinnedBudget = new(gc => gc.PerHeapHistories[0].GenData[(int) Gens.GenPinObj].Budget, "H0/GenPin Budget", "bytes"); + public static Metric PauseStack = new(gc => gc.PerHeapMarkTimes.Values.Select(mi => mi.MarkTimes[(int) MarkRootType.MarkStack]).Sum(), "Pause (stack)", "ms"); public static Metric PauseFQ = new(gc => gc.PerHeapMarkTimes.Values.Select(mi => mi.MarkTimes[(int) MarkRootType.MarkFQ]).Sum(), "Pause (FQ)", "ms"); public static Metric PauseHandles = new(gc => gc.PerHeapMarkTimes.Values.Select(mi => mi.MarkTimes[(int) MarkRootType.MarkHandles]).Sum(), "Pause (handles)", "ms"); @@ -751,20 +819,58 @@ public class PrefixSimplifier : NameSimplifier } } +[Flags] +public enum ColorKeys +{ + Run = 0x1, + Config = 0x2, + Benchmark = 0x4, + Iteration = 0x8, + Metric = 0x10, +} + // Some will be null depending on the chart type -record SeriesInfo(Metric Metric, string Run, string Config, ConfigData ConfigData, string Benchmark, int? Iteration, IterationData IterationData); +record SeriesInfo(Metric Metric, string Run, string Config, ConfigData ConfigData, string Benchmark, int? Iteration, IterationData IterationData) +{ + public string GetColorFamilyKey(ColorKeys keys) + { + var items = new List(); + + if ((keys & ColorKeys.Run) == ColorKeys.Run) items.Add(Benchmark); + if ((keys & ColorKeys.Config) == ColorKeys.Config) items.Add(Config); + if ((keys & ColorKeys.Benchmark) == ColorKeys.Benchmark) items.Add(Benchmark); + if ((keys & ColorKeys.Iteration) == ColorKeys.Iteration) items.Add(Iteration?.ToString()); + if ((keys & ColorKeys.Metric) == ColorKeys.Metric) items.Add(Metric.Title); + + return string.Join(", ", items); + } + + public string GetColorFamilyId(ColorKeys keys) => GetColorFamilyKey(~keys); + + public string GetSeriesTitle(bool multipleMetrics, bool includeRunName, bool multipleConfigs, bool multipleBenchmarks, Dictionary configDisplayNames) + { + var items = new List(); + + if (multipleBenchmarks) items.Add(Benchmark); + if (multipleMetrics) items.Add(Metric.Title); + if (includeRunName) items.Add(Run); + if (multipleConfigs) items.Add(configDisplayNames?.GetValueOrDefault(Config) ?? Config); + + string title = string.Join(", ", items.Where(s => !string.IsNullOrEmpty(s))); + if (Iteration.HasValue) title += $"_{Iteration}"; + + return title; + } +} abstract class ChartType { public abstract BaseMetric<(string, TData), XValue> DefaultXMetric { get; } public abstract string DefaultBenchmarkMap(string benchmark); + public abstract ColorKeys DefaultColorKeysToGroup { get; } public abstract IEnumerable> GetSeries(DataManager dataManager, List> metrics, Filter runFilter, Filter configFilter, Filter benchmarkFilter, IntFilter iterationFilter, ConfigIterationFilter configIterationFilter, IEnumerable benchmarkList); - public abstract string GetColorFamilyKey(SeriesInfo info, bool multipleMetrics, bool includeRunName, bool multipleConfigs, - Dictionary configDisplayNames, bool multipleBenchmarks); - public abstract string GetColorFamilyId(SeriesInfo info, bool multipleMetrics); - public abstract string GetSeriesTitle(SeriesInfo info, string colorFamilyKey, bool multipleMetrics); public abstract string GetChartTitle(); public abstract List> GetDataSource(SeriesInfo info, Filter benchmarkFilter, IntFilter iterationFilter, ConfigIterationFilter configIterationFilter, Func dataFilter); @@ -774,6 +880,7 @@ class BenchmarksChartType : ChartType { public override BaseMetric<(string, BenchmarkData), XValue> DefaultXMetric { get; } = Metrics.X.BenchmarkName; public override string DefaultBenchmarkMap(string benchmark) => ""; + public override ColorKeys DefaultColorKeysToGroup => ColorKeys.Metric; public override IEnumerable> GetSeries(DataManager dataManager, List> metrics, Filter runFilter, Filter configFilter, Filter benchmarkFilter, IntFilter iterationFilter, ConfigIterationFilter configIterationFilter, IEnumerable benchmarkList) @@ -790,18 +897,6 @@ class BenchmarksChartType : ChartType } } - public override string GetColorFamilyKey(SeriesInfo info, bool multipleMetrics, bool includeRunName, bool multipleConfigs, - Dictionary configDisplayNames, bool multipleBenchmarks) - { - string runDisplay = includeRunName ? $"{info.Run}, " : ""; - string configDisplay = multipleConfigs ? (configDisplayNames?.GetValueOrDefault(info.Config) ?? info.Config) : ""; - string colorFamilyKey = $"{runDisplay}{configDisplay}"; - return colorFamilyKey; - } - - public override string GetColorFamilyId(SeriesInfo info, bool multipleMetrics) => multipleMetrics ? $"{info.Metric.Title} / " : ""; - public override string GetSeriesTitle(SeriesInfo info, string colorFamilyKey, bool multipleMetrics) => $"{GetColorFamilyId(info, multipleMetrics)}{colorFamilyKey}"; - public override string GetChartTitle() => "Per-benchmark behavior"; public override List> GetDataSource(SeriesInfo info, @@ -818,6 +913,7 @@ class IterationsChartType : ChartType { public override BaseMetric<(string, IterationData), XValue> DefaultXMetric { get; } = Metrics.X.IterationBenchmarkName; public override string DefaultBenchmarkMap(string benchmark) => ""; + public override ColorKeys DefaultColorKeysToGroup => ColorKeys.Iteration | ColorKeys.Metric; public override IEnumerable> GetSeries(DataManager dataManager, List> metrics, Filter runFilter, Filter configFilter, Filter benchmarkFilter, IntFilter iterationFilter, ConfigIterationFilter configIterationFilter, IEnumerable benchmarkList) @@ -834,20 +930,6 @@ class IterationsChartType : ChartType } } - public override string GetColorFamilyKey(SeriesInfo info, bool multipleMetrics, bool includeRunName, bool multipleConfigs, - Dictionary configDisplayNames, bool multipleBenchmarks) - { - string metricDisplay = multipleMetrics ? $"{info.Metric.Title}, " : ""; - string runDisplay = includeRunName ? $"{info.Run}, " : ""; - string configDisplay = multipleConfigs ? (configDisplayNames?.GetValueOrDefault(info.Config) ?? info.Config) : ""; - string colorFamilyKey = $"{metricDisplay}{runDisplay}{configDisplay}"; - - return colorFamilyKey; - } - - public override string GetColorFamilyId(SeriesInfo info, bool multipleMetrics) => $"_{info.Iteration}"; - public override string GetSeriesTitle(SeriesInfo info, string colorFamilyKey, bool multipleMetrics) => $"{colorFamilyKey}{GetColorFamilyId(info, multipleMetrics)}"; - public override string GetChartTitle() => "Per-iteration behavior"; public override List> GetDataSource(SeriesInfo info, @@ -871,6 +953,7 @@ class TraceGCChartType : ChartType { public override BaseMetric<(string, TraceGC), XValue> DefaultXMetric { get; } = Metrics.X.GCIndex; public override string DefaultBenchmarkMap(string benchmark) => benchmark; + public override ColorKeys DefaultColorKeysToGroup => ColorKeys.Iteration | ColorKeys.Config; public override IEnumerable> GetSeries(DataManager dataManager, List> metrics, Filter runFilter, Filter configFilter, Filter benchmarkFilter, IntFilter iterationFilter, ConfigIterationFilter configIterationFilter, IEnumerable benchmarkList) @@ -888,21 +971,6 @@ class TraceGCChartType : ChartType } } - public override string GetColorFamilyKey(SeriesInfo info, bool multipleMetrics, bool includeRunName, bool multipleConfigs, - Dictionary configDisplayNames, bool multipleBenchmarks) - { - string benchmarkDisplay = multipleBenchmarks ? $"{info.Benchmark}, " : ""; - string metricDisplay = multipleMetrics ? $"{info.Metric.Title}, " : ""; - string runDisplay = includeRunName ? $"{info.Run}, " : ""; - string configDisplay = multipleConfigs ? (configDisplayNames?.GetValueOrDefault(info.Config) ?? info.Config) : ""; - string colorFamilyKey = $"{benchmarkDisplay}{metricDisplay}{runDisplay}{configDisplay}"; - - return colorFamilyKey; - } - - public override string GetColorFamilyId(SeriesInfo info, bool multipleMetrics) => $"_{info.Iteration}"; - public override string GetSeriesTitle(SeriesInfo info, string colorFamilyKey, bool multipleMetrics) => $"{colorFamilyKey}{GetColorFamilyId(info, multipleMetrics)}"; - public override string GetChartTitle() => "Per-run behavior"; public override List> GetDataSource(SeriesInfo info, @@ -1417,7 +1485,7 @@ TResult ChartInternal(DataPresenter presenter, ChartTyp Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, TData), XValue> xMetric = null, XArrangement xArrangement = null, - NameSimplifier configNameSimplifier = null, bool includeRunName = false, + ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) { runFilter = runFilter ?? Filter.All; @@ -1429,6 +1497,7 @@ TResult ChartInternal(DataPresenter presenter, ChartTyp benchmarkMap = benchmarkMap ?? chartType.DefaultBenchmarkMap; xMetric = xMetric ?? chartType.DefaultXMetric; xArrangement = xArrangement ?? XArrangements.Default; + ColorKeys colorKeys = colorKeysToGroup ?? chartType.DefaultColorKeysToGroup; presenter.Clear(); presenter.Debug = debug; @@ -1495,9 +1564,7 @@ TResult ChartInternal(DataPresenter presenter, ChartTyp chartType.GetSeries(dataManager, metrics, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, benchmarkList: benchmarkList)) { - string colorFamilyKey = chartType.GetColorFamilyKey(info, multipleMetrics: metrics.Count > 1, includeRunName: includeRunName, multipleConfigs: configs.Count > 1, - configDisplayNames: configDisplayNames, multipleBenchmarks: benchmarkList.Count > 1); - + string colorFamilyKey = info.GetColorFamilyKey(colorKeys); colorGroups[colorFamilyKey] = colorGroups.GetValueOrDefault(colorFamilyKey, 0) + 1; } @@ -1526,9 +1593,9 @@ TResult ChartInternal(DataPresenter presenter, ChartTyp chartType.GetSeries(dataManager, metrics, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, benchmarkList: benchmarkList).WithIndex()) { - string colorFamilyKey = chartType.GetColorFamilyKey(info, multipleMetrics: metrics.Count > 1, includeRunName: includeRunName, multipleConfigs: configs.Count > 1, - configDisplayNames: configDisplayNames, multipleBenchmarks: benchmarkList.Count > 1); - string seriesTitle = chartType.GetSeriesTitle(info, colorFamilyKey, metrics.Count > 1); + string seriesTitle = info.GetSeriesTitle(multipleMetrics: metrics.Count > 1, includeRunName: includeRunName, multipleConfigs: configs.Count > 1, + multipleBenchmarks: benchmarkList.Count > 1, configDisplayNames: configDisplayNames); + if (debug) Console.Write($"series title: {seriesTitle}, "); List> dataSource; @@ -1599,7 +1666,8 @@ TResult ChartInternal(DataPresenter presenter, ChartTyp continue; } - string colorFamilyId = chartType.GetColorFamilyId(info, multipleMetrics: metrics.Count > 1); + string colorFamilyKey = info.GetColorFamilyKey(colorKeys); + string colorFamilyId = info.GetColorFamilyId(colorKeys); presenter.AddSeries(title: seriesTitle, unit: info.Metric.Unit, colorFamilyKey: colorFamilyKey, colorFamilyId: colorFamilyId, data: data); } @@ -1700,81 +1768,81 @@ List ChartBenchmarks(DataManager dataManager, List dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, BenchmarkData), XValue> xMetric = null, XArrangement xArrangement = null, - NameSimplifier configNameSimplifier = null, bool includeRunName = false, + ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) => ChartInternal(new ChartPresenter(scatterMode: null), new BenchmarksChartType(), dataManager, metrics, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, benchmarkMap: benchmarkMap, xMetric: xMetric, xArrangement: xArrangement, - configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, + colorKeysToGroup: colorKeysToGroup, configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, display: display, debug: debug); List ChartBenchmarks(DataManager dataManager, Metric metric, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, BenchmarkData), XValue> xMetric = null, XArrangement xArrangement = null, - NameSimplifier configNameSimplifier = null, bool includeRunName = false, + ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) => ChartBenchmarks(dataManager, ML(metric), runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, benchmarkMap: benchmarkMap, xMetric: xMetric, xArrangement: xArrangement, - configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, + colorKeysToGroup: colorKeysToGroup, configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, display: display, debug: debug); List ChartIterations(DataManager dataManager, List> metrics, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, IterationData), XValue> xMetric = null, XArrangement xArrangement = null, - NameSimplifier configNameSimplifier = null, bool includeRunName = false, + ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) => ChartInternal(new ChartPresenter(scatterMode: "markers"), new IterationsChartType(), dataManager, metrics, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, benchmarkMap: benchmarkMap, xMetric: xMetric, xArrangement: xArrangement, - configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, + colorKeysToGroup: colorKeysToGroup, configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, display: display, debug: debug); List ChartIterations(DataManager dataManager, Metric metric, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, IterationData), XValue> xMetric = null, XArrangement xArrangement = null, - NameSimplifier configNameSimplifier = null, bool includeRunName = false, + ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) => ChartIterations(dataManager, ML(metric), runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, benchmarkMap: benchmarkMap, xMetric: xMetric, xArrangement: xArrangement, - configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, + colorKeysToGroup: colorKeysToGroup, configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, display: display, debug: debug); List ChartGCData(DataManager dataManager, List> metrics, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, TraceGC), XValue> xMetric = null, XArrangement xArrangement = null, - NameSimplifier configNameSimplifier = null, bool includeRunName = false, + ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) => ChartInternal(new ChartPresenter(scatterMode: null), new TraceGCChartType(), dataManager, metrics, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, benchmarkMap: benchmarkMap, xMetric: xMetric, xArrangement: xArrangement, - configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, + colorKeysToGroup: colorKeysToGroup, configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, display: display, debug: debug); List ChartGCData(DataManager dataManager, Metric metric, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, TraceGC), XValue> xMetric = null, XArrangement xArrangement = null, - NameSimplifier configNameSimplifier = null, bool includeRunName = false, + ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) => ChartGCData(dataManager, ML(metric), runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, benchmarkMap: benchmarkMap, xMetric: xMetric, xArrangement: xArrangement, - configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, + colorKeysToGroup: colorKeysToGroup, configNameSimplifier: configNameSimplifier, includeRunName: includeRunName, display: display, debug: debug); #!csharp From 9fa6b5c818c27fdcc3a8d7e551d420d33dcea1c1 Mon Sep 17 00:00:00 2001 From: Mark Plesko Date: Fri, 9 Aug 2024 16:32:22 -0700 Subject: [PATCH 2/5] undo some metrics examples --- .../GC.Infrastructure/Notebooks/Reports.dib | 90 +++---------------- 1 file changed, 11 insertions(+), 79 deletions(-) diff --git a/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib b/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib index a2705bcdae7..d95aabbaf62 100644 --- a/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib +++ b/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib @@ -445,11 +445,9 @@ public class Metric : BaseMetric AxisCountOffset = axisCountOffset; } - private double? BaseExtract(TSource gc) => base.DoExtract(gc); - public double? DoExtract(TSource gc, int count) { - double? value = BaseExtract(gc); + double? value = base.DoExtract(gc); if (value.HasValue) { if (value > Cap) @@ -465,7 +463,6 @@ public class Metric : BaseMetric } private Metric Copy() => new(ExtractFunc, Title, Unit, Cap); - public Metric WithTitle(string title) => new (ExtractFunc, title, Unit, Cap, AxisCountOffset); public Metric WithCap(double cap) => new(ExtractFunc, Title, Unit, cap, AxisCountOffset); public Metric WithOffset(double offset) => new(ExtractFunc, Title, Unit, Cap, offset); @@ -488,20 +485,6 @@ public class Metric : BaseMetric => new(extract: source => aggregation.Func(oldExtract(source).Select(metric.ExtractFunc).Where(NotNull).Select(value => value.Value)), title: $"{aggregation.Title} of {metric.Title}", unit: aggregation.UnitOverride ?? metric.Unit); - - public static Metric operator +(Metric m1, Metric m2) - => new(extract: source => m1.BaseExtract(source) + m2.BaseExtract(source), - title: $"Sum of {m1.Title} and {m2.Title}", - unit: m1.Unit - // ignoring cap/offset for now - ); - - public static Metric operator -(Metric m1, Metric m2) - => new(extract: source => m1.BaseExtract(source) - m2.BaseExtract(source), - title: $"Diff of {m1.Title} and {m2.Title}", - unit: m1.Unit - // ignoring cap/offset for now - ); } public static class Metrics @@ -517,22 +500,6 @@ public static class Metrics public static Metric Promote(Metric metric, Aggregation aggregation) => Metric.Promote(metric, data => data.Runs.Values, aggregation); - public static Metric ToMB(Metric m) - { - double conversion = m.Unit switch - { - "bytes" => 0.000_001, - "MB" => 1, - _ => throw new Exception("Not convertible to MB") - }; - - return new(extract: source => conversion * m.DoExtract(source), - title: m.Title, - unit: "MB" - // Cap/offset handled by original metric - ); - } - public static class X { public static BaseMetric<(string, TraceGC), XValue> GCIndex { get; } = new(pair => new XValue(pair.Item2.Number), "GC Index"); @@ -546,44 +513,18 @@ public static class Metrics public static Metric AllocedSinceLastGCMB = new(gc => gc.AllocedSinceLastGCMB, title: "Allocated", unit: "MB"); // AllocRateMBSec is MB/s but this puts it on same y-axis as plain MB public static Metric AllocRateMBSec = new(gc => gc.AllocRateMBSec, title: "Allocation rate", unit: "MB"); - - public static Metric CommittedAfterTotalBookkeeping = new(gc => gc.CommittedUsageAfter.TotalBookkeepingCommitted, title: "Committed Book (after)", unit: "bytes"); - public static Metric CommittedAfterInFree = new(gc => gc.CommittedUsageAfter.TotalCommittedInFree, title: "Committed In Free (after)", unit: "bytes"); - public static Metric CommittedAfterInGlobalDecommit = new(gc => gc.CommittedUsageAfter.TotalCommittedInGlobalDecommit, title: "Committed In Global Decommit (after)", unit: "bytes"); - public static Metric CommittedAfterInGlobalFree = new(gc => gc.CommittedUsageAfter.TotalCommittedInGlobalFree, title: "Committed In Global Free (after)", unit: "bytes"); - public static Metric CommittedAfterInUse = new(gc => gc.CommittedUsageAfter.TotalCommittedInUse, title: "Committed In Use (after)", unit: "bytes"); + public static Metric CommittedAfterTotalBookkeeping = new(gc => gc.CommittedUsageAfter.TotalBookkeepingCommitted, title: "Committed Book (after)", unit: "MB"); + public static Metric CommittedAfterInFree = new(gc => gc.CommittedUsageAfter.TotalCommittedInFree, title: "Committed In Free (after)", unit: "MB"); + public static Metric CommittedAfterInGlobalDecommit = new(gc => gc.CommittedUsageAfter.TotalCommittedInGlobalDecommit, title: "Committed In Global Decommit (after)", unit: "MB"); + public static Metric CommittedAfterInGlobalFree = new(gc => gc.CommittedUsageAfter.TotalCommittedInGlobalFree, title: "Committed In Global Free (after)", unit: "MB"); + public static Metric CommittedAfterInUse = new(gc => gc.CommittedUsageAfter.TotalCommittedInUse, title: "Committed In Use (after)", unit: "MB"); public static List> CommittedAfterMetrics = ML(CommittedAfterTotalBookkeeping, CommittedAfterInFree, CommittedAfterInGlobalDecommit, CommittedAfterInGlobalFree, CommittedAfterInUse); - public static Metric CommittedAfterEitherFree = (CommittedAfterInFree + CommittedAfterInGlobalFree).WithTitle("Committed In Either Free (after)"); - public static Metric CommittedAfterFreeOrDecommit = CommittedAfterEitherFree + CommittedAfterInGlobalDecommit; - - public static Metric CommittedBeforeTotalBookkeeping = new(gc => gc.CommittedUsageBefore.TotalBookkeepingCommitted, title: "Committed Book (before)", unit: "bytes"); - public static Metric CommittedBeforeInFree = new(gc => gc.CommittedUsageBefore.TotalCommittedInFree, title: "Committed In Free (before)", unit: "bytes"); - public static Metric CommittedBeforeInGlobalDecommit = new(gc => gc.CommittedUsageBefore.TotalCommittedInGlobalDecommit, title: "Committed In Global Decommit (before)", unit: "bytes"); - public static Metric CommittedBeforeInGlobalFree = new(gc => gc.CommittedUsageBefore.TotalCommittedInGlobalFree, title: "Committed In Global Free (before)", unit: "bytes"); - public static Metric CommittedBeforeInUse = new(gc => gc.CommittedUsageBefore.TotalCommittedInUse, title: "Committed In Use (before)", unit: "bytes"); + public static Metric CommittedBeforeTotalBookkeeping = new(gc => gc.CommittedUsageBefore.TotalBookkeepingCommitted, title: "Committed Book (before)", unit: "MB"); + public static Metric CommittedBeforeInFree = new(gc => gc.CommittedUsageBefore.TotalCommittedInFree, title: "Committed In Free (before)", unit: "MB"); + public static Metric CommittedBeforeInGlobalDecommit = new(gc => gc.CommittedUsageBefore.TotalCommittedInGlobalDecommit, title: "Committed In Global Decommit (before)", unit: "MB"); + public static Metric CommittedBeforeInGlobalFree = new(gc => gc.CommittedUsageBefore.TotalCommittedInGlobalFree, title: "Committed In Global Free (before)", unit: "MB"); + public static Metric CommittedBeforeInUse = new(gc => gc.CommittedUsageBefore.TotalCommittedInUse, title: "Committed In Use (before)", unit: "MB"); public static List> CommittedBeforeMetrics = ML(CommittedBeforeTotalBookkeeping, CommittedBeforeInFree, CommittedBeforeInGlobalDecommit, CommittedBeforeInGlobalFree, CommittedBeforeInUse); - public static Metric CommittedBeforeEitherFree = (CommittedBeforeInFree + CommittedBeforeInGlobalFree).WithTitle("Committed In Either Free (before)"); - public static Metric CommittedBeforeFreeOrDecommit = CommittedBeforeEitherFree + CommittedBeforeInGlobalDecommit; - - public static Metric CommittedChangeInGlobalFree = (CommittedAfterInGlobalFree - CommittedBeforeInGlobalFree).WithTitle("Change in Committed In Global Free"); - - private static double? GetTotalCommittedBefore(TraceGC gc) - { - long? total = gc.CommittedUsageBefore?.TotalBookkeepingCommitted + gc.CommittedUsageBefore?.TotalCommittedInFree + gc.CommittedUsageBefore?.TotalCommittedInGlobalDecommit - + gc.CommittedUsageBefore?.TotalCommittedInGlobalFree + gc.CommittedUsageBefore?.TotalCommittedInUse; - if (total.HasValue) return total; - return 1_000_000 * gc.HeapSizeBeforeMB + gc.PerHeapHistories.Select(h => h.ExtraGen0Commit).Sum(); - } - public static Metric TotalCommittedBefore = new(GetTotalCommittedBefore, title: "Total Committed (before)", unit: "bytes"); - private static double? GetTotalCommittedAfter(TraceGC gc) - { - long? total = gc.CommittedUsageAfter?.TotalBookkeepingCommitted + gc.CommittedUsageAfter?.TotalCommittedInFree + gc.CommittedUsageAfter?.TotalCommittedInGlobalDecommit - + gc.CommittedUsageAfter?.TotalCommittedInGlobalFree + gc.CommittedUsageAfter?.TotalCommittedInUse; - if (total.HasValue) return total; - return 1_000_000 * gc.HeapSizeAfterMB + gc.PerHeapHistories.Select(h => h.ExtraGen0Commit).Sum(); - } - public static Metric TotalCommittedAfter = new(GetTotalCommittedAfter, title: "Total Committed (after)", unit: "bytes"); - public static Metric DurationMSec = new(gc => gc.DurationMSec, "Duration", "ms"); public static Metric GCCpuMSec = new(gc => gc.GCCpuMSec, "GC CPU", "ms"); public static Metric Gen0Budget = new(gc => gc.GenBudgetMB(Gens.Gen0), "Gen0 budget", "MB"); @@ -681,16 +622,7 @@ public static class Metrics // TODO: Remaining are less comprehensive public static Metric PauseDuration = new((gc => gc.PauseDurationMSec), "GC pause", "ms"); public static Metric PausePercent = new((gc => gc.PauseTimePercentageSinceLastGC), "GC pause %", "%"); - public static Metric EndOfSegAllocated = new(gc => gc.PerHeapHistories.Sum(p => p.EndOfSegAllocated), title: "EndOfSegAllocated", unit: "?"); - public static Metric ExtraGen0Committed = new(gc => gc.PerHeapHistories.Sum(p => p.ExtraGen0Commit), "Committed - extra gen0", "bytes"); - - public static Metric Heap0Gen0Budget = new(gc => gc.PerHeapHistories[0].GenData[(int) Gens.Gen0].Budget, "H0/Gen0 Budget", "bytes"); - public static Metric Heap0Gen1Budget = new(gc => gc.PerHeapHistories[0].GenData[(int) Gens.Gen1].Budget, "H0/Gen1 Budget", "bytes"); - public static Metric Heap0Gen2Budget = new(gc => gc.PerHeapHistories[0].GenData[(int) Gens.Gen2].Budget, "H0/Gen2 Budget", "bytes"); - public static Metric Heap0GenLargeBudget = new(gc => gc.PerHeapHistories[0].GenData[(int) Gens.GenLargeObj].Budget, "H0/GenLarge Budget", "bytes"); - public static Metric Heap0GenPinnedBudget = new(gc => gc.PerHeapHistories[0].GenData[(int) Gens.GenPinObj].Budget, "H0/GenPin Budget", "bytes"); - public static Metric PauseStack = new(gc => gc.PerHeapMarkTimes.Values.Select(mi => mi.MarkTimes[(int) MarkRootType.MarkStack]).Sum(), "Pause (stack)", "ms"); public static Metric PauseFQ = new(gc => gc.PerHeapMarkTimes.Values.Select(mi => mi.MarkTimes[(int) MarkRootType.MarkFQ]).Sum(), "Pause (FQ)", "ms"); public static Metric PauseHandles = new(gc => gc.PerHeapMarkTimes.Values.Select(mi => mi.MarkTimes[(int) MarkRootType.MarkHandles]).Sum(), "Pause (handles)", "ms"); From 691fedef84ece1f2cef3925c0405d88c848d8b9f Mon Sep 17 00:00:00 2001 From: Mark Plesko Date: Thu, 1 Aug 2024 12:40:10 -0700 Subject: [PATCH 3/5] fix for colors --- src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib b/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib index d95aabbaf62..dd6bc806d20 100644 --- a/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib +++ b/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib @@ -764,7 +764,9 @@ public enum ColorKeys // Some will be null depending on the chart type record SeriesInfo(Metric Metric, string Run, string Config, ConfigData ConfigData, string Benchmark, int? Iteration, IterationData IterationData) { - public string GetColorFamilyKey(ColorKeys keys) + public string GetColorFamilyKey(ColorKeys keys) => GetColorFamilyId(~keys); + + public string GetColorFamilyId(ColorKeys keys) { var items = new List(); @@ -777,8 +779,6 @@ record SeriesInfo(Metric Metric, string Run, string Config, Config return string.Join(", ", items); } - public string GetColorFamilyId(ColorKeys keys) => GetColorFamilyKey(~keys); - public string GetSeriesTitle(bool multipleMetrics, bool includeRunName, bool multipleConfigs, bool multipleBenchmarks, Dictionary configDisplayNames) { var items = new List(); @@ -845,7 +845,7 @@ class IterationsChartType : ChartType { public override BaseMetric<(string, IterationData), XValue> DefaultXMetric { get; } = Metrics.X.IterationBenchmarkName; public override string DefaultBenchmarkMap(string benchmark) => ""; - public override ColorKeys DefaultColorKeysToGroup => ColorKeys.Iteration | ColorKeys.Metric; + public override ColorKeys DefaultColorKeysToGroup => ColorKeys.Iteration; public override IEnumerable> GetSeries(DataManager dataManager, List> metrics, Filter runFilter, Filter configFilter, Filter benchmarkFilter, IntFilter iterationFilter, ConfigIterationFilter configIterationFilter, IEnumerable benchmarkList) From 1e62cde22a79d0f26897c396656279b34f60b1bb Mon Sep 17 00:00:00 2001 From: Mark Plesko Date: Fri, 9 Aug 2024 15:55:13 -0700 Subject: [PATCH 4/5] change a default --- src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib b/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib index dd6bc806d20..9cd6b073109 100644 --- a/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib +++ b/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib @@ -885,7 +885,7 @@ class TraceGCChartType : ChartType { public override BaseMetric<(string, TraceGC), XValue> DefaultXMetric { get; } = Metrics.X.GCIndex; public override string DefaultBenchmarkMap(string benchmark) => benchmark; - public override ColorKeys DefaultColorKeysToGroup => ColorKeys.Iteration | ColorKeys.Config; + public override ColorKeys DefaultColorKeysToGroup => ColorKeys.Iteration; public override IEnumerable> GetSeries(DataManager dataManager, List> metrics, Filter runFilter, Filter configFilter, Filter benchmarkFilter, IntFilter iterationFilter, ConfigIterationFilter configIterationFilter, IEnumerable benchmarkList) From 283a73b1272af21b27d60c019ae303077e197ebb Mon Sep 17 00:00:00 2001 From: Mark Plesko Date: Fri, 9 Aug 2024 16:01:20 -0700 Subject: [PATCH 5/5] scattermode, width, debug --- .../GC.Infrastructure/Notebooks/Reports.dib | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib b/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib index 9cd6b073109..2fb77302dcf 100644 --- a/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib +++ b/src/benchmarks/gc/GC.Infrastructure/Notebooks/Reports.dib @@ -1026,7 +1026,8 @@ public abstract class DataPresenter { public bool Debug; - public abstract void Clear(); + // Must be called to clear state before each presentation + public virtual void Clear() => Debug = false; // true if ok public abstract bool PrepareUnits(IEnumerable units); @@ -1053,7 +1054,7 @@ public abstract class TextPresenter : DataPresenter>> private record Table(string title, string xlabel, List series); private List> _result = new(); - public override void Clear() => _result.Clear(); + public override void Clear() { base.Clear(); _result.Clear(); } // true if ok public override bool PrepareUnits(IEnumerable units) => true; @@ -1328,16 +1329,18 @@ public class CsvPresenter : TextPresenter public class ChartPresenter : DataPresenter> { private string _scatterMode; + private int? _width; private List _uniqueUnits; private ColorProvider _colorProvider; private List _charts = new(); - public ChartPresenter(string scatterMode = null) + public ChartPresenter(string scatterMode = null, int? width = null) { _scatterMode = scatterMode; + _width = width; } - public override void Clear() => _charts.Clear(); + public override void Clear() { base.Clear(); _charts.Clear(); } public override bool PrepareUnits(IEnumerable units) { @@ -1384,6 +1387,8 @@ public class ChartPresenter : DataPresenter> // margin = new Margin() { r = 123 }, }; + if (_width.HasValue) _layout.width = _width.Value; + if (_uniqueUnits.Count > 1) { _layout.yaxis2 = new Yaxis { title = _uniqueUnits[1], side = "right", overlaying = "y" }; @@ -1697,12 +1702,13 @@ List> TableGCData(DataManager dataManager, Metric metric, display: display, debug: debug); List ChartBenchmarks(DataManager dataManager, List> metrics, + string scatterMode = null, int? width = null, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, BenchmarkData), XValue> xMetric = null, XArrangement xArrangement = null, ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) - => ChartInternal(new ChartPresenter(scatterMode: null), new BenchmarksChartType(), + => ChartInternal(new ChartPresenter(scatterMode: scatterMode, width: width), new BenchmarksChartType(), dataManager, metrics, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, @@ -1711,12 +1717,14 @@ List ChartBenchmarks(DataManager dataManager, List ChartBenchmarks(DataManager dataManager, Metric metric, + string scatterMode = null, int? width = null, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, BenchmarkData), XValue> xMetric = null, XArrangement xArrangement = null, ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) => ChartBenchmarks(dataManager, ML(metric), + scatterMode: scatterMode, width: width, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, benchmarkMap: benchmarkMap, xMetric: xMetric, xArrangement: xArrangement, @@ -1724,12 +1732,13 @@ List ChartBenchmarks(DataManager dataManager, Metric display: display, debug: debug); List ChartIterations(DataManager dataManager, List> metrics, + string scatterMode = "markers", int? width = null, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, IterationData), XValue> xMetric = null, XArrangement xArrangement = null, ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) - => ChartInternal(new ChartPresenter(scatterMode: "markers"), new IterationsChartType(), + => ChartInternal(new ChartPresenter(scatterMode: scatterMode, width: width), new IterationsChartType(), dataManager, metrics, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, @@ -1738,12 +1747,14 @@ List ChartIterations(DataManager dataManager, List ChartIterations(DataManager dataManager, Metric metric, + string scatterMode = "markers", int? width = null, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, IterationData), XValue> xMetric = null, XArrangement xArrangement = null, ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) => ChartIterations(dataManager, ML(metric), + scatterMode: scatterMode, width: width, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, benchmarkMap: benchmarkMap, xMetric: xMetric, xArrangement: xArrangement, @@ -1751,12 +1762,13 @@ List ChartIterations(DataManager dataManager, Metric display: display, debug: debug); List ChartGCData(DataManager dataManager, List> metrics, + string scatterMode = null, int? width = null, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, TraceGC), XValue> xMetric = null, XArrangement xArrangement = null, ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) - => ChartInternal(new ChartPresenter(scatterMode: null), new TraceGCChartType(), + => ChartInternal(new ChartPresenter(scatterMode: scatterMode, width: width), new TraceGCChartType(), dataManager, metrics, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, @@ -1765,12 +1777,14 @@ List ChartGCData(DataManager dataManager, List> met display: display, debug: debug); List ChartGCData(DataManager dataManager, Metric metric, + string scatterMode = null, int? width = null, Filter runFilter = null, Filter configFilter = null, Filter benchmarkFilter = null, IntFilter iterationFilter = null, ConfigIterationFilter configIterationFilter = null, Func dataFilter = null, Func benchmarkMap = null, BaseMetric<(string, TraceGC), XValue> xMetric = null, XArrangement xArrangement = null, ColorKeys? colorKeysToGroup = null, NameSimplifier configNameSimplifier = null, bool includeRunName = false, bool display = true, bool debug = false) => ChartGCData(dataManager, ML(metric), + scatterMode: scatterMode, width: width, runFilter: runFilter, configFilter: configFilter, benchmarkFilter: benchmarkFilter, iterationFilter: iterationFilter, configIterationFilter: configIterationFilter, dataFilter: dataFilter, benchmarkMap: benchmarkMap, xMetric: xMetric, xArrangement: xArrangement,