| File: Harness\Metrics.cs | Web Access |
| Project: src\test\Microsoft.ML.PerformanceTests\Microsoft.ML.PerformanceTests.csproj (Microsoft.ML.PerformanceTests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Linq; using System.Text; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Columns; using BenchmarkDotNet.Reports; using BenchmarkDotNet.Running; namespace Microsoft.ML.PerformanceTests { public abstract class WithExtraMetrics : BenchmarkBase { protected abstract IEnumerable<Metric> GetMetrics(); /// <summary> /// this method is executed after running the benchmarks /// we use it as hack to simply print to console so ExtraMetricColumn can parse the output /// </summary> [GlobalCleanup] public void ReportMetrics() { foreach (var metric in GetMetrics()) { Console.WriteLine(metric.ToParsableString()); } } } public class ExtraMetricColumn : IColumn { public string ColumnName => "Extra Metric"; public string Id => nameof(ExtraMetricColumn); public string Legend => "Value of the provided extra metric"; public bool IsNumeric => true; public bool IsDefault(Summary summary, BenchmarkCase benchmark) => true; public bool IsAvailable(Summary summary) => true; public bool AlwaysShow => true; public ColumnCategory Category => ColumnCategory.Custom; public int PriorityInCategory => 1; public UnitType UnitType => UnitType.Dimensionless; public string GetValue(Summary summary, BenchmarkCase benchmark) => GetValue(summary, benchmark, null); public override string ToString() => ColumnName; public string GetValue(Summary summary, BenchmarkCase benchmark, SummaryStyle style) { if (!summary.HasReport(benchmark)) return "-"; var results = summary[benchmark].ExecuteResults; if (results.Count != 1) return "-"; var result = results.Single(); var buffer = new StringBuilder(); foreach (var line in result.StandardOutput) { if (Metric.TryParse(line, out Metric metric)) { if (buffer.Length > 0) buffer.Append(", "); buffer.Append(metric.ToColumnValue()); } } return buffer.Length > 0 ? buffer.ToString() : "-"; } } public struct Metric { private const string Prefix = "// Metric"; private const char Separator = '#'; public string Name { get; } public string Value { get; } public Metric(string name, string value) : this() { Name = name; Value = value; } public string ToColumnValue() => $"{Name}: {Value}"; public string ToParsableString() => $"{Prefix} {Separator} {Name} {Separator} {Value}"; public static bool TryParse(string line, out Metric metric) { metric = default; if (!line.StartsWith(Prefix)) return false; var splitted = line.Split(Separator); metric = new Metric(splitted[1].Trim(), splitted[2].Trim()); return true; } } }