public static void TestCriticalProofContainsWithRoundingBruteForce() { var unitScale = MetricUnitScale.FromEnumValues(typeof(Distance)); var lastRange = MetricValueHelpers.CreateMetricRange(0, 0); int repeats = 0; int increment = 3; for (long i = 0; i < int.MaxValue; i += increment) { // exponential growth as the scale is exponential if (++repeats >= 1000 && increment < int.MaxValue / 10) { repeats = 0; increment *= 2; } lastRange = AssertAssertRoundtripInvariant(i, lastRange, unitScale); } lastRange = MetricValueHelpers.CreateMetricRange(int.MaxValue, int.MaxValue); repeats = 0; increment = int.MaxValue / 200; for (long i = int.MaxValue; i > 0; i -= increment) // reverse order { // logarithmic decrease as the scale is enumerated in reverse order if (++repeats >= 1000 && increment > 10) { repeats = 0; increment /= 2; } lastRange = AssertAssertRoundtripInvariant(i, lastRange, unitScale); } }
public static void TestMetricUnitScaleOnes() { var scale = MetricUnitScale.FromEnumValues(typeof(MetricEnumOk)); var scale2 = MetricUnitScale.FromEnumValues(typeof(MetricEnumOk)); AreSame(scale, scale2); var unit = scale[0]; AreSame(unit, scale[MetricEnumOk.Ones]); AreSame(unit, scale["onES"]); // case-insensitive AreSame(unit, scale[1]); AreSame(unit, scale[2]); AreSame(unit, scale[-2]); AreSame(unit, scale[double.NaN]); AreSame(unit, scale[MetricRange.Empty]); AreSame(unit, scale[new MetricRange(-1, 20000)]); AreSame(unit, scale[new MetricRange(-20000, 1)]); IsFalse(unit.IsEmpty); AreEqual(unit.EnumValue, MetricEnumOk.Ones); AreEqual(unit.AppliesFrom, 1); AreEqual(unit.ScaleCoefficient, 1); AreEqual(unit.RoundingDigits, null); AreEqual(unit.DisplayName, "Ones"); }
public static void TestCreateMetricRange(double min, double max, string unit, double expectedMin, double expectedMax) { var unitScale = MetricUnitScale.FromEnumValues(typeof(Distance)); var metricUnit = unitScale[unit]; var range = MetricValueHelpers.CreateMetricRange(min, max, metricUnit); AreEqual(range.Min, expectedMin); AreEqual(range.Max, expectedMax); }
public static void TestEmptyMetricUnitScale() { var scale = MetricUnitScale.Empty; AreSame(scale, MetricUnitScale.FromEnumValues(null)); var unit = scale[0]; IsTrue(unit.IsEmpty); AreSame(unit, MetricUnit.Empty); AreEqual(unit.EnumValue, null); AreEqual(unit.AppliesFrom, 0); AreEqual(unit.ScaleCoefficient, 1); AreEqual(unit.RoundingDigits, null); }
public static void TestMetricUnitScaleArgValidation() { DoesNotThrow(() => MetricUnitScale.FromEnumValues(typeof(MetricEnumOk))); DoesNotThrow(() => MetricUnitScale.FromEnumValues(typeof(MetricEnumZero))); // DONTTOUCH: called twice to proof that error is cached. Throws <ArgumentException>(() => MetricUnitScale.FromEnumValues(typeof(MetricEnumEmpty))); Throws <ArgumentException>(() => MetricUnitScale.FromEnumValues(typeof(MetricEnumEmpty))); Throws <ArgumentException>(() => MetricUnitScale.FromEnumValues(typeof(MetricEnumNextLessThanPrevious))); Throws <ArgumentException>(() => MetricUnitScale.FromEnumValues(typeof(MetricEnumNextLessThanPreviousAtt))); Throws <ArgumentException>(() => MetricUnitScale.FromEnumValues(typeof(MetricEnumNegativeApplies))); Throws <CustomAttributeFormatException>(() => MetricUnitScale.FromEnumValues(typeof(MetricEnumNegativeScale))); Throws <CustomAttributeFormatException>(() => MetricUnitScale.FromEnumValues(typeof(MetricEnumNegativeRounding))); Throws <CustomAttributeFormatException>(() => MetricUnitScale.FromEnumValues(typeof(MetricEnumRoundingTooLarge))); }
private static MetricRange AssertAssertRoundtripInvariant( long i, MetricRange lastRange, MetricUnitScale unitScale) { // best applicable unit var unit = unitScale[i]; // new ranges var newRange = MetricValueHelpers.CreateMetricRange(i, i); var minMaxRange = lastRange.Union(newRange); AssertRoundtripInvariant(newRange, lastRange, unit); AssertRoundtripInvariant(newRange, minMaxRange, unit); AssertRoundtripInvariant(lastRange, minMaxRange, unit); return(newRange.ContainsWithRounding(lastRange, unit) ? lastRange : newRange); }
public static void TestMetricUnitScaleFiveThousands() { var scale = MetricUnitScale.FromEnumValues(typeof(MetricEnumOk)); var unit = scale[4900]; AreSame(unit, scale[MetricEnumOk.FiveThousands]); AreSame(unit, scale["x5K"]); AreNotSame(unit, scale[4899.9999]); AreSame(unit, scale[5000]); AreSame(unit, scale[11505]); AreSame(unit, scale[-33000]); AreSame(unit, scale[new MetricRange(-20000, 10000)]); AreSame(unit, scale[new MetricRange(MetricRange.FromNegativeInfinity, 6543.21)]); IsFalse(unit.IsEmpty); AreEqual(unit.EnumValue, MetricEnumOk.FiveThousands); AreEqual(unit.AppliesFrom, 4900); AreEqual(unit.ScaleCoefficient, 5000); AreEqual(unit.RoundingDigits, 0); AreEqual(unit.DisplayName, "x5K"); }
public static void TestMetricUnitScaleThousands() { var scale = MetricUnitScale.FromEnumValues(typeof(MetricEnumOk)); var unit = scale[900]; AreSame(unit, scale[MetricEnumOk.Thousands]); AreSame(unit, scale["k"]); AreNotSame(unit, scale[899.9999]); AreSame(unit, scale[1000]); AreSame(unit, scale[1505]); AreSame(unit, scale[-1505]); AreSame(unit, scale[new MetricRange(-10000, 900)]); AreSame(unit, scale[new MetricRange(MetricRange.FromNegativeInfinity, 907)]); IsFalse(unit.IsEmpty); AreEqual(unit.EnumValue, MetricEnumOk.Thousands); AreEqual(unit.AppliesFrom, 900); AreEqual(unit.ScaleCoefficient, 1000); AreEqual(unit.RoundingDigits, null); AreEqual(unit.DisplayName, "K"); }
public static void TestMetricUnitScaleMillions() { var m = 1000 * 1000; var scale = MetricUnitScale.FromEnumValues(typeof(MetricEnumOk)); var unit = scale[m]; AreSame(unit, scale[MetricEnumOk.Millions]); AreSame(unit, scale["M"]); AreNotSame(unit, scale[0.99 * m]); AreSame(unit, scale[-2 * m]); AreSame(unit, scale[double.NegativeInfinity]); AreSame(unit, scale[double.PositiveInfinity]); AreSame(unit, scale[MetricRange.Infinite]); AreSame(unit, scale[new MetricRange(-4 * m, 1 * m)]); IsFalse(unit.IsEmpty); AreEqual(unit.EnumValue, MetricEnumOk.Millions); AreEqual(unit.AppliesFrom, m); AreEqual(unit.ScaleCoefficient, m); AreEqual(unit.RoundingDigits, null); AreEqual(unit.DisplayName, "M"); }
public static void TestMetricUnitScaleTens() { var scale = MetricUnitScale.FromEnumValues(typeof(MetricEnumOk)); var unit = scale[8]; AreSame(unit, scale[MetricEnumOk.Tens]); AreSame(unit, scale["* 10"]); AreNotSame(unit, scale[7.9999]); AreSame(unit, scale[10]); AreSame(unit, scale[505]); AreSame(unit, scale[-505]); AreNotSame(unit, scale[double.NaN]); AreSame(unit, scale[new MetricRange(-10, MetricRange.ToPositiveInfinity)]); AreSame(unit, scale[new MetricRange(MetricRange.FromNegativeInfinity, 12)]); IsFalse(unit.IsEmpty); AreEqual(unit.EnumValue, MetricEnumOk.Tens); AreEqual(unit.AppliesFrom, 8); AreEqual(unit.ScaleCoefficient, 10); AreEqual(unit.RoundingDigits, 15); AreEqual(unit.DisplayName, "* 10"); }
public static void TestContainsWithRounding() { var unitScale = MetricUnitScale.FromEnumValues(typeof(Distance)); var valueX = 1002; var valueY = 1005; var valueZ = 1008; var rangeX = new MetricRange(valueX, valueX); var rangeY = new MetricRange(valueY, valueY); var rangeZ = new MetricRange(valueZ, valueZ); var rangeYz = new MetricRange(valueY, valueZ); var unit = unitScale[Distance.Meter]; AssertRoundtripInvariant(rangeY, rangeX, unit); AssertRoundtripInvariant(rangeY, rangeZ, unit); AssertRoundtripInvariant(rangeY, rangeYz, unit); IsFalse(rangeY.ContainsWithRounding(rangeX, unit)); IsTrue(rangeY.ContainsWithRounding(rangeZ, unit)); IsTrue(rangeY.ContainsWithRounding(rangeYz, unit)); }
private static void CheckExecution(ResultAnalysis analysis) { var summary = analysis.Summary; // DONTTOUCH: DO NOT add return into if clauses. // All conditions should be checked var benchmarksWithReports = summary.Reports .Where(r => r.ExecuteResults.Any()) .Select(r => r.Benchmark); var benchMissing = summary.GetSummaryOrderBenchmarks() .Except(benchmarksWithReports) .Select(b => b.Target.MethodDisplayInfo) .Distinct(). ToArray(); if (benchMissing.Any()) { var benchmarks = benchMissing.Length == 1 ? "benchmark" : "benchmarks"; analysis.WriteExecutionErrorMessage( $"No result reports for {benchmarks}: {benchMissing.Join(", ")}.", "Ensure that benchmarks were run successfully and did not throw any exceptions."); } var checksMode = analysis.Options.Checks; if (checksMode.CheckMetrics) { var timeUnits = MetricUnitScale.FromEnumValues(typeof(TimeUnit)); if (checksMode.TooFastBenchmarkLimit > TimeSpan.Zero) { var tooFastReports = GetTargetNames( analysis, r => r.GetResultRuns().Average(run => run.Nanoseconds) < checksMode.TooFastBenchmarkLimit.TotalNanoseconds()); if (tooFastReports.Any()) { var benchmarks = tooFastReports.Length == 1 ? "Benchmark" : "Benchmarks"; var time = checksMode.TooFastBenchmarkLimit .TotalNanoseconds() .ToString(timeUnits); analysis.AddWarningConclusion( $"{benchmarks} {tooFastReports.Join(", ")}: measured run time is less than {time}. " + "Timings are imprecise as they are too close to the timer resolution.", $"Timing limit for this warning is configured via {CompetitionCheckMode.TooFastBenchmarkLimitCharacteristic.FullId}."); } } if (checksMode.LongRunningBenchmarkLimit > TimeSpan.Zero) { var tooSlowReports = GetTargetNames( analysis, r => r.GetResultRuns().Average(run => run.Nanoseconds) > checksMode.LongRunningBenchmarkLimit.TotalNanoseconds()); if (tooSlowReports.Any()) { var benchmarks = tooSlowReports.Length == 1 ? "Benchmark" : "Benchmarks"; var time = checksMode.LongRunningBenchmarkLimit .TotalNanoseconds() .ToString(timeUnits); analysis.AddWarningConclusion( $"{benchmarks} {string.Join(", ", tooSlowReports)}: measured run time is greater than {time}. " + "There's a risk the peak timings were hidden by averages. " + "Consider to reduce the number of iterations performed per each measurement.", $"Timing limit for this warning is configured via {CompetitionCheckMode.LongRunningBenchmarkLimitCharacteristic.FullId}."); } } } }