Skip to content

Commit

Permalink
Add precision to Scaled Column (#590)
Browse files Browse the repository at this point in the history
Add precision to Scaled Column
  • Loading branch information
Christopher Gozdziewski authored and AndreyAkinshin committed Nov 25, 2017
1 parent 15d7238 commit 696f899
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/BenchmarkDotNet.Core/Columns/BaselineScaledColumn.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public string GetValue(Summary summary, Benchmark benchmark)
switch (Kind)
{
case DiffKind.Mean:
return mean.ToStr("N2");
return IsNonBaselinesPrecise(summary, baselineStat, benchmark) ? mean.ToStr("N3") : mean.ToStr("N2");
case DiffKind.StdDev:
return stdDev.ToStr("N2");
case DiffKind.WelchTTestPValue:
Expand All @@ -87,6 +87,16 @@ public string GetValue(Summary summary, Benchmark benchmark)
}
}

public bool IsNonBaselinesPrecise(Summary summary, Statistics baselineStat, Benchmark benchmark)
{
var nonBaselines = summary.Benchmarks.
Where(b => b.Job.DisplayInfo == benchmark.Job.DisplayInfo).
Where(b => b.Parameters.DisplayInfo == benchmark.Parameters.DisplayInfo).
Where(b => !b.Target.Baseline);

return nonBaselines.Any(x => Statistics.DivMean(summary[x].ResultStatistics, baselineStat) < 0.01);
}

public bool IsAvailable(Summary summary) => summary.Benchmarks.Any(b => b.Target.Baseline);
public bool AlwaysShow => true;
public ColumnCategory Category => ColumnCategory.Baseline;
Expand Down
111 changes: 111 additions & 0 deletions tests/BenchmarkDotNet.Tests/Reports/ScaledPrecisionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Jobs;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Exporters;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Tests.Mocks;
using BenchmarkDotNet.Toolchains;
using BenchmarkDotNet.Toolchains.Results;
using BenchmarkDotNet.Validators;
using Xunit;
using Xunit.Abstractions;

namespace BenchmarkDotNet.Tests.Reports
{
public class ScaledPrecisionTests
{
private readonly ITestOutputHelper output;

public ScaledPrecisionTests(ITestOutputHelper output)
{
this.output = output;
}

[Theory]
[InlineData(new [] { 140, 1, 50 })]
[InlineData(new [] { 40, 1, 20 })]
[InlineData(new [] { 0, 1, 20 })]
// First value is baseline, others are benchmark measurements
public void ScaledPrecisionTestWithBaseline(int[] values)
{
var summary = CreateSummary(values);
var scaledIndex = Array.FindIndex(summary.Table.FullHeader, c => c == "Scaled");

foreach (var row in summary.Table.FullContent)
{
ContainsDecimalPointAndCheckDecimalPrecision(values, row[scaledIndex]);
}
}

private void ContainsDecimalPointAndCheckDecimalPrecision(int[] baseLineValues, string value)
{
if (value.Contains('.'))
{
Assert.Equal((1 / (double)baseLineValues[0]) < 0.01 ? 3 : 2, value.Split('.')[1].Length);
}
}

// TODO: Union this with MockFactory
private Summary CreateSummary(int[] values)
{
var logger = new AccumulationLogger();
var benchmarks = CreateBenchmarks(DefaultConfig.Instance).ToList();
var benchmarkReports = new List<BenchmarkReport>();
for (var x = 0; x < benchmarks.Count; x++)
{
var benchmark = benchmarks[x];
benchmarkReports.Add(CreateReport(benchmark, values[x]));
}

var summary = new Summary(
"MockSummary",
benchmarkReports,
MockFactory.MockHostEnvironmentInfo.Default,
DefaultConfig.Instance,
"",
TimeSpan.FromMinutes(1),
Array.Empty<ValidationError>());
MarkdownExporter.Default.ExportToLog(summary, logger);
output.WriteLine(logger.GetLog());
return summary;
}

private static BenchmarkReport CreateReport(Benchmark benchmark, int measurementValue)
{
var buildResult = BuildResult.Success(GenerateResult.Success(ArtifactsPaths.Empty, Array.Empty<string>()));
var executeResult = new ExecuteResult(true, 0, Array.Empty<string>(), Array.Empty<string>());
var measurements = new List<Measurement>
{
new Measurement(1, IterationMode.Result, 1, 1, measurementValue),
new Measurement(1, IterationMode.Result, 2, 1, measurementValue),
new Measurement(1, IterationMode.Result, 3, 1, measurementValue),
new Measurement(1, IterationMode.Result, 4, 1, measurementValue),
new Measurement(1, IterationMode.Result, 5, 1, measurementValue),
new Measurement(1, IterationMode.Result, 6, 1, measurementValue),
};
return new BenchmarkReport(benchmark, buildResult, buildResult, new List<ExecuteResult> { executeResult }, measurements, default(GcStats));
}

private static IEnumerable<Benchmark> CreateBenchmarks(IConfig config) =>
BenchmarkConverter.TypeToBenchmarks(typeof(MockBenchmarkClass), config).Benchmarks;

[LongRunJob]
public class MockBenchmarkClass
{
[Benchmark(Baseline = true)]
public void Baseline() { }

[Benchmark]
public void Bar() { }

[Benchmark]
public void Foo() { }
}
}
}

0 comments on commit 696f899

Please sign in to comment.