diff --git a/BenchmarkDotNet/BenchmarkCompetition.cs b/BenchmarkDotNet/BenchmarkCompetition.cs index 85db0554a..8c5d6c51e 100644 --- a/BenchmarkDotNet/BenchmarkCompetition.cs +++ b/BenchmarkDotNet/BenchmarkCompetition.cs @@ -38,11 +38,13 @@ namespace BenchmarkDotNet ConsoleHelper.WriteLineHeader("Competition results:"); var nameWidth = tasks.Max(task => task.Name.Length) + 1; var msWidth = tasks.Max(task => task.Info.Result.MedianMilliseconds.ToString().Length); + var stdDevWidth = tasks.Max(task => string.Format("{0:0.00}", task.Info.Result.StandardDeviationMilliseconds).Length); foreach (var task in tasks) - ConsoleHelper.WriteLineStatistic("{0}: {1}ms [Error: {2:00.00}%]", + ConsoleHelper.WriteLineStatistic("{0}: {1}ms [Error = {2:00.00}%, StdDev = {3}]", task.Name.PadRight(nameWidth), task.Info.Result.MedianMilliseconds.ToString().PadLeft(msWidth), - task.Info.Result.Error * 100); + task.Info.Result.Error * 100, + string.Format("{0:0.00}", task.Info.Result.StandardDeviationMilliseconds).PadLeft(stdDevWidth)); } } } \ No newline at end of file diff --git a/BenchmarkDotNet/BenchmarkRunList.cs b/BenchmarkDotNet/BenchmarkRunList.cs index 36f5df162..e75f8fca9 100644 --- a/BenchmarkDotNet/BenchmarkRunList.cs +++ b/BenchmarkDotNet/BenchmarkRunList.cs @@ -26,18 +26,22 @@ namespace BenchmarkDotNet public void PrintStatistic() { - ConsoleHelper.WriteLineStatistic("TickStats: Min={0}, Max={1}, Median={2}, Diff={3:00.00}%", - MinTicks, MaxTicks, MedianTicks, Error * 100); - ConsoleHelper.WriteLineStatistic("MsStats: Min={0}, Max={1}, Median={2}", - MinMilliseconds, MaxMilliseconds, MedianMilliseconds); + ConsoleHelper.WriteLineStatistic("TickStats: Min={0}, Max={1}, Med={2}, StdDev={3:0}, Err={4:00.00}%", + MinTicks, MaxTicks, MedianTicks, StandardDeviationTicks, Error * 100); + ConsoleHelper.WriteLineStatistic("MsStats: Min={0}, Max={1}, Med={2}, StdDev={3:0.00}", + MinMilliseconds, MaxMilliseconds, MedianMilliseconds, StandardDeviationMilliseconds); } public long MinTicks { get { return this.Min(run => run.ElapsedTicks); } } public long MaxTicks { get { return this.Max(run => run.ElapsedTicks); } } public long MedianTicks { get { return this.Median(run => run.ElapsedTicks); } } + public double StandardDeviationTicks { get { return this.StandardDeviation(run => run.ElapsedTicks); } } + public long MinMilliseconds { get { return this.Min(run => run.ElapsedMilliseconds); } } public long MaxMilliseconds { get { return this.Max(run => run.ElapsedMilliseconds); } } public long MedianMilliseconds { get { return this.Median(run => run.ElapsedMilliseconds); } } + public double StandardDeviationMilliseconds { get { return this.StandardDeviation(run => run.ElapsedMilliseconds); } } + public double Error { get { return (MaxTicks - MinTicks) * 1.0 / MinTicks; } diff --git a/BenchmarkDotNet/Extensions.cs b/BenchmarkDotNet/Extensions.cs index 90940a85e..4730fcc49 100644 --- a/BenchmarkDotNet/Extensions.cs +++ b/BenchmarkDotNet/Extensions.cs @@ -16,5 +16,18 @@ namespace BenchmarkDotNet return list[list.Count / 2]; return (list[list.Count / 2 - 1] + list[list.Count / 2]) / 2; } + + public static double StandardDeviation(this IEnumerable source, Func selector) + { + var list = source.Select(selector).ToList(); + double result = 0; + if (list.Any()) + { + double avg = list.Average(); + double sum = list.Sum(d => Math.Pow(d - avg, 2)); + result = Math.Sqrt(sum / list.Count()); + } + return result; + } } } \ No newline at end of file