Skip to content

Commit ef16a87

Browse files
committed
Add threshold argument to ZeroMeasurementHelper.
1 parent a6a4625 commit ef16a87

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

src/BenchmarkDotNet/Analysers/ZeroMeasurementHelper.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Perfolizer.Mathematics.SignificanceTesting;
2+
using Perfolizer.Mathematics.Thresholds;
23

34
namespace BenchmarkDotNet.Analysers
45
{
@@ -19,11 +20,11 @@ public static bool CheckZeroMeasurementOneSample(double[] results, double thresh
1920
/// Checks distribution against Zero Measurement hypothesis in case of two samples
2021
/// </summary>
2122
/// <returns>True if measurement is ZeroMeasurement</returns>
22-
public static bool CheckZeroMeasurementTwoSamples(double[] workload, double[] overhead)
23+
public static bool CheckZeroMeasurementTwoSamples(double[] workload, double[] overhead, Threshold threshold = null)
2324
{
2425
if (workload.Length < 3 || overhead.Length < 3)
2526
return false;
26-
return !WelchTest.Instance.IsGreater(workload, overhead).NullHypothesisIsRejected;
27+
return !WelchTest.Instance.IsGreater(workload, overhead, threshold).NullHypothesisIsRejected;
2728
}
2829
}
2930
}

tests/BenchmarkDotNet.IntegrationTests.ManualRunning/ExpectedBenchmarkResultsTests.cs

+15-4
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@
99
using BenchmarkDotNet.Engines;
1010
using BenchmarkDotNet.Extensions;
1111
using BenchmarkDotNet.Jobs;
12+
using BenchmarkDotNet.Portability;
1213
using BenchmarkDotNet.Reports;
1314
using BenchmarkDotNet.Tests.XUnit;
1415
using BenchmarkDotNet.Toolchains.InProcess.Emit;
16+
using Perfolizer.Horology;
17+
using Perfolizer.Mathematics.Thresholds;
1518
using Xunit;
1619
using Xunit.Abstractions;
1720

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

28+
private static readonly TimeInterval FallbackCpuResolutionValue = TimeInterval.FromNanoseconds(0.2d);
29+
2530
public ExpectedBenchmarkResultsTests(ITestOutputHelper output) : base(output) { }
2631

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

114+
var cpuResolution = RuntimeInformation.GetCpuInfo().MaxFrequency?.ToResolution() ?? FallbackCpuResolutionValue;
115+
var threshold = Threshold.Create(ThresholdUnit.Nanoseconds, cpuResolution.Nanoseconds);
116+
109117
foreach (var report in summary.Reports)
110118
{
111119
var workloadMeasurements = report.AllMeasurements.Where(m => m.Is(IterationMode.Workload, IterationStage.Actual)).GetStatistics().WithoutOutliers();
112120
var overheadMeasurements = report.AllMeasurements.Where(m => m.Is(IterationMode.Overhead, IterationStage.Actual)).GetStatistics().WithoutOutliers();
113121

114-
bool isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(workloadMeasurements, overheadMeasurements);
122+
bool isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(workloadMeasurements, overheadMeasurements, threshold);
115123
Assert.True(isZero, $"Actual time was not 0.");
116124

117-
isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(overheadMeasurements, workloadMeasurements);
125+
isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(overheadMeasurements, workloadMeasurements, threshold);
118126
Assert.True(isZero, "Overhead took more time than workload.");
119127

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

170+
var cpuResolution = RuntimeInformation.GetCpuInfo().MaxFrequency?.ToResolution() ?? FallbackCpuResolutionValue;
171+
var threshold = Threshold.Create(ThresholdUnit.Nanoseconds, cpuResolution.Nanoseconds);
172+
162173
foreach (var report in summary.Reports)
163174
{
164175
var workloadMeasurements = report.AllMeasurements.Where(m => m.Is(IterationMode.Workload, IterationStage.Actual)).GetStatistics().WithoutOutliers();
165176
var overheadMeasurements = report.AllMeasurements.Where(m => m.Is(IterationMode.Overhead, IterationStage.Actual)).GetStatistics().WithoutOutliers();
166177

167-
bool isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(workloadMeasurements, overheadMeasurements);
178+
bool isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(workloadMeasurements, overheadMeasurements, threshold);
168179
Assert.False(isZero, $"Actual time was 0.");
169180

170-
isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(overheadMeasurements, workloadMeasurements);
181+
isZero = ZeroMeasurementHelper.CheckZeroMeasurementTwoSamples(overheadMeasurements, workloadMeasurements, threshold);
171182
Assert.True(isZero, "Overhead took more time than workload.");
172183

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

0 commit comments

Comments
 (0)