include MemoryDiagnoser's results in CsvMeasurementsExporter, fixes #309

This commit is contained in:
Adam Sitnik 2016-11-28 15:09:43 +01:00
Родитель f1f2317daf
Коммит 6300a29a11
2 изменённых файлов: 57 добавлений и 42 удалений

Просмотреть файл

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Characteristics;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Extensions;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Loggers;
@ -11,26 +12,68 @@ namespace BenchmarkDotNet.Exporters.Csv
{
public class CsvMeasurementsExporter : ExporterBase
{
public static readonly CsvMeasurementsExporter Default = new CsvMeasurementsExporter(CsvSeparator.CurrentCulture);
private static readonly CharacteristicPresenter Presenter = CharacteristicPresenter.SummaryPresenter;
protected override string FileExtension => "csv";
protected override string FileCaption => "measurements";
public string Separator { get; }
public static readonly CsvMeasurementsExporter Default = new CsvMeasurementsExporter(CsvSeparator.CurrentCulture);
private static readonly Lazy<MeasurementColumn[]> Columns = new Lazy<MeasurementColumn[]>(BuildColumns);
public CsvMeasurementsExporter(CsvSeparator separator)
{
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()
{
var columns = new List<MeasurementColumn>();
// 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_Type", (summary, report, m) => report.Benchmark.Target.Type.Name));
columns.Add(new MeasurementColumn("Target_Method", (summary, report, m) => report.Benchmark.Target.MethodDisplayInfo));
@ -54,9 +97,7 @@ namespace BenchmarkDotNet.Exporters.Csv
return columns.ToArray();
}
private static readonly Lazy<MeasurementColumn[]> lazyColumns = new Lazy<MeasurementColumn[]>(BuildColumns);
private class MeasurementColumn
private struct MeasurementColumn
{
public string Title { get; }
public Func<Summary, BenchmarkReport, Measurement, string> GetValue { get; }
@ -67,30 +108,5 @@ namespace BenchmarkDotNet.Exporters.Csv
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)
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>();
GcStats gcStats = default(GcStats);
for (int index = 0; index < executeResults.Count; index++)
{
var executeResult = executeResults[index];
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);
@ -222,9 +220,10 @@ namespace BenchmarkDotNet.Running
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>();
gcStats = default(GcStats);
logger.WriteLineInfo("// *** Execute ***");
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 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);
compositeDiagnoser.ProcessResults(benchmark, report);