include MemoryDiagnoser's results in CsvMeasurementsExporter, fixes #309
This commit is contained in:
Родитель
f1f2317daf
Коммит
6300a29a11
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using BenchmarkDotNet.Characteristics;
|
using BenchmarkDotNet.Characteristics;
|
||||||
|
using BenchmarkDotNet.Diagnosers;
|
||||||
using BenchmarkDotNet.Extensions;
|
using BenchmarkDotNet.Extensions;
|
||||||
using BenchmarkDotNet.Jobs;
|
using BenchmarkDotNet.Jobs;
|
||||||
using BenchmarkDotNet.Loggers;
|
using BenchmarkDotNet.Loggers;
|
||||||
|
@ -11,26 +12,68 @@ namespace BenchmarkDotNet.Exporters.Csv
|
||||||
{
|
{
|
||||||
public class CsvMeasurementsExporter : ExporterBase
|
public class CsvMeasurementsExporter : ExporterBase
|
||||||
{
|
{
|
||||||
|
public static readonly CsvMeasurementsExporter Default = new CsvMeasurementsExporter(CsvSeparator.CurrentCulture);
|
||||||
|
|
||||||
private static readonly CharacteristicPresenter Presenter = CharacteristicPresenter.SummaryPresenter;
|
private static readonly CharacteristicPresenter Presenter = CharacteristicPresenter.SummaryPresenter;
|
||||||
|
|
||||||
protected override string FileExtension => "csv";
|
private static readonly Lazy<MeasurementColumn[]> Columns = new Lazy<MeasurementColumn[]>(BuildColumns);
|
||||||
protected override string FileCaption => "measurements";
|
|
||||||
|
|
||||||
public string Separator { get; }
|
|
||||||
|
|
||||||
public static readonly CsvMeasurementsExporter Default = new CsvMeasurementsExporter(CsvSeparator.CurrentCulture);
|
|
||||||
|
|
||||||
public CsvMeasurementsExporter(CsvSeparator separator)
|
public CsvMeasurementsExporter(CsvSeparator separator)
|
||||||
{
|
{
|
||||||
Separator = separator.ToRealSeparator();
|
Separator = separator.ToRealSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Separator { get; }
|
||||||
|
|
||||||
|
protected override string FileExtension => "csv";
|
||||||
|
|
||||||
|
protected override string FileCaption => "measurements";
|
||||||
|
|
||||||
|
public static Job[] GetJobs(Summary summary) => summary.Benchmarks.Select(b => b.Job).ToArray();
|
||||||
|
|
||||||
|
public override void ExportToLog(Summary summary, ILogger logger)
|
||||||
|
{
|
||||||
|
var columns = GetColumns(summary);
|
||||||
|
logger.WriteLine(string.Join(Separator, columns.Select(c => CsvHelper.Escape(c.Title))));
|
||||||
|
|
||||||
|
foreach (var report in summary.Reports)
|
||||||
|
{
|
||||||
|
foreach (var measurement in report.AllMeasurements)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < columns.Length; )
|
||||||
|
{
|
||||||
|
logger.Write(CsvHelper.Escape(columns[i].GetValue(summary, report, measurement)));
|
||||||
|
|
||||||
|
if (++i < columns.Length)
|
||||||
|
{
|
||||||
|
logger.Write(Separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.WriteLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MeasurementColumn[] GetColumns(Summary summary)
|
||||||
|
{
|
||||||
|
if (!summary.Config.GetDiagnosers().Contains(MemoryDiagnoser.Default))
|
||||||
|
return Columns.Value;
|
||||||
|
|
||||||
|
var columns = new List<MeasurementColumn>(Columns.Value);
|
||||||
|
columns.Add(new MeasurementColumn("Gen 0", (_, report, __) => report.GcStats.Gen0Collections.ToString()));
|
||||||
|
columns.Add(new MeasurementColumn("Gen 1", (_, report, __) => report.GcStats.Gen1Collections.ToString()));
|
||||||
|
columns.Add(new MeasurementColumn("Gen 2", (_, report, __) => report.GcStats.Gen2Collections.ToString()));
|
||||||
|
columns.Add(new MeasurementColumn("Allocated Bytes", (_, report, __) => report.GcStats.BytesAllocatedPerOperation.ToString()));
|
||||||
|
|
||||||
|
return columns.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
private static MeasurementColumn[] BuildColumns()
|
private static MeasurementColumn[] BuildColumns()
|
||||||
{
|
{
|
||||||
var columns = new List<MeasurementColumn>();
|
var columns = new List<MeasurementColumn>();
|
||||||
|
|
||||||
// Target
|
// Target
|
||||||
columns.Add(new MeasurementColumn("Target", (summary, report, m) => report.Benchmark.Target.Type.Name + "." +report.Benchmark.Target.MethodDisplayInfo));
|
columns.Add(new MeasurementColumn("Target", (summary, report, m) => report.Benchmark.Target.Type.Name + "." + report.Benchmark.Target.MethodDisplayInfo));
|
||||||
columns.Add(new MeasurementColumn("Target_Namespace", (summary, report, m) => report.Benchmark.Target.Type.Namespace));
|
columns.Add(new MeasurementColumn("Target_Namespace", (summary, report, m) => report.Benchmark.Target.Type.Namespace));
|
||||||
columns.Add(new MeasurementColumn("Target_Type", (summary, report, m) => report.Benchmark.Target.Type.Name));
|
columns.Add(new MeasurementColumn("Target_Type", (summary, report, m) => report.Benchmark.Target.Type.Name));
|
||||||
columns.Add(new MeasurementColumn("Target_Method", (summary, report, m) => report.Benchmark.Target.MethodDisplayInfo));
|
columns.Add(new MeasurementColumn("Target_Method", (summary, report, m) => report.Benchmark.Target.MethodDisplayInfo));
|
||||||
|
@ -54,9 +97,7 @@ namespace BenchmarkDotNet.Exporters.Csv
|
||||||
return columns.ToArray();
|
return columns.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Lazy<MeasurementColumn[]> lazyColumns = new Lazy<MeasurementColumn[]>(BuildColumns);
|
private struct MeasurementColumn
|
||||||
|
|
||||||
private class MeasurementColumn
|
|
||||||
{
|
{
|
||||||
public string Title { get; }
|
public string Title { get; }
|
||||||
public Func<Summary, BenchmarkReport, Measurement, string> GetValue { get; }
|
public Func<Summary, BenchmarkReport, Measurement, string> GetValue { get; }
|
||||||
|
@ -67,30 +108,5 @@ namespace BenchmarkDotNet.Exporters.Csv
|
||||||
GetValue = getValue;
|
GetValue = getValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ExportToLog(Summary summary, ILogger logger)
|
|
||||||
{
|
|
||||||
var columns = lazyColumns.Value;
|
|
||||||
logger.WriteLine(string.Join(Separator, columns.Select(c => CsvHelper.Escape(c.Title))));
|
|
||||||
|
|
||||||
foreach (var report in summary.Reports)
|
|
||||||
{
|
|
||||||
foreach (var measurement in report.AllMeasurements)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < columns.Length; )
|
|
||||||
{
|
|
||||||
logger.Write(CsvHelper.Escape(columns[i].GetValue(summary, report, measurement)));
|
|
||||||
|
|
||||||
if (++i < columns.Length)
|
|
||||||
{
|
|
||||||
logger.Write(Separator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logger.WriteLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Job[] GetJobs(Summary summary) => summary.Benchmarks.Select(b => b.Job).ToArray();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -161,17 +161,15 @@ namespace BenchmarkDotNet.Running
|
||||||
if (!buildResult.IsBuildSuccess)
|
if (!buildResult.IsBuildSuccess)
|
||||||
return new BenchmarkReport(benchmark, generateResult, buildResult, null, null, default(GcStats));
|
return new BenchmarkReport(benchmark, generateResult, buildResult, null, null, default(GcStats));
|
||||||
|
|
||||||
var executeResults = Execute(logger, benchmark, toolchain, buildResult, config, resolver);
|
var gcStats = default(GcStats);
|
||||||
|
var executeResults = Execute(logger, benchmark, toolchain, buildResult, config, resolver, out gcStats);
|
||||||
|
|
||||||
var runs = new List<Measurement>();
|
var runs = new List<Measurement>();
|
||||||
GcStats gcStats = default(GcStats);
|
|
||||||
for (int index = 0; index < executeResults.Count; index++)
|
for (int index = 0; index < executeResults.Count; index++)
|
||||||
{
|
{
|
||||||
var executeResult = executeResults[index];
|
var executeResult = executeResults[index];
|
||||||
runs.AddRange(executeResult.Data.Select(line => Measurement.Parse(logger, line, index + 1)).Where(r => r.IterationMode != IterationMode.Unknown));
|
runs.AddRange(executeResult.Data.Select(line => Measurement.Parse(logger, line, index + 1)).Where(r => r.IterationMode != IterationMode.Unknown));
|
||||||
|
|
||||||
if (executeResult.Data.Any())
|
|
||||||
gcStats = gcStats + GcStats.Parse(executeResult.Data.Last());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BenchmarkReport(benchmark, generateResult, buildResult, executeResults, runs, gcStats);
|
return new BenchmarkReport(benchmark, generateResult, buildResult, executeResults, runs, gcStats);
|
||||||
|
@ -222,9 +220,10 @@ namespace BenchmarkDotNet.Running
|
||||||
return buildResult;
|
return buildResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<ExecuteResult> Execute(ILogger logger, Benchmark benchmark, IToolchain toolchain, BuildResult buildResult, IConfig config, IResolver resolver)
|
private static List<ExecuteResult> Execute(ILogger logger, Benchmark benchmark, IToolchain toolchain, BuildResult buildResult, IConfig config, IResolver resolver, out GcStats gcStats)
|
||||||
{
|
{
|
||||||
var executeResults = new List<ExecuteResult>();
|
var executeResults = new List<ExecuteResult>();
|
||||||
|
gcStats = default(GcStats);
|
||||||
|
|
||||||
logger.WriteLineInfo("// *** Execute ***");
|
logger.WriteLineInfo("// *** Execute ***");
|
||||||
bool analyzeRunToRunVariance = benchmark.Job.ResolveValue(AccuracyMode.AnalyzeLaunchVarianceCharacteristic, resolver);
|
bool analyzeRunToRunVariance = benchmark.Job.ResolveValue(AccuracyMode.AnalyzeLaunchVarianceCharacteristic, resolver);
|
||||||
|
@ -284,7 +283,7 @@ namespace BenchmarkDotNet.Running
|
||||||
var executeResult = toolchain.Executor.Execute(buildResult, benchmark, logger, resolver, compositeDiagnoser);
|
var executeResult = toolchain.Executor.Execute(buildResult, benchmark, logger, resolver, compositeDiagnoser);
|
||||||
|
|
||||||
var allRuns = executeResult.Data.Select(line => Measurement.Parse(logger, line, 0)).Where(r => r.IterationMode != IterationMode.Unknown).ToList();
|
var allRuns = executeResult.Data.Select(line => Measurement.Parse(logger, line, 0)).Where(r => r.IterationMode != IterationMode.Unknown).ToList();
|
||||||
var gcStats = GcStats.Parse(executeResult.Data.Last());
|
gcStats = GcStats.Parse(executeResult.Data.Last());
|
||||||
var report = new BenchmarkReport(benchmark, null, null, new[] { executeResult }, allRuns, gcStats);
|
var report = new BenchmarkReport(benchmark, null, null, new[] { executeResult }, allRuns, gcStats);
|
||||||
compositeDiagnoser.ProcessResults(benchmark, report);
|
compositeDiagnoser.ProcessResults(benchmark, report);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче