Skip to content

Commit

Permalink
Add threshold argument to ZeroMeasurementHelper.
Browse files Browse the repository at this point in the history
  • Loading branch information
timcassell committed Jul 10, 2023
1 parent a6a4625 commit ef16a87
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
5 changes: 3 additions & 2 deletions src/BenchmarkDotNet/Analysers/ZeroMeasurementHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Perfolizer.Mathematics.SignificanceTesting;
using Perfolizer.Mathematics.Thresholds;

namespace BenchmarkDotNet.Analysers
{
Expand All @@ -19,11 +20,11 @@ public static bool CheckZeroMeasurementOneSample(double[] results, double thresh
/// Checks distribution against Zero Measurement hypothesis in case of two samples
/// </summary>
/// <returns>True if measurement is ZeroMeasurement</returns>
public static bool CheckZeroMeasurementTwoSamples(double[] workload, double[] overhead)
public static bool CheckZeroMeasurementTwoSamples(double[] workload, double[] overhead, Threshold threshold = null)
{
if (workload.Length < 3 || overhead.Length < 3)
return false;
return !WelchTest.Instance.IsGreater(workload, overhead).NullHypothesisIsRejected;
return !WelchTest.Instance.IsGreater(workload, overhead, threshold).NullHypothesisIsRejected;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Extensions;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Portability;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Tests.XUnit;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
using Perfolizer.Horology;
using Perfolizer.Mathematics.Thresholds;
using Xunit;
using Xunit.Abstractions;

Expand All @@ -22,6 +25,8 @@ public class ExpectedBenchmarkResultsTests : BenchmarkTestExecutor
// NativeAot takes a long time to build, so not including it in these tests.
// We also don't test InProcessNoEmitToolchain because it is known to be less accurate than code-gen toolchains.

private static readonly TimeInterval FallbackCpuResolutionValue = TimeInterval.FromNanoseconds(0.2d);

public ExpectedBenchmarkResultsTests(ITestOutputHelper output) : base(output) { }

private static IEnumerable<Type> EmptyBenchmarkTypes() =>
Expand Down Expand Up @@ -106,15 +111,18 @@ private void AssertZeroResults(Type benchmarkType, IConfig config)
.AddDiagnoser(new MemoryDiagnoser(new MemoryDiagnoserConfig(false)))
);

var cpuResolution = RuntimeInformation.GetCpuInfo().MaxFrequency?.ToResolution() ?? FallbackCpuResolutionValue;
var threshold = Threshold.Create(ThresholdUnit.Nanoseconds, cpuResolution.Nanoseconds);

foreach (var report in summary.Reports)
{
var workloadMeasurements = report.AllMeasurements.Where(m => m.Is(IterationMode.Workload, IterationStage.Actual)).GetStatistics().WithoutOutliers();
var overheadMeasurements = report.AllMeasurements.Where(m => m.Is(IterationMode.Overhead, IterationStage.Actual)).GetStatistics().WithoutOutliers();

bool isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(workloadMeasurements, overheadMeasurements);
bool isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(workloadMeasurements, overheadMeasurements, threshold);
Assert.True(isZero, $"Actual time was not 0.");

isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(overheadMeasurements, workloadMeasurements);
isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(overheadMeasurements, workloadMeasurements, threshold);
Assert.True(isZero, "Overhead took more time than workload.");

Assert.True((report.GcStats.GetBytesAllocatedPerOperation(report.BenchmarkCase) ?? 0L) == 0L, "Memory allocations measured above 0.");
Expand Down Expand Up @@ -159,15 +167,18 @@ private void AssertDifferentSizedStructsResults(IConfig config)
.AddDiagnoser(new MemoryDiagnoser(new MemoryDiagnoserConfig(false)))
);

var cpuResolution = RuntimeInformation.GetCpuInfo().MaxFrequency?.ToResolution() ?? FallbackCpuResolutionValue;
var threshold = Threshold.Create(ThresholdUnit.Nanoseconds, cpuResolution.Nanoseconds);

foreach (var report in summary.Reports)
{
var workloadMeasurements = report.AllMeasurements.Where(m => m.Is(IterationMode.Workload, IterationStage.Actual)).GetStatistics().WithoutOutliers();
var overheadMeasurements = report.AllMeasurements.Where(m => m.Is(IterationMode.Overhead, IterationStage.Actual)).GetStatistics().WithoutOutliers();

bool isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(workloadMeasurements, overheadMeasurements);
bool isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(workloadMeasurements, overheadMeasurements, threshold);
Assert.False(isZero, $"Actual time was 0.");

isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(overheadMeasurements, workloadMeasurements);
isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(overheadMeasurements, workloadMeasurements, threshold);
Assert.True(isZero, "Overhead took more time than workload.");

Assert.True((report.GcStats.GetBytesAllocatedPerOperation(report.BenchmarkCase) ?? 0L) == 0L, "Memory allocations measured above 0.");
Expand Down

0 comments on commit ef16a87

Please sign in to comment.